import { createColumnHelper } from "@tanstack/react-table";
import { AttachBadge } from "@/components/keywords/attach-badge";
import { IntentBadge } from "@/components/keywords/intent-badge";
import { KdBar } from "@/components/keywords/kd-bar";
import { MetricCellView, type MetricCell } from "@/components/keywords/metric-cell";
import { Badge } from "@/components/ui/badge";
import type { DataTableFeatures } from "@/components/data-table/features";

// Ligne prête à afficher du réservoir. Les nombres et les dates sont **formatés côté
// serveur** : `Intl` divergerait entre le rendu serveur et l'hydratation (même piège que
// l'onglet Imports).
//
// Une `MetricCell` porte **N observations** et non une valeur élue (spec 2026-09-01 §3.2).
// C'est une donnée de ligne, pas de colonne : elle voyage dans `row.original`, jamais dans
// `KeywordColumnsContext` — voir plus bas pourquoi la distinction n'est pas cosmétique.
export type KeywordTableRow = {
  id: string;
  keyword: string;
  volume: MetricCell;
  kd: MetricCell;
  cpc: MetricCell;
  intent: MetricCell;
  /** Valeur brute du statut d'attache, pour le badge ; le libellé est calculé au rendu. */
  attachStatus: string;
  lists: { id: string; name: string }[];
  tags: { id: string; name: string }[];
  lastUpdatedLabel: string;
  /** `last_updated` brut : il fait vieillir l'entrée de cache de l'historique par ligne. */
  lastUpdated: string | null;
};

/** Colonnes dont l'en-tête et les cellules s'alignent à droite — les valeurs numériques. */
export const KEYWORD_NUMERIC_COLUMNS = ["volume", "kd", "cpc"];

const helper = createColumnHelper<DataTableFeatures, KeywordTableRow>();

/**
 * Ce dont les cellules ont besoin, et **rien de plus** : une valeur stable d'un rendu à
 * l'autre. C'est la condition pour que `useMemo` ne recrée pas les colonnes à chaque
 * revalidation — de nouvelles fonctions `cell` sont de nouveaux *types* d'élément pour
 * `FlexRender`, donc un démontage/remontage de **toutes** les cellules de la table. Les
 * listes et les tags, eux, changent à chaque rendu serveur : ils vont aux dialogues, qui
 * vivent au-dessus de la table, jamais aux colonnes.
 */
export type KeywordColumnsContext = {
  /** Ouvre le panneau de détail — le chemin clavier vers toutes les sources d'une ligne. */
  openDetail: (row: KeywordTableRow) => void;
};

/**
 * Colonnes du réservoir. Une **fabrique** et non une constante : chaque cellule a besoin de
 * savoir ouvrir le panneau de détail.
 */
export function keywordColumns(context: KeywordColumnsContext) {
  const metric = (key: "volume" | "kd" | "cpc", header: string) =>
    helper.accessor(key, {
      header,
      // Le tri et la recherche sont **serveur** (§7.5) : la table ne voit qu'une page.
      enableSorting: false,
      enableGlobalFilter: false,
      cell: ({ row }) => (
        <MetricCellView
          cell={row.original[key]}
          label={header}
          renderValue={key === "kd" ? (value) => <KdBar value={value} /> : undefined}
        />
      ),
    });

  return helper.columns([
    helper.accessor("keyword", {
      header: "Mot-clé",
      enableHiding: false,
      enableSorting: false,
      cell: ({ row }) => {
        // L'intention de la **première source de l'ordre** (décision A5), comme toute autre
        // métrique : les autres restent dans le panneau de détail.
        const intent = row.original.intent.values[0]?.text ?? null;
        return (
          <div className="flex min-w-0 flex-wrap items-center gap-2">
            {/* Un vrai bouton : la ligne entière est cliquable à la souris, mais le clavier
                et les lecteurs d'écran ont besoin d'une cible déclarée. */}
            <button
              type="button"
              className="hover:text-primary max-w-64 truncate text-left font-medium"
              onClick={() => context.openDetail(row.original)}
            >
              {row.original.keyword}
            </button>
            {intent === null ? null : <IntentBadge value={intent} />}
          </div>
        );
      },
    }),
    metric("volume", "Volume"),
    metric("kd", "KD"),
    metric("cpc", "CPC"),
    helper.accessor("attachStatus", {
      header: "Attache",
      enableSorting: false,
      cell: ({ row }) => <AttachBadge status={row.original.attachStatus} />,
    }),
    helper.accessor("lists", {
      header: "Listes",
      enableSorting: false,
      cell: ({ row }) =>
        row.original.lists.length === 0 ? (
          <span className="text-muted-foreground">—</span>
        ) : (
          <div className="flex flex-wrap gap-1">
            {row.original.lists.map((list) => (
              <Badge key={list.id} variant="outline" className="font-normal">
                {list.name}
              </Badge>
            ))}
          </div>
        ),
    }),
    helper.accessor("lastUpdatedLabel", {
      header: "Dernière maj",
      enableSorting: false,
      cell: ({ row }) => (
        <span className="text-muted-foreground num text-sm">{row.original.lastUpdatedLabel}</span>
      ),
    }),
  ]);
}
