import { protectedProcedure, router } from "../_core/trpc.ts";
import { z } from "zod";
import {
  getOrCreateWallet, getTransactions, getLastDailyBonus, claimDailyBonus,
  getCoinPackages, writeAuditLog, getDb
} from "../db.ts";
import { eq } from "drizzle-orm";
import { scRedemptions } from "../../drizzle/schema.ts";

// Welcome Bonus Configuration
const WELCOME_BONUS_SC = 10; // 10 SC for new users (one-time)

const DAILY_BONUS_WHEEL = [
  { gcAmount: 500, scAmount: 0 },
  { gcAmount: 1000, scAmount: 0 },
  { gcAmount: 2500, scAmount: 0 },
  { gcAmount: 5000, scAmount: 0.50 },
  { gcAmount: 10000, scAmount: 1.00 },
  { gcAmount: 25000, scAmount: 2.50 },
  { gcAmount: 50000, scAmount: 5.00 },
  { gcAmount: 100000, scAmount: 10.00 },
];

export const walletRouter = router({
  /**
   * Get welcome bonus status for current user
   */
  getWelcomeBonusStatus: protectedProcedure.query(async ({ ctx }) => {
    const db = await getDb();
    const user = await db.query.users.findFirst({
      where: (users, { eq }) => eq(users.id, ctx.user.id),
    });
    
    return {
      claimed: user?.welcomeBonusClaimed || false,
      amount: WELCOME_BONUS_SC,
      claimableAt: user?.welcomeBonusClaimed ? null : new Date(),
    };
  }),

  /**
   * Claim welcome bonus (one-time for new users)
   */
  claimWelcomeBonus: protectedProcedure.mutation(async ({ ctx }) => {
    const db = await getDb();
    const user = await db.query.users.findFirst({
      where: (users, { eq }) => eq(users.id, ctx.user.id),
    });

    if (!user) throw new Error("User not found");
    if (user.welcomeBonusClaimed) throw new Error("Welcome bonus already claimed");

    const { creditWallet } = await import("../db");
    const { createNotification } = await import("./notifications");

    // Credit the welcome bonus
    await creditWallet(ctx.user.id, "SC", WELCOME_BONUS_SC, "welcome_bonus", "Welcome Bonus - New Player");
    
    // Mark bonus as claimed
    await db.update(users).set({ welcomeBonusClaimed: true }).where((u) => u.id === ctx.user.id);
    
    // Log the action
    await writeAuditLog({
      actorId: ctx.user.id,
      actorRole: "user",
      action: "welcome_bonus_claimed",
      category: "wallet",
      details: { amount: WELCOME_BONUS_SC },
    });

    // Send notification
    await createNotification(
      ctx.user.id,
      "bonus_credited",
      "Welcome Bonus Claimed!",
      `You've received ${WELCOME_BONUS_SC} Sweep Coins as a welcome gift! Start playing now.`,
      ["in_app", "email"],
      { amount: WELCOME_BONUS_SC }
    );

    return { success: true, amount: WELCOME_BONUS_SC };
  }),

  getBalance: protectedProcedure.query(async ({ ctx }) => {
    const wallet = await getOrCreateWallet(ctx.user.id);
    return {
      gcBalance: parseFloat(wallet.gcBalance),
      scBalance: parseFloat(wallet.scBalance),
      lifetimeGcEarned: parseFloat(wallet.lifetimeGcEarned),
      lifetimeScEarned: parseFloat(wallet.lifetimeScEarned),
      lifetimeScRedeemed: parseFloat(wallet.lifetimeScRedeemed),
    };
  }),

  getTransactions: protectedProcedure
    .input(z.object({ limit: z.number().min(1).max(100).default(20), offset: z.number().min(0).default(0) }))
    .query(async ({ ctx, input }) => {
      return getTransactions(ctx.user.id, input.limit, input.offset);
    }),

  getCoinPackages: protectedProcedure.query(async () => {
    return getCoinPackages();
  }),

  purchaseCoinPackage: protectedProcedure
    .input(z.object({ packageId: z.number() }))
    .mutation(async ({ ctx, input }) => {
      const packages = await getCoinPackages();
      const pkg = packages.find(p => p.id === input.packageId);
      if (!pkg) throw new Error("Package not found");
      const { creditWallet } = await import("../db");
      const { createNotification: createNotif } = await import("./notifications");
      const gcAmount = parseFloat(pkg.gcAmount);
      const scBonus = parseFloat(pkg.scBonusAmount);
      await creditWallet(ctx.user.id, "GC", gcAmount, "gc_purchase", `Purchased ${pkg.name}: ${gcAmount.toLocaleString()} GC`, String(pkg.id));
      if (scBonus > 0) {
        await creditWallet(ctx.user.id, "SC", scBonus, "sc_bonus", `Bonus SC from ${pkg.name}`, String(pkg.id));
      }
      await writeAuditLog({ actorId: ctx.user.id, actorRole: "user", action: "coin_package_purchase", category: "wallet", details: { packageId: pkg.id, packageName: pkg.name, gcAmount, scBonus } });
      // Send notification
      await createNotif(ctx.user.id, "bonus_credited", "Coins Purchased!", `You've received ${gcAmount.toLocaleString()} Gold Coins${scBonus > 0 ? ` + ${scBonus} Sweeps Coins` : ""}`, ["in_app", "email"], { packageId: pkg.id, gcAmount, scBonus });
      return { success: true, gcAmount, scBonus };
    }),

  getDailyBonusStatus: protectedProcedure.query(async ({ ctx }) => {
    const last = await getLastDailyBonus(ctx.user.id);
    if (!last) return { canClaim: true, nextClaimAt: null };
    const lastClaimed = new Date(last.claimedAt);
    const nextClaim = new Date(lastClaimed.getTime() + 24 * 60 * 60 * 1000);
    const canClaim = Date.now() >= nextClaim.getTime();
    return { canClaim, nextClaimAt: canClaim ? null : nextClaim.getTime() };
  }),

  claimDailyBonus: protectedProcedure.mutation(async ({ ctx }) => {
    const { createNotification } = await import("./notifications");
    const last = await getLastDailyBonus(ctx.user.id);
    if (last) {
      const nextClaim = new Date(new Date(last.claimedAt).getTime() + 24 * 60 * 60 * 1000);
      if (Date.now() < nextClaim.getTime()) throw new Error("Daily bonus not yet available");
    }
    const spinResult = Math.floor(Math.random() * DAILY_BONUS_WHEEL.length);
    const reward = DAILY_BONUS_WHEEL[spinResult];
    await claimDailyBonus(ctx.user.id, spinResult, reward.gcAmount, reward.scAmount);
    await writeAuditLog({ actorId: ctx.user.id, actorRole: "user", action: "daily_bonus_claimed", category: "wallet", details: reward });
    // Send notification
    await createNotification(ctx.user.id, "bonus_credited", "Daily Bonus Claimed!", `You've claimed ${reward.gcAmount.toLocaleString()} Gold Coins${reward.scAmount > 0 ? ` + ${reward.scAmount} Sweeps Coins` : ""}`, ["in_app"], { gcAmount: reward.gcAmount, scAmount: reward.scAmount });
    return { spinResult, gcAmount: reward.gcAmount, scAmount: reward.scAmount };
  }),

  requestScRedemption: protectedProcedure
    .input(z.object({
      scAmount: z.number().min(100),
      method: z.enum(["bank_transfer", "check", "paypal", "crypto"]),
      paymentDetails: z.record(z.string(), z.string()),
    }))
    .mutation(async ({ ctx, input }) => {
      // ENFORCED SITEWIDE: KYC verification required for ALL withdrawals
      if (ctx.user.kycStatus !== "approved") {
        throw new Error("KYC verification is required to withdraw funds. Please complete your identity verification.");
      }

      const wallet = await getOrCreateWallet(ctx.user.id);
      if (parseFloat(wallet.scBalance) < input.scAmount) throw new Error("Insufficient SC balance");
      
      // ENFORCED SITEWIDE: Minimum withdrawal amount is 100 SC
      if (input.scAmount < 100) throw new Error("Minimum withdrawal amount is 100 SC");
      if (ctx.user.kycStatus !== "approved") throw new Error("KYC verification required for SC redemption");
      const { debitWallet } = await import("../db");
      const { createNotification } = await import("./notifications");
      await debitWallet(ctx.user.id, "SC", input.scAmount, "sc_redeem", `SC redemption request: $${input.scAmount.toFixed(2)}`);
      const db = await getDb();
      let requestId = 0;
      if (db) {
        const result = await (db as any).insert(scRedemptions).values({
          userId: ctx.user.id,
          scAmount: input.scAmount.toFixed(2),
          usdAmount: input.scAmount.toFixed(2),
          method: input.method,
          paymentDetails: JSON.stringify(input.paymentDetails),
          status: "pending",
        });
        requestId = (result as any).insertId || 0;
      }
      await writeAuditLog({ actorId: ctx.user.id, actorRole: "user", action: "sc_redemption_requested", category: "wallet", details: { scAmount: input.scAmount, method: input.method } });
      // Send notification
      await createNotification(ctx.user.id, "withdrawal_approved", "Redemption Request Submitted", `Your request to redeem ${input.scAmount} SC has been submitted. We'll process it within 3-5 business days.`, ["in_app", "email"], { scAmount: input.scAmount, method: input.method });
      return { success: true, requestId };
    }),

  getScRedemptions: protectedProcedure.query(async ({ ctx }) => {
    const { getScRedemptions } = await import("../db");
    return getScRedemptions(ctx.user.id);
  }),
});
