// src/components/keywords/research/research-toolbar.tsx — recherche
// (design ELEVA « Toolbar Keywords — Finale (B) ») : search ⌘K + pill
// « Filtres » unique (panneau 2 colonnes de lignes-facettes, application
// instantanée) à gauche ; « Importer » + menu « Sync » + segment liste⇄matrice
// (onglet Tous uniquement) + toggle opportunité + colonnes + menu « Exporter »
// à droite. L'ancien menu « ⋯ » est dissous (onglets de vue / menu Exporter /
// toggle) et le « Synchroniser GSC » standalone vit dans le menu Sync.
"use client";

import type {
  ColumnFiltersState,
  VisibilityState,
} from "@tanstack/react-table";
import {
  FileOutputIcon,
  FileSpreadsheetIcon,
  TrendingUpIcon,
  UploadIcon,
} from "lucide-react";
import type { ReactNode } from "react";
import {
  FacetRow,
  FiltersPanel,
  facetSummary,
} from "@/components/keywords/filters-panel";
import { Button } from "@/components/ui/button";
import {
  activeRangeCount,
  ActiveFilterChips as ChipsRow,
  clearFacet,
  FacetMenuContent,
  facetValue,
  facetValues,
  formatRange,
  MultiFacetMenuContent,
  type RangeDef,
  RangesFields,
  type RangeValue,
  setFacet,
  ToolbarColumnsMenu,
  ToolbarDivider,
  ToolbarRow,
  ToolbarSearch,
  toggleFacet,
} from "@/components/ui/design-toolbar";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Flag } from "@/components/ui/flag";
import { RichMenuItem, RichMenuSection } from "@/components/ui/rich-menu";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { useThemeLabels } from "@/lib/keywords/theme-context";
import {
  KEYWORD_STATUSES,
  type KeywordSource,
  type SearchIntent,
} from "@/lib/keywords/types";
import { countryLabel } from "@/lib/sites/options";
import { cn } from "@/lib/utils";
import { TOGGLEABLE_COLUMNS } from "../columns";
import { INTENT_FULL_LABELS, INTENT_LABELS } from "../intent-badge";
import { SOURCE_LABELS } from "../keyword-modal-utils";
import { STATUS_LABELS } from "../status-badge";

const INTENTS: SearchIntent[] = [
  "informational",
  "commercial",
  "transactional",
  "navigational",
  "local",
];

const RANGES: RangeDef[] = [
  { id: "volume", label: "Volume" },
  { id: "kd", label: "KD" },
  { id: "cpc", label: "CPC" },
  { id: "growthPct", label: "Croissance %" },
];

// GSC positioning bands (URL-backed `gsc` facet, column id `gscPosition`).
const GSC_BAND_OPTIONS: { value: string; label: string }[] = [
  { value: "top10", label: "Top 10 (≤ 10)" },
  { value: "quickwin", label: "Quick wins (11–20)" },
  { value: "beyond", label: "Au-delà (> 20)" },
  { value: "none", label: "Non positionné" },
];

const GSC_BAND_CHIP_LABELS: Record<string, string> = {
  top10: "Top 10",
  quickwin: "Quick wins",
  beyond: "Au-delà",
  none: "Non positionné",
};

export type ResearchView = "list" | "matrix";

/* ------------------------------------------------------------------ */
/* toolbar row                                                         */
/* ------------------------------------------------------------------ */

