"use client";

import type { ReactNode } from "react";
import { SourcePill } from "@/components/keywords/source-pill";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { sourceLabel } from "@/lib/keywords";
import { cn } from "@/lib/utils";

// La cellule métrique du réservoir, telle que la **décision A5** la définit : la valeur de la
// **première source de l'ordre rendu par l'api** (la préférée de l'organisation en tête), sa
// pastille de provenance, et les autres observations au survol.
//
// Ce que ce composant ne fait jamais, et c'est tout l'enjeu : élire une valeur, en calculer
// une moyenne, ou choisir « la meilleure ». Il affiche la première de la liste **parce que
// l'api l'a mise en premier** — l'ordre est contractuel, l'écran ne retrie rien.
//
// L'infobulle est un confort de souris, pas un chemin d'accès : elle n'est pas focusable, et
// n'ajoute donc pas trois arrêts de tabulation par ligne sur une page qui en compte cinquante.
// Le chemin clavier vers les autres sources est le panneau de détail, ouvert depuis le
// mot-clé. Un résumé `sr-only` porte les valeurs manquantes pour les lecteurs d'écran.

export type MetricValue = {
  /** Valeur affichée, déjà localisée côté serveur (`Intl` divergerait à l'hydratation). */
  text: string;
  /** Nom d'adaptateur, jamais nul : une entrée sans valeur n'entre pas dans la liste. */
  source: string;
  fetchedAtLabel: string;
  /**
   * Part de la valeur sur son échelle, de 0 à 1 — renseignée pour le KD seulement, qui se
   * rend en barre. Une métrique sans échelle bornée (volume, CPC) n'en a pas.
   */
  ratio?: number;
};

/** Toutes les observations d'un champ, dans l'ordre rendu par l'api. Vide = aucune source. */
export type MetricCell = { values: MetricValue[] };

/**
 * Un chiffre étiqueté — le rendu hors table (cartes du mobile, panneau de détail), où la
 * colonne ne porte plus le nom de la métrique et où il faut donc le remettre au-dessus.
 */
export function LabeledFigure({ label, children }: { label: string; children: ReactNode }) {
  return (
    <div className="flex min-w-0 flex-col gap-0.5">
      <span className="text-muted-foreground text-xs">{label}</span>
      {children}
    </div>
  );
}

export function MetricCellView({
  cell,
  label,
  align = "right",
  renderValue,
}: {
  cell: MetricCell;
  /** Nom de la métrique, pour le résumé accessible. */
  label: string;
  align?: "left" | "right";
  /** Rendu de la valeur de tête ; par défaut, le texte en mono tabulaire. */
  renderValue?: (value: MetricValue) => ReactNode;
}) {
  const [first, ...rest] = cell.values;
  const justify = align === "right" ? "justify-end" : "justify-start";

  if (first === undefined) {
    return <div className={cn("text-muted-foreground num flex text-sm", justify)}>—</div>;
  }

  const head = (
    <>
      {renderValue ? renderValue(first) : <span className="num text-sm">{first.text}</span>}
      <SourcePill source={first.source} />
    </>
  );

  if (rest.length === 0) {
    return <div className={cn("flex min-w-0 items-center gap-1.5", justify)}>{head}</div>;
  }

  return (
    <Tooltip>
      <TooltipTrigger
        // Un `div` et non le bouton par défaut : la cellule n'est pas un geste, et cinquante
        // lignes × trois métriques ajouteraient cent cinquante arrêts de tabulation devant une
        // information déjà atteignable au clavier par le panneau de détail.
        render={<div />}
        className={cn("flex min-w-0 cursor-default items-center gap-1.5", justify)}
      >
        {head}
        <span className="sr-only">
          {label} :{" "}
          {cell.values
            .map((value) => `${value.text}, source ${sourceLabel(value.source)}`)
            .join(" ; ")}
        </span>
      </TooltipTrigger>
      <TooltipContent>
        <ul className="flex flex-col gap-0.5">
          {/* Une seule entrée par source et par métrique côté api (`DISTINCT ON (m.source)`) :
              le nom de source est une clé stable. */}
          {cell.values.map((value) => (
            <li key={value.source} className="whitespace-nowrap">
              <span className="num">{value.text}</span> · {sourceLabel(value.source)} ·{" "}
              {value.fetchedAtLabel}
            </li>
          ))}
        </ul>
      </TooltipContent>
    </Tooltip>
  );
}
