import { protectedProcedure, router } from "../_core/trpc.ts";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { getDb } from "../db.ts";
import { users, wallets } from "../../drizzle/schema.ts";
import { protectedProcedure as protectedProc } from "../_core/trpc.ts";
import { eq } from "drizzle-orm";

// VIP Tier Configuration
export const VIP_TIERS = {
  bronze: {
    name: "Bronze",
    level: 1,
    minSpent: 0,
    dailyLimit: 500,
    monthlyLimit: 5000,
    cashbackPercent: 1,
    bonusMultiplier: 1.05,
    exclusiveGames: false,
    prioritySupport: false,
    color: "#CD7F32",
  },
  silver: {
    name: "Silver",
    level: 2,
    minSpent: 500,
    dailyLimit: 1000,
    monthlyLimit: 10000,
    cashbackPercent: 2,
    bonusMultiplier: 1.1,
    exclusiveGames: false,
    prioritySupport: true,
    color: "#C0C0C0",
  },
  gold: {
    name: "Gold",
    level: 3,
    minSpent: 2000,
    dailyLimit: 2500,
    monthlyLimit: 25000,
    cashbackPercent: 3,
    bonusMultiplier: 1.15,
    exclusiveGames: true,
    prioritySupport: true,
    color: "#FFD700",
  },
  platinum: {
    name: "Platinum",
    level: 4,
    minSpent: 5000,
    dailyLimit: 5000,
    monthlyLimit: 50000,
    cashbackPercent: 5,
    bonusMultiplier: 1.2,
    exclusiveGames: true,
    prioritySupport: true,
    color: "#E5E4E2",
  },
  diamond: {
    name: "Diamond",
    level: 5,
    minSpent: 10000,
    dailyLimit: 10000,
    monthlyLimit: 100000,
    cashbackPercent: 7,
    bonusMultiplier: 1.25,
    exclusiveGames: true,
    prioritySupport: true,
    color: "#B9F2FF",
  },
};

