import type { RowDataPacket } from 'mysql2';
import { getPool } from './db';
import type { IContactQuestion } from '@/models/IContactQuestion';
import type { IGuideItem } from '@/models/IGuideItem';
import type { IPlayerInfo } from '@/models/IPlayerInfo';

let tournamentIdByKeyPromise: Promise<Record<string, number>> | null = null;

async function loadTournamentMap(): Promise<Record<string, number>> {
  const pool = getPool();
  const [rows] = await pool.query<RowDataPacket[]>(
    'SELECT id, tournament_key FROM tournaments'
  );
  const map: Record<string, number> = {};
  for (const row of rows) {
    map[row.tournament_key as string] = row.id as number;
  }
  return map;
}

export async function getTournamentIdByKey(): Promise<Record<string, number>> {
  if (!tournamentIdByKeyPromise) {
    tournamentIdByKeyPromise = loadTournamentMap();
  }
  return tournamentIdByKeyPromise;
}

export async function getAllPlayers(): Promise<IPlayerInfo[]> {
  const pool = getPool();
  const [rows] = await pool.query<RowDataPacket[]>(
    `SELECT p.id, p.player_key, p.player_name, p.description, p.image, c.name_id, c.name, c.name_jp
     FROM players p
     JOIN characters c ON c.id = p.character_id`
  );
  return rows as IPlayerInfo[];
}

export async function getPlayersForTournament(
  tournamentKey: string
): Promise<IPlayerInfo[] | null> {
  const tournaments = await getTournamentIdByKey();
  const tournamentId = tournaments[tournamentKey];
  if (tournamentId === undefined) {
    return null;
  }
  const pool = getPool();
  const [rows] = await pool.query<RowDataPacket[]>(
    `SELECT p.id, p.player_key, p.player_name, p.description, p.image, c.name_id, c.name, c.name_jp
     FROM players p
     JOIN player_to_tournament ptt ON p.id = ptt.player_id
     JOIN characters c ON c.id = p.character_id
     WHERE ptt.tournament_id = ?`,
    [tournamentId]
  );
  return rows as IPlayerInfo[];
}

export async function getGuideItems(): Promise<IGuideItem[]> {
  const pool = getPool();
  const [rows] = await pool.query<RowDataPacket[]>('SELECT * FROM guide');
  return rows as IGuideItem[];
}

export async function getArchiveItems(): Promise<IGuideItem[]> {
  const pool = getPool();
  const [rows] = await pool.query<RowDataPacket[]>('SELECT * FROM archive');
  return rows as IGuideItem[];
}

export async function getContactItems(): Promise<IContactQuestion[]> {
  const pool = getPool();
  const [rows] = await pool.query<RowDataPacket[]>('SELECT * FROM contact');
  return rows as IContactQuestion[];
}
