// src/components/keywords/add-keyword-dialog.tsx
"use client";

import { useEffect, useRef, useState } from "react";
import { QuotaNotice } from "@/components/billing/quota-notice";
import { SingleCombobox } from "@/components/site/single-combobox";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Pill } from "@/components/ui/pill";
import type { QuotaExceeded } from "@/lib/billing/quotas";
import { addKeywordAction } from "@/lib/keywords/actions";
import { useActiveSite } from "@/lib/keywords/site-context";
import type { KeywordTheme, SearchIntent } from "@/lib/keywords/types";
import {
  COUNTRY_OPTIONS,
  LANGUAGE_OPTIONS,
  siteCountryOptions,
  siteLanguageOptions,
} from "@/lib/sites/options";
import { ThemeSelect } from "./theme-select";

const INTENTS: SearchIntent[] = [
  "informational",
  "commercial",
  "transactional",
  "navigational",
  "local",
];
const INTENT_LABELS: Record<SearchIntent, string> = {
  informational: "Info",
  commercial: "Commercial",
  transactional: "Transac",
  navigational: "Navig",
  local: "Local",
};

export function AddKeywordDialog({
  open,
  onOpenChange,
  siteId,
  onAdded,
}: {
  open: boolean;
  onOpenChange: (o: boolean) => void;
  siteId: string;
  onAdded: () => void;
}) {
  const { activeSite } = useActiveSite();

  // Options langue/pays dérivées du site actif ; repli sur l'univers Google Ads
  // (LANGUAGE_OPTIONS / COUNTRY_OPTIONS) tant que le site n'est pas résolu.
  const langOptions = activeSite
    ? siteLanguageOptions(activeSite)
    : LANGUAGE_OPTIONS;
  const countryOptions = activeSite
    ? siteCountryOptions(activeSite)
    : COUNTRY_OPTIONS;

  const [term, setTerm] = useState("");
  const [lang, setLang] = useState(() => activeSite?.primaryLanguage ?? "en");
  const [country, setCountry] = useState(
    () => activeSite?.targetCountries?.[0] ?? "",
  );
  const [theme, setTheme] = useState<KeywordTheme | null>(null);
  const [intent, setIntent] = useState<SearchIntent[]>([]);
  const [destination, setDestination] = useState<"reservoir" | "recherche">(
    "reservoir",
  );
  const [pending, setPending] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [quota, setQuota] = useState<QuotaExceeded | null>(null);

  // Approche défauts (activeSite asynchrone) : `activeSite` peut être `undefined`
  // au premier render puis se peupler (résolu par SiteProvider). On (re)pose les
  // défauts langue/pays sur le site à chaque ouverture du dialog ET dès que le
  // site arrive — mais uniquement tant que l'utilisateur n'a pas touché aux
  // champs (touchedRef), pour ne jamais écraser un choix manuel. Le flag est
  // remis à zéro à la fermeture (reset()) ; défensivement on le remet aussi ici
  // si le parent force `open=false` sans passer par le callback onOpenChange, afin
  // que les défauts soient bien resynchronisés à la réouverture.
  const touchedRef = useRef(false);
  useEffect(() => {
    if (!open) {
      touchedRef.current = false;
      return;
    }
    if (!touchedRef.current) {
      setLang(activeSite?.primaryLanguage ?? "en");
      setCountry(activeSite?.targetCountries?.[0] ?? "");
    }
  }, [open, activeSite]);

  function reset() {
    setQuota(null);
    setTerm("");
    setLang(activeSite?.primaryLanguage ?? "en");
    setCountry(activeSite?.targetCountries?.[0] ?? "");
    touchedRef.current = false;
    setTheme(null);
    setIntent([]);
    setDestination("reservoir");
    setError(null);
    setPending(false);
  }

  function toggleIntent(i: SearchIntent) {
    setIntent((prev) =>
      prev.includes(i) ? prev.filter((x) => x !== i) : [...prev, i],
    );
  }

  async function submit() {
    setError(null);
    setQuota(null);
    setPending(true);
    try {
      const res = await addKeywordAction(siteId, {
        term,
        lang: lang.trim() || (activeSite?.primaryLanguage ?? "en"),
        country: country.trim() || (activeSite?.targetCountries?.[0] ?? "FR"),
        theme,
        intent,
        destination,
      });
      if (!res.ok) {
        if (res.quota) setQuota(res.quota);
        else setError(res.error);
        return;
      }
      onAdded();
      onOpenChange(false);
      reset();
    } finally {
      setPending(false);
    }
  }

  return (
    <Dialog
      open={open}
      onOpenChange={(o) => {
        if (!o) reset();
        onOpenChange(o);
      }}
    >
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>Ajouter un mot-clé</DialogTitle>
          <DialogDescription>
            Ajouté au réservoir du site actif (statut « idée », sans métriques).
          </DialogDescription>
        </DialogHeader>
        <div className="grid gap-3">
          <Input
            placeholder="Terme (ex. bagues or éthique)"
            aria-label="Terme"
            value={term}
            onChange={(e) => setTerm(e.target.value)}
          />
          <div className="flex flex-col gap-2 sm:flex-row">
            <div className="w-full min-w-0 sm:flex-1">
              <SingleCombobox
                options={langOptions}
                value={lang}
                onValueChange={(v) => {
                  touchedRef.current = true;
                  setLang(v);
                }}
                placeholder="Langue"
                ariaLabel="Langue"
              />
            </div>
            <div className="w-full min-w-0 sm:flex-1">
              <SingleCombobox
                options={countryOptions}
                value={country}
                onValueChange={(v) => {
                  touchedRef.current = true;
                  setCountry(v);
                }}
                placeholder="Pays"
                ariaLabel="Pays"
                withFlag
              />
            </div>
            <ThemeSelect
              value={theme}
              onChange={setTheme}
              className="w-full min-w-0 sm:flex-1"
            />
          </div>
          <fieldset className="grid gap-1.5 border-0 p-0">
            <legend className="text-xs font-medium">Intent</legend>
            <div className="flex flex-wrap gap-1">
              {INTENTS.map((i) => {
                const on = intent.includes(i);
                return (
                  <button
                    key={i}
                    type="button"
                    onClick={() => toggleIntent(i)}
                    aria-pressed={on}
                    className="rounded-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
                  >
                    <Pill accent={on ? "primary" : "neutral"}>
                      {INTENT_LABELS[i]}
                    </Pill>
                  </button>
                );
              })}
            </div>
          </fieldset>
          <div className="grid gap-1">
            <Label>Envoyer vers</Label>
            <div className="flex gap-1">
              <Button
                type="button"
                size="sm"
                variant={destination === "reservoir" ? "default" : "outline"}
                onClick={() => setDestination("reservoir")}
              >
                Réservoir
              </Button>
              <Button
                type="button"
                size="sm"
                variant={destination === "recherche" ? "default" : "outline"}
                onClick={() => setDestination("recherche")}
              >
                Recherche
              </Button>
            </div>
          </div>
          {quota ? <QuotaNotice quota={quota} /> : null}
          {error ? (
            <p className="text-destructive text-sm" role="alert">
              {error}
            </p>
          ) : null}
          <div className="flex justify-end">
            <Button onClick={submit} disabled={!term.trim() || pending}>
              {pending ? "Ajout…" : "Ajouter"}
            </Button>
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}
