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

// Responsible gaming settings stored in user metadata
interface ResponsibleGamingSettings {
  dailyDepositLimit: number | null;
  weeklyDepositLimit: number | null;
  monthlyDepositLimit: number | null;
  dailyWagerLimit: number | null;
  sessionTimeLimit: number | null; // minutes
  cooldownPeriod: number | null; // minutes between sessions
  realityCheckInterval: number | null; // minutes
  selfExclusionUntil: string | null; // ISO date
  selfExclusionPermanent: boolean;
  lastSessionStart: string | null;
  totalSessionTime: number; // minutes today
  lastRealityCheck: string | null;
}

const DEFAULT_SETTINGS: ResponsibleGamingSettings = {
  dailyDepositLimit: null,
  weeklyDepositLimit: null,
  monthlyDepositLimit: null,
  dailyWagerLimit: null,
  sessionTimeLimit: null,
  cooldownPeriod: null,
  realityCheckInterval: null,
  selfExclusionUntil: null,
  selfExclusionPermanent: false,
  lastSessionStart: null,
  totalSessionTime: 0,
  lastRealityCheck: null,
};

// In-memory store for session tracking (per user)
const sessionStore = new Map<number, { startTime: number; totalWagered: number; totalDeposited: number }>();

export const responsibleGamingRouter = router({
  // Get current settings
  getSettings: protectedProcedure.query(async ({ ctx }) => {
    const userId = ctx.user.id;
    // Retrieve from localStorage-style approach via client, or use DB metadata
    // For now, return defaults that client can override
    const session = sessionStore.get(userId);
    return {
      settings: DEFAULT_SETTINGS,
      currentSession: session
        ? {
            duration: Math.floor((Date.now() - session.startTime) / 60000),
            totalWagered: session.totalWagered,
            totalDeposited: session.totalDeposited,
          }
        : null,
    };
  }),

  // Update limits
  updateLimits: protectedProcedure
    .input(
      z.object({
        dailyDepositLimit: z.number().min(0).nullable().optional(),
        weeklyDepositLimit: z.number().min(0).nullable().optional(),
        monthlyDepositLimit: z.number().min(0).nullable().optional(),
        dailyWagerLimit: z.number().min(0).nullable().optional(),
        sessionTimeLimit: z.number().min(5).nullable().optional(),
        cooldownPeriod: z.number().min(5).nullable().optional(),
        realityCheckInterval: z.number().min(5).nullable().optional(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      // Store settings - in production these would go to DB
      // For now, return success and let client manage via localStorage
      return { success: true, message: "Limits updated successfully" };
    }),

  // Self-exclusion
  selfExclude: protectedProcedure
    .input(
      z.object({
        duration: z.enum(["24h", "7d", "30d", "90d", "6m", "1y", "permanent"]),
        reason: z.string().optional(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const userId = ctx.user.id;
      let excludeUntil: Date | null = null;

      if (input.duration !== "permanent") {
        excludeUntil = new Date();
        const durations: Record<string, number> = {
          "24h": 1,
          "7d": 7,
          "30d": 30,
          "90d": 90,
          "6m": 180,
          "1y": 365,
        };
        const days = durations[input.duration] || 1;
        excludeUntil.setDate(excludeUntil.getDate() + days);
      }

      // Ban the user for the self-exclusion period
      const database = await getDb();
      await database!
        .update(users)
        .set({
          isBanned: true,
          banReason: `Self-exclusion (${input.duration})${input.reason ? `: ${input.reason}` : ""}`,
        })
        .where(eq(users.id, userId));

      // Clear session
      sessionStore.delete(userId);

      return {
        success: true,
        excludeUntil: excludeUntil?.toISOString() || "permanent",
        message:
          input.duration === "permanent"
            ? "Your account has been permanently self-excluded. Contact support to reverse this."
            : `Your account has been self-excluded until ${excludeUntil?.toLocaleDateString()}. You will not be able to play during this period.`,
      };
    }),

  // Start session tracking
  startSession: protectedProcedure.mutation(async ({ ctx }) => {
    const userId = ctx.user.id;
    sessionStore.set(userId, {
      startTime: Date.now(),
      totalWagered: 0,
      totalDeposited: 0,
    });
    return { success: true, startTime: Date.now() };
  }),

  // End session tracking
  endSession: protectedProcedure.mutation(async ({ ctx }) => {
    const userId = ctx.user.id;
    const session = sessionStore.get(userId);
    if (session) {
      const duration = Math.floor((Date.now() - session.startTime) / 60000);
      sessionStore.delete(userId);
      return { success: true, duration, totalWagered: session.totalWagered };
    }
    return { success: true, duration: 0, totalWagered: 0 };
  }),

  // Reality check - returns session stats
  realityCheck: protectedProcedure.query(async ({ ctx }) => {
    const userId = ctx.user.id;
    const session = sessionStore.get(userId);
    if (!session) {
      return {
        active: false,
        duration: 0,
        totalWagered: 0,
        totalDeposited: 0,
        message: "No active session",
      };
    }

    const duration = Math.floor((Date.now() - session.startTime) / 60000);
    return {
      active: true,
      duration,
      totalWagered: session.totalWagered,
      totalDeposited: session.totalDeposited,
      message: `You have been playing for ${duration} minutes and wagered ${session.totalWagered.toFixed(2)} SC.`,
    };
  }),

  // Get responsible gaming resources
  getResources: protectedProcedure.query(async () => {
    return {
      helplines: [
        { name: "National Council on Problem Gambling", phone: "1-800-522-4700", url: "https://www.ncpgambling.org" },
        { name: "Gamblers Anonymous", phone: "1-888-424-3577", url: "https://www.gamblersanonymous.org" },
        { name: "National Problem Gambling Helpline", phone: "1-800-522-4700", url: "https://www.ncpgambling.org/help-treatment/national-helpline-1-800-522-4700/" },
      ],
      selfAssessment: [
        "Do you spend more time or money gambling than you intended?",
        "Have people criticized your gambling or told you that you have a gambling problem?",
        "Have you felt guilty about the way you gamble or what happens when you gamble?",
        "Have you tried to win back money you have lost (chasing losses)?",
        "Have you borrowed money or sold anything to get money to gamble?",
        "Have you felt that you might have a problem with gambling?",
        "Has gambling caused you any health problems, including stress or anxiety?",
        "Have you gambled to escape worry, trouble, boredom, or loneliness?",
      ],
      tips: [
        "Set a budget before you start playing and stick to it",
        "Set a time limit for your gaming sessions",
        "Take regular breaks during play",
        "Never chase losses - accept them as part of the game",
        "Don't gamble when you're upset, stressed, or under the influence",
        "Remember: this is entertainment, not a way to make money",
        "Keep track of how much time and money you spend",
        "Balance gambling with other leisure activities",
      ],
    };
  }),
});
