// src/components/keywords/reservoir-toolbar.tsx — réservoir (design ELEVA
// « Toolbar Keywords — Finale (B) », slice 2) : search + pill « Filtres »
// unique (panneau 2 colonnes de lignes-facettes, application instantanée) +
// toggle « Sans page » à gauche ; « Importer » + menu « Sync » + colonnes +
// menu « Exporter » à droite.
"use client";

import type {
  ColumnFiltersState,
  VisibilityState,
} from "@tanstack/react-table";
import {
  FileOutputIcon,
  FileSpreadsheetIcon,
  FileX2Icon,
  UploadIcon,
} from "lucide-react";
import { useTranslations } from "next-intl";
import type React 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 { 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 %" },
];

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

interface ToolbarProps {
  search: string;
  onSearch: (v: string) => void;
  columnFilters: ColumnFiltersState;
  onColumnFilters: (next: ColumnFiltersState) => void;
  columnVisibility: VisibilityState;
  onColumnVisibility: (next: VisibilityState) => void;
  languages?: string[];
  /** Target countries present in the dataset (alpha-2 — feeds the « Pays » facet). */
  countries?: string[];
  /** Provider sources present in the dataset (feeds the « Source » view selector). */
  sources?: KeywordSource[];
  /** Global source view ("" = each row's primary source). One view at a time. */
  sourceView?: string;
  onSourceView?: (v: string) => void;
  /** Facette « Sans page » (module Pages) — toggle booléen, filtre les mots-clés
   *  sans page ciblée assignée. */
  noPage?: boolean;
  onNoPage?: (v: boolean) => void;
  /** Total filtré courant — description du « CSV complet » du menu Exporter. */
  resultCount: number;
  onExportFullCsv: () => void;
  onOpenExportEnrichment: () => void;
  /** Right-side actions (Importer ▾ + Ajouter). */
  actions?: React.ReactNode;
  /** Menu « Sync » (GSC + SE-Ranking) — slot fourni par le container. */
  syncMenu?: React.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?: React.ReactNode;
}

export function ReservoirToolbar({
  search,
  onSearch,
  columnFilters,
  onColumnFilters,
  columnVisibility,
  onColumnVisibility,
  languages,
  countries,
  sources,
  sourceView,
  onSourceView,
  noPage,
  onNoPage,
  resultCount,
  onExportFullCsv,
  onOpenExportEnrichment,
  actions,
  syncMenu,
  relatedButton,
}: ToolbarProps) {
  const { themes } = useThemeLabels();
  const t = useTranslations("Keywords");
  const themeLabels = Object.fromEntries(themes.map((th) => [th.id, th.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 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 mot-clé…"
          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((th) => ({ value: th.id, label: th.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 dérivé serait faux (« en » → ✖).
              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}

          {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>

        {/* Toggle 1-clic (pas un menu) : reste hors du panneau Filtres. */}
        {onNoPage ? (
          <button
            type="button"
            aria-pressed={noPage}
            onClick={() => onNoPage(!noPage)}
            className={cn(
              "inline-flex h-10 items-center gap-1.5 whitespace-nowrap rounded-[11px] border bg-card px-3 font-medium text-[13px] text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
              noPage &&
                "border-blue-500/40 bg-blue-500/10 text-blue-700 hover:bg-blue-500/15 hover:text-blue-700 dark:text-blue-200 dark:hover:text-blue-100",
            )}
          >
            <FileX2Icon className="size-3.5" aria-hidden />
            {t("facetNoPage")}
          </button>
        ) : null}
      </div>

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

        <ToolbarColumnsMenu
          columns={TOGGLEABLE_COLUMNS}
          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 (reservoir label mapping)                   */
/* ------------------------------------------------------------------ */

export function ActiveFilterChips({
  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) and ranges stay one chip.
  const chips = columnFilters.flatMap((f) => {
    const remove = (v: string) =>
      onColumnFilters(toggleFacet(columnFilters, f.id, v));
    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: ((f.value as string[])[0] ?? "").toUpperCase(),
            onRemove: () => clear("lang"),
          },
        ];
      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([])} />;
}
