// Données simulées pour le tableau de bord Loto 5/90 Côte d'Ivoire

export interface Payout {
  rank: number;
  matched: number;
  prize: number;
  winners: number;
}

export interface Draw {
  id: string;
  name: string;
  date: string;
  numbers: number[];
  machine: number[];
  winners: number;
  jackpot: number;
  payouts: Payout[];
}

export const recentDraws: Draw[] = [
  {
    id: "T-2048",
    name: "Réveil",
    date: "05 Juin 2026 · 10h00",
    numbers: [12, 47, 8, 63, 29],
    machine: [5, 81, 34, 19, 70],
    winners: 142,
    jackpot: 85_000_000,
    payouts: [
      { rank: 1, matched: 5, prize: 85_000_000, winners: 2 },
      { rank: 2, matched: 4, prize: 850_000, winners: 18 },
      { rank: 3, matched: 3, prize: 65_000, winners: 122 },
      { rank: 4, matched: 2, prize: 5_000, winners: 0 },
    ],
  },
  {
    id: "T-2047",
    name: "Étoile",
    date: "04 Juin 2026 · 13h00",
    numbers: [3, 55, 71, 22, 40],
    machine: [88, 16, 49, 7, 61],
    winners: 98,
    jackpot: 62_000_000,
    payouts: [
      { rank: 1, matched: 5, prize: 62_000_000, winners: 1 },
      { rank: 2, matched: 4, prize: 620_000, winners: 12 },
      { rank: 3, matched: 3, prize: 50_000, winners: 85 },
      { rank: 4, matched: 2, prize: 5_000, winners: 0 },
    ],
  },
  {
    id: "T-2046",
    name: "Akwaba",
    date: "04 Juin 2026 · 16h00",
    numbers: [77, 14, 38, 90, 6],
    machine: [25, 52, 11, 68, 43],
    winners: 211,
    jackpot: 120_000_000,
    payouts: [
      { rank: 1, matched: 5, prize: 120_000_000, winners: 3 },
      { rank: 2, matched: 4, prize: 1_200_000, winners: 28 },
      { rank: 3, matched: 3, prize: 80_000, winners: 180 },
      { rank: 4, matched: 2, prize: 5_000, winners: 0 },
    ],
  },
  {
    id: "T-2045",
    name: "Espoir",
    date: "03 Juin 2026 · 18h00",
    numbers: [9, 33, 60, 18, 84],
    machine: [2, 47, 75, 30, 56],
    winners: 67,
    jackpot: 45_000_000,
    payouts: [
      { rank: 1, matched: 5, prize: 45_000_000, winners: 1 },
      { rank: 2, matched: 4, prize: 450_000, winners: 8 },
      { rank: 3, matched: 3, prize: 45_000, winners: 58 },
      { rank: 4, matched: 2, prize: 5_000, winners: 0 },
    ],
  },
  {
    id: "T-2044",
    name: "Fortune",
    date: "03 Juin 2026 · 20h00",
    numbers: [41, 7, 66, 28, 53],
    machine: [13, 90, 36, 80, 21],
    winners: 154,
    jackpot: 98_000_000,
    payouts: [
      { rank: 1, matched: 5, prize: 98_000_000, winners: 2 },
      { rank: 2, matched: 4, prize: 980_000, winners: 22 },
      { rank: 3, matched: 3, prize: 70_000, winners: 130 },
      { rank: 4, matched: 2, prize: 5_000, winners: 0 },
    ],
  },
];

export const latestDraw = recentDraws[0];

// Numéros chauds (les plus sortis) et froids (les moins sortis)
export const hotNumbers = [
  { num: 47, freq: 38 },
  { num: 7, freq: 35 },
  { num: 12, freq: 33 },
  { num: 63, freq: 31 },
  { num: 29, freq: 30 },
  { num: 84, freq: 28 },
];

export const coldNumbers = [
  { num: 19, freq: 6 },
  { num: 58, freq: 7 },
  { num: 4, freq: 8 },
  { num: 72, freq: 9 },
  { num: 36, freq: 10 },
  { num: 90, freq: 11 },
];

