// src/components/site/site-form.tsx
"use client";

import { useState } from "react";
import { MultiCombobox } from "@/components/site/multi-combobox";
import { SingleCombobox } from "@/components/site/single-combobox";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { COUNTRY_OPTIONS, LANGUAGE_OPTIONS } from "@/lib/sites/options";
import type { SiteInput } from "@/lib/sites/schema";
import { cleanDomain, SCHEMES } from "@/lib/sites/url";

export interface SiteFormValues {
  name: string;
  scheme: string;
  domain: string;
  primaryLanguage: string;
  languages: string[];
  targetCountries: string[];
}

const EMPTY: SiteFormValues = {
  name: "",
  scheme: SCHEMES[0],
  domain: "",
  primaryLanguage: "fr",
  languages: [],
  targetCountries: [],
};

function Field({
  label,
  children,
}: {
  label: string;
  children: React.ReactNode;
}) {
  return (
    // biome-ignore lint/a11y/noLabelWithoutControl: children always contain the input
    <label className="grid gap-1.5">
      <span className="font-medium text-sm">{label}</span>
      {children}
    </label>
  );
}

export function SiteForm({
  defaultValues,
  submitLabel,
  pending,
  error,
  requireCountry = false,
  onSubmit,
}: {
  defaultValues?: Partial<SiteFormValues>;
  submitLabel: string;
  pending: boolean;
  error: string | null;
  /**
   * Interdit la soumission tant qu'aucun pays cible n'est choisi.
   *
   * Le pays conditionne silencieusement deux fonctions : les mots-clés associés
   * (`getRelatedKeywords` échoue en `no_location` sans lui) et la ventilation
   * par pays de la synchro Search Console. Les DEUX surfaces de création
   * l'exigent donc — l'étape 1 du wizard et `AddSiteDialog` — sans quoi un site
   * créé par l'une contourne la règle de l'autre et bloque `target-country`,
   * étape requise, sans jamais en dire la cause. Seule l'ÉDITION d'un projet
   * existant reste tolérante : imposer la règle rétroactivement rendrait
   * inenregistrables les sites créés avant elle.
   */
  requireCountry?: boolean;
  onSubmit: (input: SiteInput) => void;
}) {
  const init = { ...EMPTY, ...defaultValues };
  const [name, setName] = useState(init.name);
  const [scheme, setScheme] = useState(init.scheme);
  const [domain, setDomain] = useState(init.domain);
  const [primaryLanguage, setPrimaryLanguage] = useState(init.primaryLanguage);
  const [languages, setLanguages] = useState<string[]>(init.languages);
  const [countries, setCountries] = useState<string[]>(init.targetCountries);

  const countryMissing = requireCountry && countries.length === 0;
  // Une seule expression pour les DEUX chemins de soumission : le bouton et la
  // touche Entrée du champ Nom, qui appelle submit() directement et
  // contournerait un bouton désactivé. Les dissocier avait déjà laissé passer
  // un `url: "https://"` (domaine vide) jusqu'à Zod.
  const cannotSubmit =
    !name.trim() || !cleanDomain(domain) || countryMissing || pending;

  function submit() {
    if (cannotSubmit) return;
    onSubmit({
      name,
      url: `${scheme}${cleanDomain(domain)}`,
      primaryLanguage,
      languages,
      targetCountries: countries,
    });
  }

  return (
    <div className="grid gap-4">
      <Field label="Nom">
        <Input
          value={name}
          onChange={(e) => setName(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === "Enter") {
              e.preventDefault();
              submit();
            }
          }}
          placeholder="Atelier Forge"
          aria-label="Nom du site"
        />
      </Field>

      <Field label="Domaine">
        <div className="flex items-center gap-2">
          <Select value={scheme} onValueChange={setScheme}>
            <SelectTrigger className="w-36 shrink-0" aria-label="Schéma">
              <SelectValue />
            </SelectTrigger>
            <SelectContent>
              {SCHEMES.map((s) => (
                <SelectItem key={s} value={s}>
                  {s}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Input
            value={domain}
            onChange={(e) => setDomain(e.target.value)}
            placeholder="atelierforge.com"
            aria-label="Domaine"
            className="flex-1"
          />
        </div>
      </Field>

      <Field label="Langue principale">
        <SingleCombobox
          options={LANGUAGE_OPTIONS}
          value={primaryLanguage}
          onValueChange={(next) => {
            setPrimaryLanguage(next);
            setLanguages((prev) => prev.filter((l) => l !== next));
          }}
          ariaLabel="Langue principale"
          placeholder="Rechercher une langue…"
        />
      </Field>

      <Field label="Langues additionnelles (i18n)">
        <MultiCombobox
          options={LANGUAGE_OPTIONS.filter((l) => l.value !== primaryLanguage)}
          value={languages}
          onValueChange={setLanguages}
          placeholder="Ajouter une langue…"
        />
      </Field>

      <Field label={requireCountry ? "Pays cible (obligatoire)" : "Pays cible"}>
        <MultiCombobox
          options={COUNTRY_OPTIONS}
          value={countries}
          onValueChange={setCountries}
          placeholder="Ajouter un pays…"
          withFlag
        />
      </Field>

      {error ? (
        <p className="text-destructive text-sm" role="alert">
          {error}
        </p>
      ) : null}

      <div className="flex justify-end">
        <Button onClick={submit} disabled={cannotSubmit}>
          {pending ? "Enregistrement…" : submitLabel}
        </Button>
      </div>
    </div>
  );
}
