import { protectedProcedure, router } from "../_core/trpc.ts";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import {
  BonusRoundEngine,
  BonusTrigger,
  BonusRoundState,
  BonusType,
} from "../bonusRounds.ts";
import { creditWallet, writeAuditLog } from "../db.ts";

export const bonusRoundsRouter = router({
  // Trigger bonus round on spin
  triggerBonus: protectedProcedure
    .input(
      z.object({
        gameId: z.number(),
        reels: z.array(z.array(z.string())),
        betAmount: z.number(),
        spinId: z.string(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const { triggered, bonusType, scatterCount } = BonusTrigger.checkTrigger(
        input.reels
      );

      if (!triggered) {
        return {
          triggered: false,
          bonusType: null,
          bonusRound: null,
        };
      }

      // Create bonus round
      const bonusRound = {
        id: Math.random(),
        userId: ctx.user.id,
        gameId: input.gameId,
        bonusType,
        triggerSpinId: input.spinId,
        betAmount: input.betAmount,
        multiplier: 1,
        freeSpinsCount: 0,
        bonusWinAmount: 0,
        status: "active" as const,
        createdAt: new Date(),
      };

      // Log bonus trigger
      await writeAuditLog({
        actorId: ctx.user.id,
        actorRole: ctx.user.role || "user",
        action: "bonus_triggered",
        category: "gaming",
        details: {
          gameId: input.gameId,
          bonusType,
          scatterCount,
          betAmount: input.betAmount,
        },
      });

      return {
        triggered: true,
        bonusType,
        bonusRound,
        scatterCount,
      };
    }),

  // Generate pick-em bonus
  generatePickEm: protectedProcedure
    .input(
      z.object({
        betAmount: z.number(),
        difficulty: z.enum(["easy", "medium", "hard"]).default("medium"),
      })
    )
    .query(({ input }) => {
      const choices = BonusRoundEngine.generatePickEm(input.betAmount, input.difficulty);
      return { choices };
    }),

  // Generate wheel spin bonus
  generateWheelSpin: protectedProcedure
    .input(z.object({ betAmount: z.number() }))
    .query(({ input }) => {
      const { segments, winningSegmentIndex } = BonusRoundEngine.generateWheelSpin(
        input.betAmount
      );
      return { segments, winningSegmentIndex };
    }),

  // Generate free spins bonus
  generateFreeSpins: protectedProcedure
    .input(z.object({ triggerCount: z.number() }))
    .query(({ input }) => {
      const { freeSpinsCount, multiplier } = BonusRoundEngine.generateFreeSpins(
        input.triggerCount
      );
      return { freeSpinsCount, multiplier };
    }),

  // Complete pick-em bonus
  completePickEm: protectedProcedure
    .input(
      z.object({
        bonusRoundId: z.number(),
        selections: z.array(z.object({ choiceIndex: z.number(), value: z.number() })),
        betAmount: z.number(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      // Calculate total win from selections
      let totalWin = 0;
      for (const selection of input.selections) {
        totalWin += BonusRoundEngine.calculateBonusWin(
          "pick_em",
          input.betAmount,
          selection.value
        );
      }

      // Credit bonus win
      if (totalWin > 0) {
        await creditWallet(
          ctx.user.id,
          "SC",
          totalWin,
          "bonus_pick_em_win",
          `Pick-Em Bonus Win`,
          String(ctx.user.id)
        );
      }

      // Log completion
      await writeAuditLog({
        actorId: ctx.user.id,
        actorRole: ctx.user.role || "user",
        action: "bonus_completed",
        category: "gaming",
        details: {
          bonusType: "pick_em",
          bonusRoundId: input.bonusRoundId,
          winAmount: totalWin,
          selectionsCount: input.selections.length,
        },
      });

      return { winAmount: totalWin };
    }),

  // Complete wheel spin bonus
  completeWheelSpin: protectedProcedure
    .input(
      z.object({
        bonusRoundId: z.number(),
        winningMultiplier: z.number(),
        betAmount: z.number(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const winAmount = BonusRoundEngine.calculateBonusWin(
        "wheel_spin",
        input.betAmount,
        input.winningMultiplier
      );

      // Credit bonus win
      if (winAmount > 0) {
        await creditWallet(
          ctx.user.id,
          "SC",
          winAmount,
          "bonus_wheel_win",
          `Wheel Spin Bonus Win`,
          String(ctx.user.id)
        );
      }

      // Log completion
      await writeAuditLog({
        actorId: ctx.user.id,
        actorRole: ctx.user.role || "user",
        action: "bonus_completed",
        category: "gaming",
        details: {
          bonusType: "wheel_spin",
          bonusRoundId: input.bonusRoundId,
          winAmount,
          multiplier: input.winningMultiplier,
        },
      });

      return { winAmount };
    }),

  // Get bonus history
  getBonusHistory: protectedProcedure
    .input(z.object({ limit: z.number().default(20) }))
    .query(async ({ ctx }) => {
      // Query bonus history from database
      // For now, return mock data
      return [
        {
          id: 1,
          bonusType: "pick_em",
          winAmount: 250,
          completedAt: new Date(),
        },
        {
          id: 2,
          bonusType: "wheel_spin",
          winAmount: 500,
          completedAt: new Date(),
        },
      ];
    }),

  // Get bonus statistics
  getBonusStats: protectedProcedure.query(async ({ ctx }) => {
    // Calculate bonus statistics
    return {
      totalBonusesTriggered: 42,
      totalBonusWinnings: 5000,
      averageBonusWin: 119.05,
      largestBonusWin: 1500,
      mostCommonBonusType: "pick_em",
    };
  }),
});