// Ventes des 7 derniers jours (en millions de FCFA)
export const salesData = [
  { day: "Lun", ventes: 124, gains: 78 },
  { day: "Mar", ventes: 142, gains: 91 },
  { day: "Mer", ventes: 138, gains: 85 },
  { day: "Jeu", ventes: 167, gains: 102 },
  { day: "Ven", ventes: 198, gains: 130 },
  { day: "Sam", ventes: 245, gains: 168 },
  { day: "Dim", ventes: 221, gains: 149 },
];

export const drawSchedule = [
  // Lundi
  { name: "Réveil", days: [1], time: "10:00" },
  { name: "Étoile", days: [1], time: "13:00" },
  { name: "Akwaba", days: [1], time: "16:00" },
  { name: "Monday Special", days: [1], time: "19:00" },
  // Mardi
  { name: "La Matinale", days: [2], time: "10:00" },
  { name: "Emergence", days: [2], time: "13:00" },
  { name: "Sika", days: [2], time: "16:00" },
  { name: "Lucky Tuesday", days: [2], time: "19:00" },
  // Mercredi
  { name: "Première Heure", days: [3], time: "10:00" },
  { name: "Fortune", days: [3], time: "13:00" },
  { name: "Baraka", days: [3], time: "16:00" },
  { name: "Midweek", days: [3], time: "19:00" },
  // Jeudi
  { name: "Kado", days: [4], time: "10:00" },
  { name: "Privilège", days: [4], time: "13:00" },
  { name: "Monni", days: [4], time: "16:00" },
  { name: "Fortune Thursday", days: [4], time: "19:00" },
  // Vendredi
  { name: "Cash", days: [5], time: "10:00" },
  { name: "Solution", days: [5], time: "13:00" },
  { name: "Wari", days: [5], time: "16:00" },
  { name: "Friday Bonanza", days: [5], time: "19:00" },
  // Samedi
  { name: "Soutra", days: [6], time: "10:00" },
  { name: "Diamant", days: [6], time: "13:00" },
  { name: "Moaye", days: [6], time: "16:00" },
  { name: "National", days: [6], time: "19:00" },
  // Dimanche
  { name: "Bénédiction", days: [0], time: "10:00" },
  { name: "Prestige", days: [0], time: "13:00" },
  { name: "Awalé", days: [0], time: "16:00" },
  { name: "Espoir", days: [0], time: "19:00" },
  // Tous les jours
  { name: "Digital Réveil 7h", days: [0, 1, 2, 3, 4, 5, 6], time: "07:00" },
  { name: "Digital Réveil 8h", days: [0, 1, 2, 3, 4, 5, 6], time: "08:00" },
  { name: "Afterwork", days: [0, 1, 2, 3, 4, 5, 6], time: "18:00" },
  { name: "Digital 21h", days: [0, 1, 2, 3, 4, 5, 6], time: "21:00" },
  { name: "Digital 22h", days: [0, 1, 2, 3, 4, 5, 6], time: "22:00" },
  { name: "Digital 23h", days: [0, 1, 2, 3, 4, 5, 6], time: "23:00" },
  // Vendredi et Samedi
  { name: "Spécial Weekend 1h", days: [5, 6], time: "01:00" },
  { name: "Spécial Weekend 3h", days: [5, 6], time: "03:00" },
];

export function getTodayDrawsSchedule() {
  const now = new Date();
  const todayDay = now.getDay(); // 0 = Dimanche, 1 = Lundi, etc.
  
  return drawSchedule
    .filter(d => d.days.includes(todayDay))
    .sort((a, b) => a.time.localeCompare(b.time));
}

