import { router, protectedProcedure } from "../_core/trpc.ts";
import { z } from "zod";
import { getDb } from "../db.ts";
import { users, wallets, transactions } from "../../drizzle/schema.ts";
import { eq, and } from "drizzle-orm";

export const playerEngagementRouter = router({
  // Referral System
  generateReferralCode: protectedProcedure.mutation(async ({ ctx }) => {
    const db = await getDb();
    const referralCode = `REF-${ctx.user.id}-${Date.now()}`.substring(0, 20);
    
    // Update user with referral code
    await db
      .update(users)
      .set({ referralCode })
      .where(eq(users.id, ctx.user.id));

    return { referralCode, shareUrl: `${process.env.VITE_APP_URL}?ref=${referralCode}` };
  }),

  getReferralStats: protectedProcedure.query(async ({ ctx }) => {
    const db = await getDb();
    const user = await db.query.users.findFirst({
      where: eq(users.id, ctx.user.id),
    });

    const referredUsers = await db.query.users.findMany({
      where: eq(users.referredBy, user?.referralCode),
    });

    const totalReferralBonus = referredUsers.reduce((sum, u) => sum + (u.referralBonusEarned || 0), 0);

    return {
      referralCode: user?.referralCode,
      totalReferrals: referredUsers.length,
      activeReferrals: referredUsers.filter(u => u.lastLogin && new Date(u.lastLogin) > new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)).length,
      totalBonusEarned: totalReferralBonus,
      referredUsers: referredUsers.map(u => ({
        id: u.id,
        username: u.username,
        joinedAt: u.createdAt,
        status: u.lastLogin && new Date(u.lastLogin) > new Date(Date.now() - 7 * 24 * 60 * 60 * 1000) ? 'active' : 'inactive',
      })),
    };
  }),

  claimReferralBonus: protectedProcedure
    .input(z.object({ referralId: z.string() }))
    .mutation(async ({ ctx, input }) => {
      const db = await getDb();
      const referral = await db.query.users.findFirst({
        where: eq(users.id, input.referralId),
      });

      if (!referral || referral.referredBy !== ctx.user.referralCode) {
        throw new Error("Invalid referral");
      }

      const bonusAmount = 500; // 500 GC per referral
      const userWallet = await db.query.wallets.findFirst({
        where: eq(wallets.userId, ctx.user.id),
      });

      if (!userWallet) throw new Error("Wallet not found");

      // Add bonus to wallet
      await db
        .update(wallets)
        .set({ gameCoins: userWallet.gameCoins + bonusAmount })
        .where(eq(wallets.id, userWallet.id));

      // Record transaction
      await db.insert(transactions).values({
        userId: ctx.user.id,
        type: "referral_bonus",
        amount: bonusAmount,
        currency: "GC",
        status: "completed",
        description: `Referral bonus from ${referral.username}`,
        createdAt: new Date(),
      });

      return { success: true, bonusAmount };
    }),

  // Social Sharing
  recordShare: protectedProcedure
    .input(z.object({ platform: z.string(), content: z.string() }))
    .mutation(async ({ ctx, input }) => {
      const db = await getDb();
      await db.insert(transactions).values({
        userId: ctx.user.id,
        type: "social_share",
        amount: 100,
        currency: "GC",
        status: "completed",
        description: `Shared on ${input.platform}`,
        metadata: { platform: input.platform, content: input.content },
        createdAt: new Date(),
      });

      // Award bonus coins for sharing
      const wallet = await db.query.wallets.findFirst({
        where: eq(wallets.userId, ctx.user.id),
      });

      if (wallet) {
        await db
          .update(wallets)
          .set({ gameCoins: wallet.gameCoins + 100 })
          .where(eq(wallets.id, wallet.id));
      }

      return { success: true, bonusAwarded: 100 };
    }),

  // Tournament System
  getTournaments: protectedProcedure.query(async () => {
    const db = await getDb();
    return [
      {
        id: "tournament-1",
        name: "Weekly Spin Challenge",
        description: "Compete for the highest total winnings",
        startDate: new Date(),
        endDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
        prizePool: 10000,
        participants: 1250,
        status: "active",
        leaderboard: [
          { rank: 1, username: "SpinMaster", score: 45000, prize: 5000 },
          { rank: 2, username: "LuckyPlayer", score: 38000, prize: 3000 },
          { rank: 3, username: "CoinHunter", score: 32000, prize: 2000 },
        ],
      },
      {
        id: "tournament-2",
        name: "Monthly Jackpot Race",
        description: "Reach the biggest jackpot to win",
        startDate: new Date(Date.now() - 10 * 24 * 60 * 60 * 1000),
        endDate: new Date(Date.now() + 20 * 24 * 60 * 60 * 1000),
        prizePool: 50000,
        participants: 5000,
        status: "active",
        leaderboard: [],
      },
    ];
  }),

  joinTournament: protectedProcedure
    .input(z.object({ tournamentId: z.string() }))
    .mutation(async ({ ctx, input }) => {
      const db = await getDb();
      return {
        success: true,
        message: `Successfully joined tournament ${input.tournamentId}`,
        entryFee: 100,
      };
    }),

  // Achievement System
  getAchievements: protectedProcedure.query(async ({ ctx }) => {
    const db = await getDb();
    return {
      earned: [
        {
          id: "first-spin",
          name: "First Spin",
          description: "Complete your first game spin",
          icon: "🎰",
          unlockedAt: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
          reward: 100,
        },
        {
          id: "high-roller",
          name: "High Roller",
          description: "Win 10,000 coins in a single spin",
          icon: "💰",
          unlockedAt: new Date(Date.now() - 15 * 24 * 60 * 60 * 1000),
          reward: 500,
        },
      ],
      available: [
        {
          id: "jackpot-hunter",
          name: "Jackpot Hunter",
          description: "Hit 5 jackpots",
          icon: "🎯",
          progress: 2,
          total: 5,
          reward: 1000,
        },
        {
          id: "social-butterfly",
          name: "Social Butterfly",
          description: "Share on 10 different occasions",
          icon: "🦋",
          progress: 3,
          total: 10,
          reward: 500,
        },
      ],
    };
  }),

  claimAchievementReward: protectedProcedure
    .input(z.object({ achievementId: z.string() }))
    .mutation(async ({ ctx, input }) => {
      const db = await getDb();
      const reward = 500;

      const wallet = await db.query.wallets.findFirst({
        where: eq(wallets.userId, ctx.user.id),
      });

      if (!wallet) throw new Error("Wallet not found");

      await db
        .update(wallets)
        .set({ gameCoins: wallet.gameCoins + reward })
        .where(eq(wallets.id, wallet.id));

      await db.insert(transactions).values({
        userId: ctx.user.id,
        type: "achievement_reward",
        amount: reward,
        currency: "GC",
        status: "completed",
        description: `Achievement reward: ${input.achievementId}`,
        createdAt: new Date(),
      });

      return { success: true, rewardClaimed: reward };
    }),

  // Leaderboard
  getGlobalLeaderboard: protectedProcedure
    .input(z.object({ timeframe: z.enum(["day", "week", "month", "all"]) }))
    .query(async ({ input }) => {
      const db = await getDb();
      const startDate = new Date();
      if (input.timeframe === "day") startDate.setDate(startDate.getDate() - 1);
      else if (input.timeframe === "week") startDate.setDate(startDate.getDate() - 7);
      else if (input.timeframe === "month") startDate.setMonth(startDate.getMonth() - 1);

      return [
        { rank: 1, username: "CryptoKing", totalWinnings: 500000, gamesPlayed: 1250, winRate: 45 },
        { rank: 2, username: "LuckyAce", totalWinnings: 450000, gamesPlayed: 980, winRate: 42 },
        { rank: 3, username: "SpinMaster", totalWinnings: 420000, gamesPlayed: 1100, winRate: 40 },
        { rank: 4, username: "CoinCollector", totalWinnings: 380000, gamesPlayed: 890, winRate: 38 },
        { rank: 5, username: "JackpotHunter", totalWinnings: 350000, gamesPlayed: 750, winRate: 36 },
      ];
    }),
});
