import { router, protectedProcedure, adminProcedure } from "../_core/trpc.ts";
import { z } from "zod";
import { getDb } from "../db.ts";
import { casinoGames, transactions } from "../../drizzle/schema.ts";
import { eq, desc, and } from "drizzle-orm";
import { TRPCError } from "@trpc/server";

const gameSymbolSchema = z.object({
  id: z.string(),
  name: z.string(),
  emoji: z.string(),
  multiplier: z.number().positive(),
  weight: z.number().positive(),
});

const bonusFeaturesSchema = z.object({
  freeSpins: z.boolean(),
  freeSpinsCount: z.number().min(5).max(100),
  scatterSymbol: z.boolean(),
  wildSymbol: z.boolean(),
  bonusRound: z.boolean(),
});

const gameTemplateSchema = z.object({
  name: z.string().min(3).max(255),
  type: z.enum(["classic-3-reel", "5-reel", "bonus-heavy"]),
  reels: z.number().min(3).max(6),
  rows: z.number().min(1).max(5),
  rtp: z.number().min(70).max(99),
  volatility: z.enum(["low", "medium", "high"]),
  symbols: z.array(gameSymbolSchema).min(3),
  bonusFeatures: bonusFeaturesSchema,
  maxWin: z.number().positive(),
  minBet: z.number().positive(),
  maxBet: z.number().positive(),
});

export const gameTemplatesRouter = router({
  // Save a new game template
  saveTemplate: adminProcedure
    .input(gameTemplateSchema)
    .mutation(async ({ input, ctx }) => {
      const db = await getDb();

      // Create game from template
      const result = await db.insert(casinoGames).values({
        gameName: input.name,
        provider: "Template Builder",
        category: input.type,
        rtp: input.rtp,
        volatility: input.volatility,
        maxWin: input.maxWin,
        isActive: 1,
        metadata: JSON.stringify({
          template: input,
          createdBy: ctx.user.id,
          createdAt: new Date().toISOString(),
        }),
      });

      // Log audit trail
      await db.insert(transactions).values({
        userId: ctx.user.id,
        type: "admin_game_create",
        currency: "GC",
        amount: 0,
        balanceBefore: 0,
        balanceAfter: 0,
        referenceId: input.name,
        referenceType: "game",
        description: `Created game from template: ${input.name}`,
        metadata: JSON.stringify(input),
      });

      return {
        success: true,
        gameName: input.name,
        message: "Game template saved successfully",
      };
    }),

  // Get template presets
  getPresets: protectedProcedure.query(async () => {
    const db = await getDb();
    return {
      "classic-3-reel": {
        reels: 3,
        rows: 1,
        minBet: 0.01,
        maxBet: 10,
        maxWin: 1000,
        description: "Classic 3-reel slot machine",
      },
      "5-reel": {
        reels: 5,
        rows: 3,
        minBet: 0.01,
        maxBet: 50,
        maxWin: 10000,
        description: "Modern 5-reel video slot",
      },
      "bonus-heavy": {
        reels: 5,
        rows: 4,
        minBet: 0.05,
        maxBet: 100,
        maxWin: 50000,
        description: "Feature-rich bonus slot",
      },
    };
  }),

  // Get default symbols
  getDefaultSymbols: protectedProcedure.query(async () => {
    const db = await getDb();
    return [
      { id: "1", name: "Cherry", emoji: "🍒", multiplier: 2, weight: 10 },
      { id: "2", name: "Lemon", emoji: "🍋", multiplier: 3, weight: 10 },
      { id: "3", name: "Orange", emoji: "🍊", multiplier: 4, weight: 8 },
      { id: "4", name: "Grape", emoji: "🍇", multiplier: 5, weight: 6 },
      { id: "5", name: "Watermelon", emoji: "🍉", multiplier: 10, weight: 4 },
      { id: "6", name: "Diamond", emoji: "💎", multiplier: 25, weight: 2 },
    ];
  }),

  // Validate template configuration
  validateTemplate: protectedProcedure
    .input(gameTemplateSchema)
    .query(async ({ input }) => {
      const db = await getDb();
      const errors: string[] = [];

      // Validate symbol weights sum
      const totalWeight = input.symbols.reduce((sum, s) => sum + s.weight, 0);
      if (totalWeight === 0) {
        errors.push("Symbol weights must sum to a positive number");
      }

      // Validate bet limits
      if (input.minBet >= input.maxBet) {
        errors.push("Min bet must be less than max bet");
      }

      // Validate max win is achievable
      const maxPossibleWin = Math.max(...input.symbols.map((s) => s.multiplier)) * input.maxBet * input.reels;
      if (input.maxWin > maxPossibleWin * 10) {
        errors.push("Max win is too high relative to bet limits and symbols");
      }

      // Validate RTP is achievable with symbols
      if (input.rtp < 70 || input.rtp > 99) {
        errors.push("RTP must be between 70% and 99%");
      }

      return {
        valid: errors.length === 0,
        errors,
      };
    }),

  // Get template suggestions based on goals
  getSuggestions: protectedProcedure
    .input(
      z.object({
        goal: z.enum(["high-engagement", "high-revenue", "balanced", "low-volatility"]),
      })
    )
    .query(async ({ input }) => {
      const db = await getDb();
      const suggestions = {
        "high-engagement": {
          type: "bonus-heavy",
          rtp: 96,
          volatility: "high",
          bonusFeatures: {
            freeSpins: true,
            freeSpinsCount: 15,
            scatterSymbol: true,
            wildSymbol: true,
            bonusRound: true,
          },
          description: "Frequent bonus features keep players engaged",
        },
        "high-revenue": {
          type: "5-reel",
          rtp: 92,
          volatility: "high",
          bonusFeatures: {
            freeSpins: false,
            freeSpinsCount: 10,
            scatterSymbol: false,
            wildSymbol: false,
            bonusRound: false,
          },
          description: "Lower RTP with high volatility maximizes revenue",
        },
        balanced: {
          type: "5-reel",
          rtp: 96,
          volatility: "medium",
          bonusFeatures: {
            freeSpins: true,
            freeSpinsCount: 10,
            scatterSymbol: true,
            wildSymbol: false,
            bonusRound: false,
          },
          description: "Balanced approach for sustained player retention",
        },
        "low-volatility": {
          type: "classic-3-reel",
          rtp: 98,
          volatility: "low",
          bonusFeatures: {
            freeSpins: false,
            freeSpinsCount: 5,
            scatterSymbol: false,
            wildSymbol: true,
            bonusRound: false,
          },
          description: "Frequent small wins for casual players",
        },
      };

      return suggestions[input.goal];
    }),
});