export function getUpcomingDraws() {
  const now = new Date();
  const todayDay = now.getDay();
  const currentHours = now.getHours();
  const currentMinutes = now.getMinutes();
  const currentTimeStr = `${String(currentHours).padStart(2, '0')}:${String(currentMinutes).padStart(2, '0')}`;

  let upcoming = drawSchedule
    .filter(d => d.days.includes(todayDay) && d.time > currentTimeStr)
    .sort((a, b) => a.time.localeCompare(b.time));

  if (upcoming.length < 3) {
    const tomorrowDay = (todayDay + 1) % 7;
    const tomorrowDraws = drawSchedule
      .filter(d => d.days.includes(tomorrowDay))
      .sort((a, b) => a.time.localeCompare(b.time));
    upcoming = [...upcoming, ...tomorrowDraws];
  }

  return upcoming.slice(0, 5).map(d => {
    // Generate countdown manually or return structured data
    let drawDate = new Date(now);
    const [hours, minutes] = d.time.split(':').map(Number);
    drawDate.setHours(hours, minutes, 0, 0);
    
    if (d.time <= currentTimeStr || !d.days.includes(todayDay)) {
       drawDate.setDate(drawDate.getDate() + 1);
    }

    const diffMs = drawDate.getTime() - now.getTime();
    const diffHrs = Math.floor(diffMs / (1000 * 60 * 60));
    const diffMins = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60));

    return {
      name: d.name,
      time: d.time,
      countdown: `${String(diffHrs).padStart(2, '0')}h ${String(diffMins).padStart(2, '0')}m`
    };
  });
}

export function formatFCFA(value: number): string {
  return new Intl.NumberFormat("fr-FR").format(value) + " F";
}

export function formatCompact(value: number): string {
  if (value >= 1_000_000) return (value / 1_000_000).toFixed(0) + " M";
  if (value >= 1_000) return (value / 1_000).toFixed(0) + " K";
  return String(value);
}

export function getDrawById(id: string): Draw | undefined {
  return recentDraws.find((d) => d.id === id);
}

export function getPreviousDraws(currentId: string, count: number = 3): Draw[] {
  const idx = recentDraws.findIndex((d) => d.id === currentId);
  if (idx === -1) return [];
  return recentDraws.slice(idx + 1, idx + 1 + count);
}

export const allDrawNames = [
  "Réveil",
  "Étoile",
  "Akwaba",
  "Monday Special",
  "La Matinale",
  "Emergence",
  "Sika",
  "Lucky Tuesday",
  "Première Heure",
  "Fortune",
  "Baraka",
  "Midweek",
  "Kado",
  "Privilège",
  "Monni",
  "Fortune Thursday",
  "Cash",
  "Solution",
  "Wari",
  "Friday Bonanza",
  "Soutra",
  "Diamant",
  "Moaye",
  "National",
  "Bénédiction",
  "Prestige",
  "Awalé",
  "Espoir",
  "Day Off",
  "Digital 21h",
  "Digital Réveil 7h",
  "Digital 23h",
  "Spécial Weekend 1h",
  "Spécial Weekend 3h",
  "Digital Réveil 8h",
  "Digital 22h",
  "Afterwork",
];

export const drawGroups = [
  {
    label: "Tous les tirages",
    items: allDrawNames,
  },
];

export function getDrawIdByName(name: string): string | undefined {
  return recentDraws.find((d) => d.name === name)?.id;
}

// ---------------------------------------------------------------------------
// Slug helpers : chaque module/tirage devient une page autonome cliquable
// ---------------------------------------------------------------------------

export function slugify(name: string): string {
  return name
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/(^-|-$)/g, "");
}

export function getDrawNameBySlug(slug: string): string | undefined {
  return allDrawNames.find((n) => slugify(n) === slug);
}

// ---------------------------------------------------------------------------
// Ordre canonique des tirages — source unique de vérité partagée par toutes
// les vues (sidebar, grille, filtres, export PDF).
// ---------------------------------------------------------------------------

export const drawOrderIndex: Record<string, number> = Object.fromEntries(
  allDrawNames.map((name, i) => [name, i]),
);

export function getDrawOrder(name: string): number {
  return drawOrderIndex[name] ?? Number.MAX_SAFE_INTEGER;
}

/** Trie n'importe quelle liste d'éléments selon l'ordre canonique des tirages. */
export function sortByDrawOrder<T>(items: T[], getName: (item: T) => string): T[] {
  return [...items].sort((a, b) => {
    const timeA = getDrawTime(getName(a));
    const timeB = getDrawTime(getName(b));
    if (timeA !== timeB) {
      return timeB.localeCompare(timeA); // DESCENDING
    }
    return getDrawOrder(getName(b)) - getDrawOrder(getName(a)); // DESCENDING
  });
}