export function ResearchToolbar({
  search,
  onSearch,
  columnFilters,
  onColumnFilters,
  columnVisibility,
  onColumnVisibility,
  languages,
  countries,
  view,
  onViewChange,
  showViewToggle,
  quickwinsLocked,
  oppActive,
  onToggleOpportunity,
  resultCount,
  onExportFullCsv,
  onOpenExportEnrichment,
  sources,
  sourceView,
  onSourceView,
  importButton,
  syncMenu,
  relatedButton,
}: {
  search: string;
  onSearch: (v: string) => void;
  /** Effective filters: local column filters + the URL-backed GSC band. */
  columnFilters: ColumnFiltersState;
  onColumnFilters: (next: ColumnFiltersState) => void;
  columnVisibility: VisibilityState;
  onColumnVisibility: (next: VisibilityState) => void;
  languages?: string[];
  /** Target countries present (alpha-2 — feeds the « Pays » facet). */
  countries?: string[];
  view: ResearchView;
  onViewChange: (v: ResearchView) => void;
  /** Segment liste⇄matrice rendu seulement sur l'onglet « Tous ». */
  showViewToggle: boolean;
  /** Onglet « Quick-wins GSC » actif : la facette GSC est verrouillée sur
   *  « Quick-wins » (l'onglet impose la bande, la facette ne peut la changer). */
  quickwinsLocked?: boolean;
  oppActive: boolean;
  onToggleOpportunity: () => void;
  /** Total filtré courant — description du « CSV complet » du menu Exporter. */
  resultCount: number;
  onExportFullCsv: () => void;
  onOpenExportEnrichment: () => void;
  /** Provider sources present in the dataset (feeds the « Source » selector). */
  sources?: KeywordSource[];
  /** Global source view ("" = primary). One view at a time. */
  sourceView?: string;
  onSourceView?: (v: string) => void;
  /** « Importer ▾ » button (same as the reservoir) rendered in the right group. */
  importButton?: ReactNode;
  /** Menu « Sync » (GSC + SE-Ranking) — slot fourni par le container. */
  syncMenu?: ReactNode;
  /** Bouton « Mots-clés associés » (Mangools KWFinder) — slot fourni par le
   *  container, actif si exactement 1 kw sélectionné, masqué si connecteur
   *  Mangools non branché. */
  relatedButton?: ReactNode;
}) {
  const { themes } = useThemeLabels();
  const themeLabels = Object.fromEntries(themes.map((t) => [t.id, t.label]));

  const themeValues = facetValues(columnFilters, "theme");
  const statusValues = facetValues(columnFilters, "status");
  const intentValues = facetValues(columnFilters, "intent");
  const countryValues = facetValues(columnFilters, "country");
  const langValue = facetValue(columnFilters, "lang");
  const gscValue = facetValue(columnFilters, "gscPosition");
  const rangesCount = activeRangeCount(columnFilters, RANGES);

  return (
    <ToolbarRow>
      <div className="flex min-w-0 flex-1 flex-wrap items-center gap-2.5">
        <ToolbarSearch
          value={search}
          onChange={onSearch}
          placeholder="Rechercher un terme…"
          ariaLabel="Rechercher un mot-clé"
        />

        <FiltersPanel
          activeCount={columnFilters.length}
          onResetAll={() => onColumnFilters([])}
        >
          <FacetRow
            label="Thèmes"
            ariaLabel="Filtrer par thème"
            value={facetSummary(themeValues, "Tous", themeLabels)}
            active={themeValues.length > 0}
          >
            <MultiFacetMenuContent
              allLabel="Tous les thèmes"
              values={themeValues}
              options={themes.map((t) => ({ value: t.id, label: t.label }))}
              onToggle={(v) =>
                onColumnFilters(toggleFacet(columnFilters, "theme", v))
              }
              onClear={() =>
                onColumnFilters(clearFacet(columnFilters, "theme"))
              }
            />
          </FacetRow>

          <FacetRow
            label="Statut"
            ariaLabel="Filtrer par statut"
            value={facetSummary(statusValues, "Tous", STATUS_LABELS)}
            active={statusValues.length > 0}
          >
            <MultiFacetMenuContent
              allLabel="Tous les statuts"
              values={statusValues}
              options={KEYWORD_STATUSES.map((s) => ({
                value: s,
                label: STATUS_LABELS[s],
              }))}
              onToggle={(v) =>
                onColumnFilters(toggleFacet(columnFilters, "status", v))
              }
              onClear={() =>
                onColumnFilters(clearFacet(columnFilters, "status"))
              }
            />
          </FacetRow>

          <FacetRow
            label="Intents"
            ariaLabel="Filtrer par intent"
            value={facetSummary(intentValues, "Tous", INTENT_LABELS)}
            active={intentValues.length > 0}
          >
            <MultiFacetMenuContent
              allLabel="Tous les intents"
              values={intentValues}
              options={INTENTS.map((i) => ({
                value: i,
                label: INTENT_FULL_LABELS[i],
              }))}
              onToggle={(v) =>
                onColumnFilters(toggleFacet(columnFilters, "intent", v))
              }
              onClear={() =>
                onColumnFilters(clearFacet(columnFilters, "intent"))
              }
            />
          </FacetRow>

          {languages && languages.length > 0 ? (
            <FacetRow
              label="Langue"
              ariaLabel="Filtrer par langue"
              // Pas de drapeau : la valeur est un code LANGUE (`en`, `fr`…),
              // pas un pays — un drapeau ici rendrait une séquence invalide
              // (« E N »). Le filtre Pays porte les drapeaux.
              value={langValue ? langValue.toUpperCase() : "Toutes"}
              active={langValue !== ""}
            >
              <FacetMenuContent
                allLabel="Toutes les langues"
                value={langValue || "all"}
                options={languages.map((l) => ({
                  value: l,
                  label: l.toUpperCase(),
                }))}
                onChange={(v) =>
                  onColumnFilters(setFacet(columnFilters, "lang", v))
                }
              />
            </FacetRow>
          ) : null}

          {countries && countries.length > 0 ? (
            <FacetRow
              label="Pays"
              ariaLabel="Filtrer par pays cible"
              value={facetSummary(
                countryValues,
                "Tous",
                // Résumé du filtre = texte (type string) : nom seul, sans drapeau.
                Object.fromEntries(countries.map((c) => [c, countryLabel(c)])),
              )}
              active={countryValues.length > 0}
            >
              <MultiFacetMenuContent
                allLabel="Tous les pays"
                values={countryValues}
                options={countries.map((c) => ({
                  value: c,
                  label: (
                    <span className="inline-flex items-center gap-1.5">
                      <Flag code={c} />
                      {countryLabel(c)}
                    </span>
                  ),
                }))}
                onToggle={(v) =>
                  onColumnFilters(toggleFacet(columnFilters, "country", v))
                }
                onClear={() =>
                  onColumnFilters(clearFacet(columnFilters, "country"))
                }
              />
            </FacetRow>
          ) : null}

          <FacetRow
            label="GSC"
            ariaLabel="Filtrer par positionnement GSC"
            value={
              quickwinsLocked
                ? "Quick-wins"
                : gscValue
                  ? (GSC_BAND_CHIP_LABELS[gscValue] ?? gscValue)
                  : "Tous"
            }
            active={quickwinsLocked || gscValue !== ""}
            disabled={quickwinsLocked}
          >
            <FacetMenuContent
              allLabel="Positionnement : tous"
              value={gscValue || "all"}
              options={GSC_BAND_OPTIONS}
              onChange={(v) =>
                onColumnFilters(setFacet(columnFilters, "gscPosition", v))
              }
            />
          </FacetRow>

          {sources && sources.length > 0 && onSourceView ? (
            <FacetRow
              label="Source"
              ariaLabel="Vue par source de données"
              value={
                sourceView
                  ? (SOURCE_LABELS[sourceView as KeywordSource] ?? sourceView)
                  : "Primaire"
              }
              active={Boolean(sourceView)}
            >
              <FacetMenuContent
                allLabel="Source primaire"
                value={sourceView || "all"}
                options={sources.map((s) => ({
                  value: s,
                  label: SOURCE_LABELS[s],
                }))}
                onChange={(v) => onSourceView(v === "all" ? "" : v)}
              />
            </FacetRow>
          ) : null}

          <FacetRow
            label="Plages (Vol, KD, CPC…)"
            ariaLabel="Filtrer par plages numériques"
            variant="popover"
            value={rangesCount > 0 ? String(rangesCount) : "—"}
            active={rangesCount > 0}
          >
            <div className="space-y-3">
              <RangesFields
                ranges={RANGES}
                filters={columnFilters}
                onFilters={onColumnFilters}
              />
            </div>
          </FacetRow>
        </FiltersPanel>
      </div>

      {/* right actions */}
      <div className="flex shrink-0 items-center gap-2.5">
        {importButton}
        {relatedButton}
        {syncMenu}
        <ToolbarDivider />

        {showViewToggle ? (
          // Ancre du tutoriel « research-matrix ». Elle vise le BASCULEUR et
          // non la matrice elle-même : le tour ne démarre que sur la vue Liste
          // (son premier point s'ancre sur `research-table`), donc une ancre
          // posée sur la matrice serait toujours absente et le point serait
          // silencieusement filtré.
          <Tabs
            data-tour="research-matrix"
            value={view}
            onValueChange={(v) => onViewChange(v as ResearchView)}
          >
            <TabsList className="rounded-[11px] group-data-horizontal/tabs:h-10">
              <TabsTrigger value="list" className="rounded-[8px] px-3">
                Liste
              </TabsTrigger>
              <TabsTrigger value="matrix" className="rounded-[8px] px-3">
                Matrice
              </TabsTrigger>
            </TabsList>
          </Tabs>
        ) : null}

        <Button
          variant="outline"
          size="icon"
          className={cn(
            "size-10 rounded-[11px]",
            oppActive
              ? "border-blue-500/40 bg-blue-500/10 text-blue-700 hover:bg-blue-500/15 hover:text-blue-700 dark:text-blue-200"
              : "text-muted-foreground hover:text-foreground",
          )}
          aria-pressed={oppActive}
          aria-label="Trier par opportunité"
          title="Trier par opportunité"
          onClick={onToggleOpportunity}
        >
          <TrendingUpIcon className="size-4" aria-hidden />
        </Button>

        <ToolbarColumnsMenu
          columns={[
            ...TOGGLEABLE_COLUMNS,
            { id: "gscPosition", label: "Pos. GSC" },
          ]}
          columnVisibility={columnVisibility}
          onColumnVisibility={onColumnVisibility}
        />

        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button
              variant="outline"
              size="icon"
              className="size-10 rounded-[11px] text-muted-foreground hover:text-foreground"
              aria-label="Exporter"
              title="Exporter"
            >
              <UploadIcon className="size-4" aria-hidden />
            </Button>
          </DropdownMenuTrigger>
          {/* w- explicite (pas min-w-) : la base force la largeur du trigger
              (icobtn 40px) — cf. gotcha du menu Sync. */}
          <DropdownMenuContent
            align="end"
            className="w-[280px] rounded-[14px] p-1.5"
          >
            <RichMenuSection>Exporter</RichMenuSection>
            <RichMenuItem
              icon={<FileSpreadsheetIcon />}
              iconClassName="border border-border bg-muted text-foreground"
              title="CSV complet"
              description={`Tous les résultats filtrés (${resultCount})`}
              onSelect={onExportFullCsv}
            />
            <RichMenuItem
              icon={<FileOutputIcon />}
              iconClassName="border border-border bg-muted text-foreground"
              title="Export enrichissement…"
              description="Portées : sélection, périmés, jamais synchro"
              onSelect={onOpenExportEnrichment}
            />
          </DropdownMenuContent>
        </DropdownMenu>
      </div>
    </ToolbarRow>
  );
}

