/**
 * Bonus Rounds tRPC Router
 * Handles bonus game triggers, processing, and payouts
 */

import { router, protectedProcedure } from '../_core/trpc.ts';
import { z } from 'zod';
import {
  triggerBonusRound,
  processPickEm,
  processWheelSpin,
  processFreeSpins,
  processMultiplier,
  processMysteryBox,
  calculateBonusPayout,
  getBonusStats,
  type BonusType,
} from '../bonusRoundsSystem.ts';
import { getDb } from '../db.ts';
import { COOKIE_NAME } from '../_core/cookies.ts';
import { wallets } from '../../drizzle/schema.ts';
import { eq } from 'drizzle-orm';
import type { AppRouter } from '../routers.ts';


// Fix: bonusRouter is properly typed
export const bonusRouter = router({
  /**
   * Trigger bonus round based on scatter symbols
   */
  triggerBonus: protectedProcedure
    .input(
      z.object({
        gameId: z.string(),
        scatterCount: z.number().int().min(0).max(10),
        triggerAmount: z.number().positive(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      const bonus = await triggerBonusRound(ctx.user.id, input.gameId, input.scatterCount, input.triggerAmount);

      if (!bonus) {
        return { triggered: false };
      }

      return {
        triggered: true,
        bonus: {
          id: bonus.id,
          type: bonus.bonusType,
          multiplier: bonus.multiplier,
          freeSpins: bonus.freeSpins,
          prize: bonus.prize,
        },
      };
    }),

  /**
   * Process pick-em bonus selection
   */
  processPickEm: protectedProcedure
    .input(
      z.object({
        bonusId: z.string(),
        itemCount: z.number().int().min(3).max(10),
        selectedItems: z.array(z.number().int().nonnegative()),
      })
    )
    .mutation(async ({ input, ctx }) => {
      const result = processPickEm(input.itemCount, input.selectedItems);

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

      if (wallet) {
        await db
          .update(wallets)
          .set({
            scBalance: wallet.scBalance + result.totalPrize,
          })
          .where(eq(wallets.userId, ctx.user.id));
      }

      return {
        success: true,
        result: {
          type: 'pick-em',
          prizes: result.prizes,
          selectedItems: result.selectedItems,
          totalPrize: result.totalPrize,
        },
      };
    }),

  /**
   * Process wheel spin bonus
   */
  processWheelSpin: protectedProcedure
    .input(
      z.object({
        bonusId: z.string(),
        segments: z.number().int().min(4).max(12),
        selectedSegment: z.number().int().nonnegative(),
        baseMultiplier: z.number().positive(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      const result = processWheelSpin(input.segments, input.selectedSegment, input.baseMultiplier);

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

      if (wallet) {
        await db
          .update(wallets)
          .set({
            scBalance: wallet.scBalance + result.prize,
          })
          .where(eq(wallets.userId, ctx.user.id));
      }

      return {
        success: true,
        result: {
          type: 'wheel-spin',
          selectedSegment: result.selectedSegment,
          prize: result.prize,
          multiplier: result.multiplier,
        },
      };
    }),

  /**
   * Process free spins bonus
   */
  processFreeSpin: protectedProcedure
    .input(
      z.object({
        bonusId: z.string(),
        freeSpins: z.number().int().positive(),
        baseMultiplier: z.number().positive(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      const result = processFreeSpins(input.freeSpins, input.baseMultiplier);

      return {
        success: true,
        result: {
          type: 'free-spins',
          freeSpins: result.freeSpins,
          multiplier: result.multiplier,
          estimatedPrize: result.totalPrize,
        },
      };
    }),

  /**
   * Process multiplier bonus
   */
  processMultiplier: protectedProcedure
    .input(
      z.object({
        bonusId: z.string(),
        baseMultiplier: z.number().positive(),
        duration: z.number().int().positive(),
        baseAmount: z.number().positive(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      const result = processMultiplier(input.baseMultiplier, input.duration, input.baseAmount);

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

      if (wallet) {
        await db
          .update(wallets)
          .set({
            scBalance: wallet.scBalance + result.prize,
          })
          .where(eq(wallets.userId, ctx.user.id));
      }

      return {
        success: true,
        result: {
          type: 'multiplier',
          multiplier: result.multiplier,
          duration: result.duration,
          prize: result.prize,
        },
      };
    }),

  /**
   * Process mystery box bonus
   */
  processMysteryBox: protectedProcedure
    .input(
      z.object({
        bonusId: z.string(),
        boxCount: z.number().int().min(3).max(10),
        selectedBoxes: z.array(z.number().int().nonnegative()),
      })
    )
    .mutation(async ({ input, ctx }) => {
      const result = processMysteryBox(input.boxCount, input.selectedBoxes);

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

      if (wallet) {
        await db
          .update(wallets)
          .set({
            scBalance: wallet.scBalance + result.totalPrize,
          })
          .where(eq(wallets.userId, ctx.user.id));
      }

      return {
        success: true,
        result: {
          type: 'mystery-box',
          prizes: result.prizes,
          selectedBoxes: result.selectedBoxes,
          totalPrize: result.totalPrize,
        },
      };
    }),

  /**
   * Get bonus statistics for player
   */
  getBonusStats: protectedProcedure.query(async ({ ctx }) => {
    const stats = await getBonusStats(ctx.user.id);
    return stats;
  }),

  /**
   * Get bonus history for player
   */
  getBonusHistory: protectedProcedure
    .input(
      z.object({
        limit: z.number().int().positive().max(100).default(50),
      })
    )
    .query(async ({ input, ctx }) => {
      // In production, would query bonus history from database
      return {
        bonuses: [],
        total: 0,
      };
    }),
});
