import type { ImportReport } from "@/lib/imports";

// Ventilation par pays du rapport d'import (§4.5). Le rapport porte deux dictionnaires
// `{libellé brut du fichier: décompte}` — `ignored_by_country` (lignes d'un autre pays que
// celui de la cible) et `unresolved_by_country` (libellés qu'aucune table ne résout).
//
// LE TRI VIT ICI, ET IL EST LOAD-BEARING. Le pipeline les émet déjà par décompte
// décroissant, mais `imports.report` est du **jsonb** : Postgres range ses clés par longueur
// puis par octets et l'ordre d'insertion est perdu — mesuré côté api, `{"United Kingdom":55,
// "Australia":32,"Canada":13,"Japan":1}` ressort `{"Japan":1,"Canada":13,"Australia":32,
// "United Kingdom":55}`. Sans ce tri, l'écran afficherait les pays dans un ordre arbitraire.
//
// Ce module est le voisin de `lib/imports.ts` (miroir Zod figé, un seul propriétaire) et non
// un ajout dedans : il ne décrit aucune frontière réseau, seulement la mise en ordre d'un
// champ déjà validé. Il est distinct de `lib/import-countries.ts`, qui décide des pays
// *avant* un import (quelles cibles créer, combien de jobs partent) : ici on ne décide plus
// rien, on rend lisible ce qu'un import a déjà écarté.

/** Un libellé brut du fichier et le nombre de lignes qu'il a fait écarter. */
export type CountryTally = { label: string; rows: number };

/** Un motif d'écartement et son détail par pays. */
export type CountryBreakdown = {
  key: "off_target" | "unresolved";
  /**
   * Le motif, recopié mot pour mot de `ignoredBreakdown` (`lib/imports.ts`) : la ligne du
   * listing dit « 155 ignorées (hors cible 152, pays non reconnu 3) », la page de détail doit
   * dire « hors cible » et « pays non reconnu » aussi. Ce sont les termes de la spec §4.3,
   * les mêmes que le badge du wizard — un synonyme de plus (« pays inconnu ») ferait croire
   * à un troisième décompte.
   */
  motive: string;
  /**
   * Le total du motif tel que le RAPPORT le compte, jamais la somme du dictionnaire : une
   * cellule pays vide entre dans `rows_country_unresolved` sans entrer dans le dictionnaire
   * (elle n'a pas de libellé à nommer). Les deux peuvent donc diverger, et c'est le compteur
   * qui fait foi. Repli sur la somme quand le compteur manque.
   */
  rows: number;
  entries: CountryTally[];
};

/** Décompte décroissant, puis libellé, pour que deux pays à égalité gardent un ordre stable. */
function tally(counts: Record<string, number> | undefined): CountryTally[] {
  if (counts === undefined) return [];
  return Object.entries(counts)
    .map(([label, rows]) => ({ label, rows }))
    .sort((a, b) => b.rows - a.rows || a.label.localeCompare(b.label, "fr"));
}

/**
 * Les deux répartitions par pays d'un rapport, prêtes à rendre.
 *
 * Tolérante par construction — les quatre clés sont facultatives : un import antérieur au
 * §4.5, un import `failed` (dont `report` reste `null`) et une source sans colonne pays
 * (tout Semrush, dictionnaires `{}` et compteurs à zéro) rendent tous une liste vide, donc
 * aucun bloc à l'écran. Un motif dont le dictionnaire est vide est tu : son compteur reste
 * lisible parmi les compteurs du rapport, une ligne « hors cible : » sans pays serait du bruit.
 */
export function countryBreakdowns(report: ImportReport | null | undefined): CountryBreakdown[] {
  if (!report) return [];
  const motives = [
    {
      key: "off_target",
      motive: "hors cible",
      counter: report.rows_off_target,
      counts: report.ignored_by_country,
    },
    {
      key: "unresolved",
      motive: "pays non reconnu",
      counter: report.rows_country_unresolved,
      counts: report.unresolved_by_country,
    },
  ] as const;

  const blocks: CountryBreakdown[] = [];
  for (const motive of motives) {
    const entries = tally(motive.counts);
    if (entries.length === 0) continue;
    blocks.push({
      key: motive.key,
      motive: motive.motive,
      rows:
        typeof motive.counter === "number"
          ? motive.counter
          : entries.reduce((total, entry) => total + entry.rows, 0),
      entries,
    });
  }
  return blocks;
}