export const vipRouter = router({
  // Get user's VIP status
  getVIPStatus: protectedProcedure.query(async ({ ctx }) => {
    const db = await getDb();
    if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

    const user = await db.select().from(users).where(eq(users.id, ctx.user!.id)).limit(1);
    if (!user[0]) throw new TRPCError({ code: "NOT_FOUND" });

    const wallet = await db.select().from(wallets).where(eq(wallets.userId, ctx.user!.id)).limit(1);
    const userRecord = user[0];
    const totalSpent = wallet[0] ? Number(wallet[0].lifetimeGcEarned || 0) : 0;

    // Determine VIP tier based on total spent
    let currentTier = "bronze";
    if (totalSpent >= 10000) currentTier = "diamond";
    else if (totalSpent >= 5000) currentTier = "platinum";
    else if (totalSpent >= 2000) currentTier = "gold";
    else if (totalSpent >= 500) currentTier = "silver";

    const tierConfig = VIP_TIERS[currentTier as keyof typeof VIP_TIERS];
    const nextTier = Object.entries(VIP_TIERS).find(
      ([_, tier]) => tier.minSpent > totalSpent
    );

    const progressToNextTier = nextTier
      ? Math.min(100, ((totalSpent - tierConfig.minSpent) / (nextTier[1].minSpent - tierConfig.minSpent)) * 100)
      : 100;

    return {
      userId: ctx.user!.id,
      currentTier,
      tierConfig,
      totalSpent,
      nextTier: nextTier ? nextTier[0] : null,
      nextTierMinSpent: nextTier ? nextTier[1].minSpent : null,
      progressToNextTier,
      joinedAt: userRecord.createdAt,
    };
  }),

  // Get all VIP tiers
  getAllTiers: protectedProcedure.query(async () => {
    return Object.entries(VIP_TIERS).map(([key, tier]) => ({
      id: key,
      ...tier,
    }));
  }),

  // Get VIP benefits
  getVIPBenefits: protectedProcedure.query(async ({ ctx }) => {
    const db = await getDb();
    if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

    const user = await db.select().from(users).where(eq(users.id, ctx.user!.id)).limit(1);
    if (!user[0]) throw new TRPCError({ code: "NOT_FOUND" });

    const benefitWallet = await db.select().from(wallets).where(eq(wallets.userId, ctx.user!.id)).limit(1);
    const totalSpent = benefitWallet[0] ? Number(benefitWallet[0].lifetimeGcEarned || 0) : 0;

    // Determine VIP tier
    let currentTier = "bronze";
    if (totalSpent >= 10000) currentTier = "diamond";
    else if (totalSpent >= 5000) currentTier = "platinum";
    else if (totalSpent >= 2000) currentTier = "gold";
    else if (totalSpent >= 500) currentTier = "silver";

    const tierConfig = VIP_TIERS[currentTier as keyof typeof VIP_TIERS];

    return {
      tier: currentTier,
      benefits: {
        dailyLimit: tierConfig.dailyLimit,
        monthlyLimit: tierConfig.monthlyLimit,
        cashbackPercent: tierConfig.cashbackPercent,
        bonusMultiplier: tierConfig.bonusMultiplier,
        exclusiveGames: tierConfig.exclusiveGames,
        prioritySupport: tierConfig.prioritySupport,
        birthdayBonus: 50, // SC
        monthlyReward: tierConfig.level * 10, // SC
        freeSpins: tierConfig.level * 5,
      },
    };
  }),

  // Get VIP leaderboard
  getVIPLeaderboard: protectedProcedure
    .input(z.object({ limit: z.number().default(10) }))
    .query(async ({ ctx, input }) => {
      const db = await getDb();
      if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

      const allUsers = await db.select().from(users);
      const allWallets = await db.select().from(wallets);

      // Calculate VIP tier for each user
      const vipUsers = allUsers
        .map((user: any) => {
          const userWallet = allWallets.find((w: any) => w.userId === user.id);
          const totalSpent = userWallet ? Number(userWallet.lifetimeGcEarned || 0) : 0;
          let tier = "bronze";
          if (totalSpent >= 10000) tier = "diamond";
          else if (totalSpent >= 5000) tier = "platinum";
          else if (totalSpent >= 2000) tier = "gold";
          else if (totalSpent >= 500) tier = "silver";

          const tierConfig = VIP_TIERS[tier as keyof typeof VIP_TIERS];
          return {
            userId: user.id,
            username: user.username || `Player ${user.id}`,
            tier,
            tierLevel: tierConfig.level,
            totalSpent,
            joinedAt: user.createdAt,
          };
        })
        .filter((u: any) => u.tier !== "bronze") // Only show non-bronze VIPs
        .sort((a: any, b: any) => b.tierLevel - a.tierLevel || b.totalSpent - a.totalSpent)
        .slice(0, input.limit);

      return vipUsers.map((user: any, index: number) => ({
        ...user,
        rank: index + 1,
      }));
    }),

  // Claim monthly VIP reward
  claimMonthlyReward: protectedProcedure.mutation(async ({ ctx }) => {
    const db = await getDb();
    if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

    const user = await db.select().from(users).where(eq(users.id, ctx.user!.id)).limit(1);
    if (!user[0]) throw new TRPCError({ code: "NOT_FOUND" });

    const userWallet = await db.select().from(wallets).where(eq(wallets.userId, ctx.user!.id)).limit(1);
    const totalSpent = userWallet[0] ? Number(userWallet[0].lifetimeGcEarned || 0) : 0;

    // Determine VIP tier
    let currentTier = "bronze";
    if (totalSpent >= 10000) currentTier = "diamond";
    else if (totalSpent >= 5000) currentTier = "platinum";
    else if (totalSpent >= 2000) currentTier = "gold";
    else if (totalSpent >= 500) currentTier = "silver";

    const tierConfig = VIP_TIERS[currentTier as keyof typeof VIP_TIERS];
    const monthlyReward = tierConfig.level * 10; // SC

    // Add reward to wallet
    if (userWallet[0]) {
      const newBalance = (Number(userWallet[0].scBalance) || 0) + monthlyReward;
      await db
        .update(wallets)
        .set({ scBalance: newBalance.toString() })
        .where(eq(wallets.userId, ctx.user!.id));
    }

    return {
      success: true,
      rewardAmount: monthlyReward,
      tier: currentTier,
    };
  }),

  // Get VIP exclusive games
  getExclusiveGames: protectedProcedure.query(async ({ ctx }) => {
    const db = await getDb();
    if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

    const user = await db.select().from(users).where(eq(users.id, ctx.user!.id)).limit(1);
    if (!user[0]) throw new TRPCError({ code: "NOT_FOUND" });

    const exclusiveWallet = await db.select().from(wallets).where(eq(wallets.userId, ctx.user!.id)).limit(1);
    const totalSpent = exclusiveWallet[0] ? Number(exclusiveWallet[0].lifetimeGcEarned || 0) : 0;

    // Determine VIP tier
    let currentTier = "bronze";
    if (totalSpent >= 10000) currentTier = "diamond";
    else if (totalSpent >= 5000) currentTier = "platinum";
    else if (totalSpent >= 2000) currentTier = "gold";
    else if (totalSpent >= 500) currentTier = "silver";

    const tierConfig = VIP_TIERS[currentTier as keyof typeof VIP_TIERS];

    if (!tierConfig.exclusiveGames) {
      return [];
    }

    // Return exclusive games based on tier
    const exclusiveGames = [
      {
        id: "vip_mega_fortune",
        name: "VIP Mega Fortune",
        minTier: "gold",
        description: "Exclusive high-stakes slot with 5x multiplier",
        maxWin: 100,
      },
      {
        id: "vip_diamond_rush",
        name: "VIP Diamond Rush",
        minTier: "platinum",
        description: "Premium slot with guaranteed daily bonus",
        maxWin: 200,
      },
      {
        id: "vip_royal_flush",
        name: "VIP Royal Flush",
        minTier: "diamond",
        description: "Ultimate exclusive poker game with VIP-only tournaments",
        maxWin: 500,
      },
    ];

    const tierLevels: Record<string, number> = {
      bronze: 1,
      silver: 2,
      gold: 3,
      platinum: 4,
      diamond: 5,
    };

    return exclusiveGames.filter(
      (game) => tierLevels[game.minTier] <= tierLevels[currentTier]
    );
  }),

  // Get VIP statistics
  getVIPStats: protectedProcedure.query(async ({ ctx }) => {
    const db = await getDb();
    if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

    const user = await db.select().from(users).where(eq(users.id, ctx.user!.id)).limit(1);
    if (!user[0]) throw new TRPCError({ code: "NOT_FOUND" });

    const wallet = await db.select().from(wallets).where(eq(wallets.userId, ctx.user!.id)).limit(1);
    const totalSpent = wallet[0] ? Number(wallet[0].lifetimeGcEarned || 0) : 0;
    const totalWon = wallet[0] ? Number(wallet[0].lifetimeScEarned || 0) : 0;

    // Determine VIP tier
    let currentTier = "bronze";
    if (totalSpent >= 10000) currentTier = "diamond";
    else if (totalSpent >= 5000) currentTier = "platinum";
    else if (totalSpent >= 2000) currentTier = "gold";
    else if (totalSpent >= 500) currentTier = "silver";

    const tierConfig = VIP_TIERS[currentTier as keyof typeof VIP_TIERS];

    return {
      tier: currentTier,
      totalSpent,
      totalWon,
      gamesPlayed: 0,
      memberSince: user[0].createdAt,
      nextTierIn: (() => {
        const nextTier = Object.entries(VIP_TIERS).find(
          ([_, tier]) => tier.minSpent > totalSpent
        );
        return nextTier ? nextTier[1].minSpent - totalSpent : 0;
      })(),
      monthlyRewardAmount: tierConfig.level * 10,
      cashbackEarned: Math.floor((totalWon * tierConfig.cashbackPercent) / 100),
    };
  }),
});
