import { getDb } from "../db.ts";
import { gameSessions, users } from "../../drizzle/schema.ts";
import { eq, desc, and, gte, lte } from "drizzle-orm";

export interface PlayerStats {
  totalSessions: number;
  totalWins: number;
  totalLosses: number;
  winRate: number;
  totalBet: number;
  totalWinnings: number;
  netProfit: number;
  roi: number;
  averageBet: number;
  averageWin: number;
  longestWinStreak: number;
  currentWinStreak: number;
}

export interface GameSession {
  id: number;
  userId: number;
  gameId: string;
  gameName: string;
  betAmount: number;
  winAmount: number;
  result: "win" | "loss";
  multiplier: number;
  createdAt: Date;
}

export async function getPlayerStats(userId: number): Promise<PlayerStats> {
  const db = await getDb();
  if (!db) return getDefaultStats();

  const sessions = await db
    .select()
    .from(gameSessions)
    .where(eq(gameSessions.userId, userId))
    .orderBy(desc(gameSessions.createdAt));

  if (sessions.length === 0) {
    return getDefaultStats();
  }

  const totalBet = sessions.reduce((sum, s) => sum + (s.betAmount || 0), 0);
  const totalWinnings = sessions.reduce((sum, s) => sum + (s.winAmount || 0), 0);
  const totalWins = sessions.filter((s) => s.result === "win").length;
  const totalLosses = sessions.filter((s) => s.result === "loss").length;

  let longestWinStreak = 0;
  let currentWinStreak = 0;
  let maxStreak = 0;

  for (const session of sessions.reverse()) {
    if (session.result === "win") {
      currentWinStreak++;
      maxStreak = Math.max(maxStreak, currentWinStreak);
    } else {
      currentWinStreak = 0;
    }
  }

  // Calculate current win streak from most recent sessions
  currentWinStreak = 0;
  for (const session of sessions) {
    if (session.result === "win") {
      currentWinStreak++;
    } else {
      break;
    }
  }

  const netProfit = totalWinnings - totalBet;
  const roi = totalBet > 0 ? (netProfit / totalBet) * 100 : 0;
  const winRate = sessions.length > 0 ? (totalWins / sessions.length) * 100 : 0;
  const averageBet = sessions.length > 0 ? totalBet / sessions.length : 0;
  const averageWin = totalWins > 0 ? totalWinnings / totalWins : 0;

  return {
    totalSessions: sessions.length,
    totalWins,
    totalLosses,
    winRate,
    totalBet,
    totalWinnings,
    netProfit,
    roi,
    averageBet,
    averageWin,
    longestWinStreak: maxStreak,
    currentWinStreak,
  };
}

export async function getPlayerGameSessions(
  userId: number,
  limit: number = 50,
  offset: number = 0
): Promise<GameSession[]> {
  const db = await getDb();
  if (!db) return [];

  const sessions = await db
    .select()
    .from(gameSessions)
    .where(eq(gameSessions.userId, userId))
    .orderBy(desc(gameSessions.createdAt))
    .limit(limit)
    .offset(offset);

  return sessions as GameSession[];
}

export async function getPlayerSessionsByDateRange(
  userId: number,
  startDate: Date,
  endDate: Date
): Promise<GameSession[]> {
  const db = await getDb();
  if (!db) return [];

  const sessions = await db
    .select()
    .from(gameSessions)
    .where(
      and(
        eq(gameSessions.userId, userId),
        gte(gameSessions.createdAt, startDate),
        lte(gameSessions.createdAt, endDate)
      )
    )
    .orderBy(desc(gameSessions.createdAt));

  return sessions as GameSession[];
}

export async function recordGameSession(
  userId: number,
  gameId: string,
  gameName: string,
  betAmount: number,
  winAmount: number,
  multiplier: number = 0
): Promise<void> {
  const db = await getDb();
  if (!db) return;

  const result = winAmount > 0 ? "win" : "loss";

  await db.insert(gameSessions).values({
    userId,
    gameId,
    gameName,
    betAmount,
    winAmount,
    result,
    multiplier,
    createdAt: new Date(),
  });
}

function getDefaultStats(): PlayerStats {
  return {
    totalSessions: 0,
    totalWins: 0,
    totalLosses: 0,
    winRate: 0,
    totalBet: 0,
    totalWinnings: 0,
    netProfit: 0,
    roi: 0,
    averageBet: 0,
    averageWin: 0,
    longestWinStreak: 0,
    currentWinStreak: 0,
  };
}