/* ------------------------------------------------------------------ */
/* active filter chips row (recherche label mapping, incl. bande GSC)  */
/* ------------------------------------------------------------------ */

export function ResearchFilterChips({
  columnFilters,
  onColumnFilters,
}: {
  columnFilters: ColumnFiltersState;
  onColumnFilters: (next: ColumnFiltersState) => void;
}) {
  const { labelOf } = useThemeLabels();

  const clear = (id: string) =>
    onColumnFilters(columnFilters.filter((f) => f.id !== id));

  // Multi-value facets (theme/status/intent) expand to one removable chip per
  // selected value ; single-value facets (lang/gscPosition) and ranges = 1 chip.
  const chips = columnFilters.flatMap((f) => {
    const remove = (v: string) =>
      onColumnFilters(toggleFacet(columnFilters, f.id, v));
    const first = (f.value as string[])[0];
    switch (f.id) {
      case "theme":
        return (f.value as string[]).map((v) => ({
          key: `theme:${v}`,
          category: "Thème",
          value: labelOf(v as Parameters<typeof labelOf>[0]),
          onRemove: () => remove(v),
        }));
      case "status":
        return (f.value as string[]).map((v) => ({
          key: `status:${v}`,
          category: "Statut",
          value: STATUS_LABELS[v as keyof typeof STATUS_LABELS] ?? v,
          onRemove: () => remove(v),
        }));
      case "intent":
        return (f.value as string[]).map((v) => ({
          key: `intent:${v}`,
          category: "Intent",
          value: INTENT_LABELS[v as keyof typeof INTENT_LABELS] ?? v,
          onRemove: () => remove(v),
        }));
      case "country":
        return (f.value as string[]).map((v) => ({
          key: `country:${v}`,
          category: "Pays",
          // Chip = libellé texte (type string) : nom seul, sans drapeau.
          value: countryLabel(v),
          onRemove: () => remove(v),
        }));
      case "lang":
        return [
          {
            key: "lang",
            category: "Langue",
            value: (first ?? "").toUpperCase(),
            onRemove: () => clear("lang"),
          },
        ];
      case "gscPosition":
        return [
          {
            key: "gscPosition",
            category: "GSC",
            value: GSC_BAND_CHIP_LABELS[first] ?? first,
            onRemove: () => clear("gscPosition"),
          },
        ];
      default: {
        const range = RANGES.find((r) => r.id === f.id);
        return [
          {
            key: f.id,
            category: range?.label ?? f.id,
            value: formatRange(f.value as RangeValue),
            onRemove: () => clear(f.id),
          },
        ];
      }
    }
  });

  return <ChipsRow chips={chips} onClearAll={() => onColumnFilters([])} />;
}
