import { db } from "../db.ts";
import { users } from "../../drizzle/schema.ts";
import { eq } from 'drizzle-orm';
import { storagePut, storageGet } from "../storage.ts";

export interface PlayerProfile {
  id: number;
  username: string;
  avatarUrl: string | null;
  bio: string | null;
  achievements: Achievement[];
  level: number;
  totalWins: number;
  totalBets: number;
  joinDate: string;
}

export interface Achievement {
  id: string;
  name: string;
  description: string;
  icon: string;
  unlockedAt: string | null;
  rarity: 'common' | 'rare' | 'epic' | 'legendary';
}

const ACHIEVEMENTS: Record<string, Omit<Achievement, 'unlockedAt'>> = {
  first_spin: {
    id: 'first_spin',
    name: 'First Spin',
    description: 'Play your first game spin',
    icon: '🎰',
    rarity: 'common',
  },
  big_win_100x: {
    id: 'big_win_100x',
    name: 'Big Winner',
    description: 'Win 100x your bet in a single spin',
    icon: '🏆',
    rarity: 'epic',
  },
  streak_10: {
    id: 'streak_10',
    name: 'On Fire',
    description: 'Win 10 spins in a row',
    icon: '🔥',
    rarity: 'rare',
  },
  total_wins_100: {
    id: 'total_wins_100',
    name: 'Centennial Winner',
    description: 'Achieve 100 total wins',
    icon: '💯',
    rarity: 'rare',
  },
  vip_gold: {
    id: 'vip_gold',
    name: 'VIP Gold',
    description: 'Reach VIP Gold tier',
    icon: '👑',
    rarity: 'legendary',
  },
  tournament_winner: {
    id: 'tournament_winner',
    name: 'Tournament Champion',
    description: 'Win a tournament',
    icon: '🥇',
    rarity: 'legendary',
  },
  free_spins_50: {
    id: 'free_spins_50',
    name: 'Lucky Spinner',
    description: 'Earn 50 free spins',
    icon: '✨',
    rarity: 'rare',
  },
  social_butterfly: {
    id: 'social_butterfly',
    name: 'Social Butterfly',
    description: 'Add 10 friends',
    icon: '🦋',
    rarity: 'common',
  },
};

export async function getPlayerProfile(userId: number): Promise<PlayerProfile | null> {
  const user = await db.select().from(users).where(eq(users.id, userId)).limit(1);

  if (!user.length) return null;

  const currentUser = user[0];

  // Get player stats from transactions
  const stats = await db.raw(
    `SELECT 
      COUNT(CASE WHEN type = 'game_win' THEN 1 END) as total_wins,
      COUNT(CASE WHEN type = 'game_bet' THEN 1 END) as total_bets
    FROM transactions WHERE userId = ?`,
    [userId]
  );

  const totalWins = stats[0]?.total_wins || 0;
  const totalBets = stats[0]?.total_bets || 0;

  // Calculate level based on total wins
  const level = Math.floor(totalWins / 10) + 1;

  // Get unlocked achievements
  const unlockedAchievements = await getUnlockedAchievements(userId);

  return {
    id: currentUser.id,
    username: currentUser.username || `Player${currentUser.id}`,
    avatarUrl: currentUser.avatarUrl,
    bio: null,
    achievements: unlockedAchievements,
    level,
    totalWins,
    totalBets,
    joinDate: currentUser.createdAt,
  };
}

export async function updatePlayerProfile(
  userId: number,
  updates: {
    bio?: string;
    avatarFile?: Buffer;
    avatarMimeType?: string;
  }
) {
  let avatarUrl = undefined;

  if (updates.avatarFile) {
    const result = await storagePut(
      `profiles/${userId}/avatar-${Date.now()}`,
      updates.avatarFile,
      updates.avatarMimeType || 'image/jpeg'
    );
    avatarUrl = result.url;
  }

  const updateData: any = {};
  if (updates.bio !== undefined) updateData.bio = updates.bio;
  if (avatarUrl) updateData.avatarUrl = avatarUrl;

  if (Object.keys(updateData).length === 0) return;

  await db.update(users).set(updateData).where(eq(users.id, userId));
}

export async function getUnlockedAchievements(userId: number): Promise<Achievement[]> {
  // Get player stats
  const stats = await db.raw(
    `SELECT 
      COUNT(CASE WHEN type = 'game_win' THEN 1 END) as total_wins,
      COUNT(CASE WHEN type = 'game_bet' THEN 1 END) as total_bets,
      MAX(CASE WHEN type = 'game_win' THEN amount END) as max_win
    FROM transactions WHERE userId = ? AND type IN ('game_win', 'game_bet')`,
    [userId]
  );

  const totalWins = stats[0]?.total_wins || 0;
  const maxWin = stats[0]?.max_win || 0;

  const unlockedIds: string[] = [];

  // Check each achievement condition
  if (totalBets > 0) unlockedIds.push('first_spin');
  if (maxWin > 100) unlockedIds.push('big_win_100x');
  if (totalWins >= 100) unlockedIds.push('total_wins_100');
  if (totalWins >= 50) unlockedIds.push('free_spins_50');

  // Get achievement unlock times from database if available
  const achievements = unlockedIds.map((id) => ({
    ...ACHIEVEMENTS[id],
    unlockedAt: new Date().toISOString(),
  }));

  return achievements;
}

export function getAllAchievements(): Achievement[] {
  return Object.entries(ACHIEVEMENTS).map(([id, achievement]) => ({
    ...achievement,
    unlockedAt: null,
  }));
}