export function getDrawTime(name: string): string {
  const draw = drawSchedule.find(d => d.name === name);
  return draw ? draw.time : "99:99";
}

// ---------------------------------------------------------------------------
// Générateur de statistiques déterministe (seedé par le nom du tirage)
// Reproduit les informations des affiches officielles :
//  - Numéros les plus / moins souvent sortis (5 premières & 5 dernières places)
//  - Numéros chauds du moment (25 derniers tirages)
//  - Tous les numéros et leur nombre de sorties
//  - Résultats des 25 derniers tirages
// ---------------------------------------------------------------------------

function hashString(s: string): number {
  let h = 2166136261;
  for (let i = 0; i < s.length; i++) {
    h ^= s.charCodeAt(i);
    h = Math.imul(h, 16777619);
  }
  return h >>> 0;
}

function mulberry32(seed: number): () => number {
  let a = seed >>> 0;
  return () => {
    a |= 0;
    a = (a + 0x6d2b79f5) | 0;
    let t = Math.imul(a ^ (a >>> 15), 1 | a);
    t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

export interface FreqEntry {
  num: number;
  freq: number;
}

export interface DrawResultRow {
  drawNo: number;
  date: string;
  first: number[]; // 5 premiers numéros tirés
  last: number[]; // 5 derniers numéros tirés
}

export interface RankedFreq {
  most: FreqEntry[]; // top 5
  least: FreqEntry[]; // bottom 5
}

export interface DrawStats {
  name: string;
  firstPlace: RankedFreq;
  lastPlace: RankedFreq;
  hotFirst: FreqEntry[];
  hotLast: FreqEntry[];
  allFirst: FreqEntry[]; // 90 numéros
  allLast: FreqEntry[]; // 90 numéros
  results: DrawResultRow[]; // 25 derniers tirages
}

const FR_MONTHS = [
  "janvier", "février", "mars", "avril", "mai", "juin",
  "juillet", "août", "septembre", "octobre", "novembre", "décembre",
];

function formatFrDate(d: Date): string {
  return `${d.getDate()} ${FR_MONTHS[d.getMonth()]} ${d.getFullYear()}`;
}

function pickDistinct(rand: () => number, count: number): number[] {
  const set = new Set<number>();
  while (set.size < count) {
    set.add(1 + Math.floor(rand() * 90));
  }
  return [...set];
}

export function computeStatsFromRows(name: string, rows: DrawResultRow[]): DrawStats {
  const allFirst: FreqEntry[] = [];
  const allLast: FreqEntry[] = [];
  
  const countFirstAll = new Map<number, number>();
  const countLastAll = new Map<number, number>();
  
  for (const r of rows) {
    r.first.forEach((n) => countFirstAll.set(n, (countFirstAll.get(n) ?? 0) + 1));
    r.last.forEach((n) => countLastAll.set(n, (countLastAll.get(n) ?? 0) + 1));
  }
  
  for (let n = 1; n <= 90; n++) {
    allFirst.push({ num: n, freq: countFirstAll.get(n) ?? 0 });
    allLast.push({ num: n, freq: countLastAll.get(n) ?? 0 });
  }

  const rank = (arr: FreqEntry[]): RankedFreq => {
    const sorted = [...arr].sort((a, b) => b.freq - a.freq);
    return {
      most: sorted.slice(0, 5),
      least: sorted.slice(-5).reverse(),
    };
  };

  const recentResults = rows.slice(0, 25);

  const countFirst = new Map<number, number>();
  const countLast = new Map<number, number>();
  for (const r of recentResults) {
    r.first.forEach((n) => countFirst.set(n, (countFirst.get(n) ?? 0) + 1));
    r.last.forEach((n) => countLast.set(n, (countLast.get(n) ?? 0) + 1));
  }
  
  const toHot = (m: Map<number, number>): FreqEntry[] =>
    [...m.entries()]
      .map(([num, freq]) => ({ num, freq }))
      .sort((a, b) => b.freq - a.freq || a.num - b.num)
      .slice(0, 5);

  return {
    name,
    firstPlace: rank(allFirst),
    lastPlace: rank(allLast),
    hotFirst: toHot(countFirst),
    hotLast: toHot(countLast),
    allFirst,
    allLast,
    results: rows,
  };
}
