"use client";

import {
  ArrowLeft,
  CheckCircle2,
  Download,
  Eye,
  FileDown,
  FileText,
  Printer,
  RefreshCw,
  Search,
} from "lucide-react";
import { useRouter } from "next/navigation";
import { useEffect, useMemo, useRef, useState } from "react";

import type { Salarie } from "@/types/type";

type Signataire = {
  id: number;
  prenomnom: string | null;
  fonction: string | null;
};

type DocumentData = Partial<Record<
  | "formuleSoussignataire"
  | "signataireNom"
  | "signataireFonction"
  | "titreNomPrenom"
  | "domicilie"
  | "adresseLigne"
  | "entreprise"
  | "typeContrat"
  | "dateEmbauche"
  | "dateFinContrat"
  | "poste"
  | "dateDocument"
  | "lieuDocument"
  | "dateSortiePrevue"
  | "dateRetraite"
  | "contratsTexte"
  | "dateEcheanceMutuelle"
  | "dateReprise"
  | "correspondantNom"
  | "correspondantFonction"
  | "adresseEntreprise"
  | "telephoneEntreprise"
  | "siret"
  | "urssaf"
  | "nomPrenom"
  | "adresseSalarie"
  | "dateNaissance"
  | "paysNaissance"
  | "nationalite"
  | "numeroSecuriteSociale"
  | "titreSejour"
  | "motifSejour"
  | "numeroCarteSejour"
  | "dateDelivrance"
  | "dateExpiration"
  | "dateDebutContrat"
  | "dureeContrat"
  | "heuresHebdomadaires",
  string
>> & { estToujoursDansEffectifs?: boolean };

type DocumentKind =
  | "attestation-impots"
  | "attestation-retraite"
  | "attestation-emploi"
  | "attestation-mutuelle"
  | "attestation-prolongation-mutuelle"
  | "autorisation-prefecture";

const DOCUMENTS: Record<
  DocumentKind,
  { label: string; description: string; filename: string }
> = {
  "attestation-impots": {
    label: "Attestation impôts",
    description: "Attestation d'emploi et de rémunération en nature",
    filename: "attestation-impots",
  },
  "attestation-retraite": {
    label: "Attestation retraite",
    description: "Attestation de départ à la retraite",
    filename: "attestation-retraite",
  },
  "attestation-emploi": {
    label: "Attestation d'emploi",
    description: "Historique des contrats du salarié",
    filename: "attestation-emploi",
  },
  "attestation-mutuelle": {
    label: "Attestation mutuelle",
    description: "Dérogation et adhésion à la mutuelle",
    filename: "attestation-mutuelle",
  },
  "attestation-prolongation-mutuelle": {
    label: "Prolongation mutuelle",
    description: "Demande de maintien jusqu'à la sortie définitive",
    filename: "attestation-prolongation-mutuelle",
  },
  "autorisation-prefecture": {
    label: "Autorisation préfecture",
    description: "Vérification du titre de séjour et du droit au travail",
    filename: "autorisation-prefecture",
  },
};

type ApiError = {
  message?: string;
  missingFields?: string[];
};

const COMMON_REQUIRED_FIELDS: Array<keyof DocumentData> = [
  "formuleSoussignataire",
  "signataireNom",
  "signataireFonction",
  "titreNomPrenom",
  "domicilie",
  "adresseLigne",
  "entreprise",
  "typeContrat",
  "dateEmbauche",
  "poste",
  "dateDocument",
  "lieuDocument",
];

function requiredFields(documentKind: DocumentKind) {
  switch (documentKind) {
    case "attestation-retraite":
      return [
        ...COMMON_REQUIRED_FIELDS,
        "dateSortiePrevue" as const,
        "dateRetraite" as const,
      ];
    case "attestation-emploi":
      return [
        "formuleSoussignataire",
        "signataireNom",
        "signataireFonction",
        "titreNomPrenom",
        "domicilie",
        "adresseLigne",
        "entreprise",
        "contratsTexte",
        "dateDocument",
        "lieuDocument",
      ] as Array<keyof DocumentData>;
    case "attestation-mutuelle":
      return COMMON_REQUIRED_FIELDS;
    case "attestation-prolongation-mutuelle":
      return [
        ...COMMON_REQUIRED_FIELDS.filter((field) => field !== "poste"),
        "dateSortiePrevue",
        "dateReprise",
      ] as Array<keyof DocumentData>;
    case "autorisation-prefecture":
      return [
        "correspondantNom",
        "correspondantFonction",
        "entreprise",
        "adresseEntreprise",
        "telephoneEntreprise",
        "siret",
        "urssaf",
        "nomPrenom",
        "adresseSalarie",
        "dateNaissance",
        "paysNaissance",
        "nationalite",
        "numeroSecuriteSociale",
        "titreSejour",
        "motifSejour",
        "numeroCarteSejour",
        "dateDelivrance",
        "dateExpiration",
        "dateDebutContrat",
        "dureeContrat",
        "typeContrat",
        "poste",
        "heuresHebdomadaires",
        "lieuDocument",
        "dateDocument",
      ] as Array<keyof DocumentData>;
    default:
      return COMMON_REQUIRED_FIELDS;
  }
}

const FIELD_LABELS: Partial<Record<keyof DocumentData, string>> = {
  formuleSoussignataire: "formule du signataire",
  signataireNom: "nom du signataire",
  signataireFonction: "fonction du signataire",
  titreNomPrenom: "identité du salarié",
  domicilie: "formule de domiciliation",
  adresseLigne: "adresse du salarié",
  entreprise: "entreprise",
  typeContrat: "type de contrat",
  dateEmbauche: "date d'embauche",
  poste: "poste",
  dateDocument: "date du document",
  lieuDocument: "lieu de signature",
  dateSortiePrevue: "date de sortie prévue",
  dateRetraite: "date de départ à la retraite",
  contratsTexte: "historique des contrats",
  dateReprise: "date de reprise",
  correspondantNom: "nom du correspondant",
  correspondantFonction: "fonction du correspondant",
  adresseEntreprise: "adresse de l'entreprise",
  telephoneEntreprise: "téléphone de l'entreprise",
  siret: "SIRET",
  urssaf: "numéro URSSAF",
  nomPrenom: "identité du salarié",
  adresseSalarie: "adresse du salarié",
  dateNaissance: "date de naissance",
  paysNaissance: "pays de naissance",
  nationalite: "nationalité",
  numeroSecuriteSociale: "numéro de sécurité sociale",
  titreSejour: "titre de séjour",
  motifSejour: "motif du séjour",
  numeroCarteSejour: "numéro de carte de séjour",
  dateDelivrance: "date de délivrance",
  dateExpiration: "date d'expiration",
  dateDebutContrat: "date de début du contrat",
  dureeContrat: "durée du contrat",
  heuresHebdomadaires: "heures hebdomadaires",
};

function salarieLabel(salarie: Salarie) {
  return (
    [salarie.NSA, salarie.PRE].filter(Boolean).join(" ") ||
    `COS ${salarie.COS}`
  );
}

function apiErrorMessage(status: number, error: ApiError | null) {
  if (status === 401) return "Votre session a expiré. Veuillez vous reconnecter.";
  if (status === 403) return "Vous n'avez pas accès aux impressions.";
  if (status === 404 && error?.message === "Employe not found") {
    return "Ce salarié est introuvable ou n'appartient pas à votre périmètre.";
  }
  if (
    status === 404 &&
    (error?.message === "Active signataire not found" ||
      error?.message === "SIGNATAIRE_NOT_FOUND")
  ) {
    return "Le signataire sélectionné n'est plus actif.";
  }
  if (status === 409 || error?.message === "CONTRACT_NOT_FOUND") {
    return "Aucun contrat n'a été trouvé pour ce salarié.";
  }
  if (status === 422) {
    return "Certains champs du document sont incomplets ou invalides.";
  }

  return "Une erreur est survenue pendant la préparation du document.";
}

function Field({
  label,
  value,
  onChange,
  type = "text",
  required = true,
}: {
  label: string;
  value: string;
  onChange: (value: string) => void;
  type?: "text" | "date";
  required?: boolean;
}) {
  return (
    <label className="block">
      <span className="mb-1 block text-xs font-semibold text-slate-600">
        {label}
        {required && <span className="ml-1 text-red-500">*</span>}
      </span>
      <input
        type={type}
        value={value}
        onChange={(event) => onChange(event.target.value)}
        className="w-full rounded-md border border-slate-300 bg-white px-3 py-2 text-sm outline-none transition focus:border-blue-500 focus:ring-2 focus:ring-blue-100"
      />
    </label>
  );
}

function TextAreaField({
  label,
  value,
  onChange,
}: {
  label: string;
  value: string;
  onChange: (value: string) => void;
}) {
  return (
    <label className="block">
      <span className="mb-1 block text-xs font-semibold text-slate-600">
        {label} <span className="text-red-500">*</span>
      </span>
      <textarea
        rows={5}
        value={value}
        onChange={(event) => onChange(event.target.value)}
        className="w-full resize-y rounded-md border border-slate-300 bg-white px-3 py-2 text-sm outline-none transition focus:border-blue-500 focus:ring-2 focus:ring-blue-100"
      />
    </label>
  );
}

export default function DocumentsAutomatiquesPage() {
  const router = useRouter();
  const previewUrlRef = useRef<string | null>(null);
  const previewFrameRef = useRef<HTMLIFrameElement | null>(null);
  const [salaries, setSalaries] = useState<Salarie[]>([]);
  const [signataires, setSignataires] = useState<Signataire[]>([]);
  const [selectedCos, setSelectedCos] = useState<number | null>(null);
  const [signataireId, setSignataireId] = useState<number | null>(null);
  const [selectedDocument, setSelectedDocument] =
    useState<DocumentKind>("attestation-impots");
  const [search, setSearch] = useState("");
  const [draft, setDraft] = useState<DocumentData | null>(null);
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
  const [previewBlob, setPreviewBlob] = useState<Blob | null>(null);
  const [loading, setLoading] = useState(true);
  const [loadingDraft, setLoadingDraft] = useState(false);
  const [loadingWord, setLoadingWord] = useState(false);
  const [updatingPreview, setUpdatingPreview] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);

  function replacePreview(blob: Blob | null) {
    if (previewUrlRef.current) URL.revokeObjectURL(previewUrlRef.current);

    const nextUrl = blob ? URL.createObjectURL(blob) : null;
    previewUrlRef.current = nextUrl;
    setPreviewUrl(nextUrl);
    setPreviewBlob(blob);
  }

  useEffect(() => {
    return () => {
      if (previewUrlRef.current) URL.revokeObjectURL(previewUrlRef.current);
    };
  }, []);

  useEffect(() => {
    let cancelled = false;

    async function loadPageData() {
      const token = localStorage.getItem("token");

      if (!token) {
        router.push("/login");
        return;
      }

      try {
        const [salariesResponse, signatairesResponse] = await Promise.all([
          fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/employes`, {
            headers: { Authorization: `Bearer ${token}` },
            cache: "no-store",
          }),
          fetch(
            `${process.env.NEXT_PUBLIC_API_URL}/api/impressions/signataires`,
            {
              headers: { Authorization: `Bearer ${token}` },
              cache: "no-store",
            },
          ),
        ]);

        if (
          salariesResponse.status === 401 ||
          signatairesResponse.status === 401
        ) {
          localStorage.removeItem("token");
          localStorage.removeItem("user");
          router.push("/login");
          return;
        }

        if (!salariesResponse.ok || !signatairesResponse.ok) {
          throw new Error(
            signatairesResponse.status === 403
              ? "Vous n'avez pas accès aux impressions."
              : "Impossible de charger les données nécessaires.",
          );
        }

        const salariesData = await salariesResponse.json();
        const signatairesData = await signatairesResponse.json();

        if (cancelled) return;

        const loadedSalaries: Salarie[] = Array.isArray(salariesData.items)
          ? salariesData.items
          : [];
        const loadedSignataires: Signataire[] = Array.isArray(
          signatairesData.items,
        )
          ? signatairesData.items
          : [];
        const requestedCos = Number(
          new URLSearchParams(window.location.search).get("cos"),
        );

        setSalaries(loadedSalaries);
        setSignataires(loadedSignataires);

        if (
          Number.isInteger(requestedCos) &&
          loadedSalaries.some((salarie) => salarie.COS === requestedCos)
        ) {
          setSelectedCos(requestedCos);
        }
        if (loadedSignataires.length === 1) {
          setSignataireId(loadedSignataires[0].id);
        }
      } catch (caughtError) {
        if (!cancelled) {
          setError(
            caughtError instanceof Error
              ? caughtError.message
              : "Une erreur inattendue est survenue.",
          );
        }
      } finally {
        if (!cancelled) setLoading(false);
      }
    }

    void loadPageData();

    return () => {
      cancelled = true;
    };
  }, [router]);

  useEffect(() => {
    if (selectedCos === null || signataireId === null) {
      return;
    }

    const controller = new AbortController();

    async function loadDraft() {
      const token = localStorage.getItem("token");
      if (!token) return;

      setLoadingDraft(true);
      setError(null);
      setSuccess(null);
      replacePreview(null);

      try {
        const params = new URLSearchParams({
          cos: String(selectedCos),
          signataireId: String(signataireId),
        });
        const response = await fetch(
          `${process.env.NEXT_PUBLIC_API_URL}/api/impressions/${selectedDocument}/draft?${params}`,
          {
            headers: { Authorization: `Bearer ${token}` },
            cache: "no-store",
            signal: controller.signal,
          },
        );

        if (!response.ok) {
          const responseError = (await response
            .json()
            .catch(() => null)) as ApiError | null;
          throw new Error(apiErrorMessage(response.status, responseError));
        }

        const payload = (await response.json()) as {
          data: DocumentData;
        };
        setDraft(payload.data);
      } catch (caughtError) {
        if (caughtError instanceof DOMException && caughtError.name === "AbortError") {
          return;
        }
        setDraft(null);
        setError(
          caughtError instanceof Error
            ? caughtError.message
            : "Impossible de préparer le document.",
        );
      } finally {
        if (!controller.signal.aborted) setLoadingDraft(false);
      }
    }

    void loadDraft();
    return () => controller.abort();
  }, [selectedCos, selectedDocument, signataireId]);

  const missingFields = useMemo(() => {
    if (!draft) return [];

    return requiredFields(selectedDocument).filter((field) => {
      const value = draft[field];
      return typeof value === "string" && value.trim().length === 0;
    });
  }, [draft, selectedDocument]);

  useEffect(() => {
    if (
      !draft ||
      selectedCos === null ||
      signataireId === null ||
      missingFields.length > 0
    ) {
      return;
    }

    const controller = new AbortController();
    const timeout = window.setTimeout(async () => {
      const token = localStorage.getItem("token");
      if (!token) return;

      setUpdatingPreview(true);

      try {
        const response = await fetch(
          `${process.env.NEXT_PUBLIC_API_URL}/api/impressions/${selectedDocument}/pdf`,
          {
            method: "POST",
            headers: {
              Authorization: `Bearer ${token}`,
              "Content-Type": "application/json",
            },
            body: JSON.stringify({
              cos: selectedCos,
              signataireId,
              data: draft,
            }),
            signal: controller.signal,
          },
        );

        if (!response.ok) {
          const responseError = (await response
            .json()
            .catch(() => null)) as ApiError | null;
          throw new Error(apiErrorMessage(response.status, responseError));
        }

        replacePreview(await response.blob());
        setError(null);
      } catch (caughtError) {
        if (caughtError instanceof DOMException && caughtError.name === "AbortError") {
          return;
        }
        replacePreview(null);
        setError(
          caughtError instanceof Error
            ? caughtError.message
            : "La prévisualisation a échoué.",
        );
      } finally {
        if (!controller.signal.aborted) setUpdatingPreview(false);
      }
    }, 450);

    return () => {
      window.clearTimeout(timeout);
      controller.abort();
    };
  }, [draft, missingFields.length, selectedCos, selectedDocument, signataireId]);

  const sortedSalaries = useMemo(
    () =>
      [...salaries].sort((left, right) =>
        salarieLabel(left).localeCompare(salarieLabel(right), "fr", {
          sensitivity: "base",
        }),
      ),
    [salaries],
  );

  const filteredSalaries = useMemo(() => {
    const normalizedSearch = search.trim().toLocaleLowerCase("fr");
    if (!normalizedSearch) return sortedSalaries;

    return sortedSalaries.filter((salarie) =>
      `${salarie.NSA ?? ""} ${salarie.PRE ?? ""} ${salarie.COS}`
        .toLocaleLowerCase("fr")
        .includes(normalizedSearch),
    );
  }, [sortedSalaries, search]);

  const selectedSalarie = salaries.find(
    (salarie) => salarie.COS === selectedCos,
  );

  function updateDraft<K extends keyof DocumentData>(
    field: K,
    value: DocumentData[K],
  ) {
    setDraft((current) => {
      if (!current) return current;

      const next = { ...current, [field]: value };
      const hasMissingField = requiredFields(selectedDocument).some((requiredField) => {
        const requiredValue = next[requiredField];
        return (
          typeof requiredValue === "string" &&
          requiredValue.trim().length === 0
        );
      });

      if (hasMissingField) {
        replacePreview(null);
        setUpdatingPreview(false);
      }

      return next;
    });
    setSuccess(null);
  }

  function downloadPdf() {
    if (!previewBlob || selectedCos === null) return;

    const url = URL.createObjectURL(previewBlob);
    const link = document.createElement("a");
    link.href = url;
    link.download = `${DOCUMENTS[selectedDocument].filename}-${selectedCos}.pdf`;
    document.body.appendChild(link);
    link.click();
    link.remove();
    URL.revokeObjectURL(url);
    setSuccess(
      `Le PDF de ${selectedSalarie ? salarieLabel(selectedSalarie) : `COS ${selectedCos}`} a été téléchargé.`,
    );
  }

  async function downloadWord() {
    if (
      !draft ||
      selectedCos === null ||
      signataireId === null ||
      missingFields.length > 0 ||
      loadingWord
    ) {
      return;
    }

    const token = localStorage.getItem("token");
    if (!token) {
      router.push("/login");
      return;
    }

    setLoadingWord(true);
    setError(null);
    setSuccess(null);

    try {
      const response = await fetch(
        `${process.env.NEXT_PUBLIC_API_URL}/api/impressions/${selectedDocument}/docx`,
        {
          method: "POST",
          headers: {
            Authorization: `Bearer ${token}`,
            "Content-Type": "application/json",
          },
          body: JSON.stringify({
            cos: selectedCos,
            signataireId,
            data: draft,
          }),
        },
      );

      if (!response.ok) {
        const responseError = (await response
          .json()
          .catch(() => null)) as ApiError | null;
        throw new Error(apiErrorMessage(response.status, responseError));
      }

      const blob = await response.blob();
      const url = URL.createObjectURL(blob);
      const link = document.createElement("a");
      link.href = url;
      link.download = `${DOCUMENTS[selectedDocument].filename}-${selectedCos}.docx`;
      document.body.appendChild(link);
      link.click();
      link.remove();
      URL.revokeObjectURL(url);
      setSuccess(
        `Le document Word de ${selectedSalarie ? salarieLabel(selectedSalarie) : `COS ${selectedCos}`} a été téléchargé.`,
      );
    } catch (caughtError) {
      setError(
        caughtError instanceof Error
          ? caughtError.message
          : "La génération du document Word a échoué.",
      );
    } finally {
      setLoadingWord(false);
    }
  }

  function printPdf() {
    if (!previewUrl || updatingPreview) return;

    const previewWindow = previewFrameRef.current?.contentWindow;
    if (!previewWindow) {
      setError(
        "Impossible d'ouvrir l'impression. Rechargez l'aperçu puis réessayez.",
      );
      return;
    }

    try {
      previewWindow.focus();
      previewWindow.print();
      setError(null);
      setSuccess("La fenêtre d'impression du PDF a été ouverte.");
    } catch {
      setError(
        "Le navigateur a bloqué l'impression intégrée. Autorisez les fenêtres d'impression puis réessayez.",
      );
    }
  }

  if (loading) {
    return (
      <main className="flex min-h-screen items-center justify-center bg-slate-100 text-slate-700">
        Chargement des documents automatiques...
      </main>
    );
  }

  return (
    <main className="min-h-screen bg-slate-100 p-4 text-slate-900 md:p-6">
      <div className="mx-auto max-w-[1500px]">
        <header className="mb-5 flex flex-wrap items-center justify-between gap-3">
          <div>
            <p className="text-sm font-semibold text-blue-600">Impressions</p>
            <h1 className="text-2xl font-bold">Documents automatiques</h1>
            <p className="mt-1 text-sm text-slate-600">
              Modifiez les valeurs, contrôlez l&apos;aperçu puis téléchargez le PDF.
            </p>
          </div>
          <button
            type="button"
            onClick={() => router.back()}
            className="inline-flex items-center gap-2 rounded-md border border-slate-300 bg-white px-4 py-2 font-semibold text-slate-700 shadow-sm hover:bg-slate-50"
          >
            <ArrowLeft size={18} />
            Retour
          </button>
        </header>

        {error && (
          <div className="mb-4 rounded-md border border-red-300 bg-red-50 px-4 py-3 text-sm text-red-700">
            {error}
          </div>
        )}
        {success && (
          <div className="mb-4 flex items-center gap-2 rounded-md border border-emerald-300 bg-emerald-50 px-4 py-3 text-sm text-emerald-700">
            <CheckCircle2 size={18} />
            {success}
          </div>
        )}

        <div className="grid items-start gap-5 xl:grid-cols-[420px_minmax(0,1fr)]">
          <div className="space-y-5">
            <section className="rounded-lg bg-white p-5 shadow">
              <h2 className="font-bold">1. Salarié</h2>
              <p className="mb-3 text-sm text-slate-500">
                {sortedSalaries.length} salarié(s) disponible(s)
              </p>
              <label className="relative mb-3 block">
                <Search
                  className="absolute left-3 top-1/2 -translate-y-1/2 text-slate-400"
                  size={18}
                />
                <input
                  type="search"
                  value={search}
                  onChange={(event) => setSearch(event.target.value)}
                  placeholder="Nom, prénom ou COS..."
                  className="w-full rounded-md border border-slate-300 py-2 pl-10 pr-3 text-sm outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-100"
                />
              </label>
              <div className="max-h-52 overflow-y-auto rounded-md border border-slate-200">
                {filteredSalaries.length === 0 ? (
                  <p className="p-4 text-center text-sm text-slate-500">
                    Aucun salarié trouvé.
                  </p>
                ) : (
                  filteredSalaries.map((salarie) => {
                    const selected = salarie.COS === selectedCos;
                    return (
                      <button
                        key={salarie.COS}
                        type="button"
                        onClick={() => {
                          setSelectedCos(salarie.COS);
                          setDraft(null);
                          setUpdatingPreview(false);
                          replacePreview(null);
                        }}
                        className={`flex w-full items-center justify-between border-b border-slate-100 px-3 py-2.5 text-left text-sm last:border-b-0 ${
                          selected
                            ? "bg-blue-600 text-white"
                            : "bg-white hover:bg-slate-50"
                        }`}
                      >
                        <span className="font-semibold">
                          {salarieLabel(salarie)}
                        </span>
                        <span
                          className={selected ? "text-blue-100" : "text-slate-400"}
                        >
                          {salarie.COS}
                        </span>
                      </button>
                    );
                  })
                )}
              </div>
            </section>

            <section className="rounded-lg bg-white p-5 shadow">
              <h2 className="mb-3 font-bold">2. Document et signataire</h2>
              <div className="mb-4 grid gap-2 sm:grid-cols-2 xl:grid-cols-1 2xl:grid-cols-2">
                {(Object.entries(DOCUMENTS) as Array<
                  [DocumentKind, (typeof DOCUMENTS)[DocumentKind]]
                >).map(([kind, document]) => {
                  const selected = kind === selectedDocument;

                  return (
                    <button
                      key={kind}
                      type="button"
                      onClick={() => {
                        setSelectedDocument(kind);
                        setDraft(null);
                        setUpdatingPreview(false);
                        replacePreview(null);
                      }}
                      className={`flex items-start gap-3 rounded-md border p-3 text-left transition ${
                        selected
                          ? "border-blue-500 bg-blue-50 ring-2 ring-blue-100"
                          : "border-slate-200 bg-white hover:border-blue-300 hover:bg-slate-50"
                      }`}
                    >
                      <FileText
                        className={selected ? "text-blue-600" : "text-slate-400"}
                        size={22}
                      />
                      <span>
                        <span className="block font-bold text-slate-900">
                          {document.label}
                        </span>
                        <span className="mt-0.5 block text-xs text-slate-500">
                          {document.description}
                        </span>
                      </span>
                    </button>
                  );
                })}
              </div>
              <label className="mb-1 block text-xs font-semibold text-slate-600">
                Signataire <span className="text-red-500">*</span>
              </label>
              <select
                value={signataireId ?? ""}
                onChange={(event) => {
                  setSignataireId(
                    event.target.value ? Number(event.target.value) : null,
                  );
                  setDraft(null);
                  setUpdatingPreview(false);
                  replacePreview(null);
                }}
                className="w-full rounded-md border border-slate-300 bg-white px-3 py-2 text-sm outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-100"
              >
                <option value="">Choisir un signataire</option>
                {signataires.map((signataire) => (
                  <option key={signataire.id} value={signataire.id}>
                    {[signataire.prenomnom, signataire.fonction]
                      .filter(Boolean)
                      .join(" - ")}
                  </option>
                ))}
              </select>
              {signataires.length === 0 && (
                <p className="mt-3 rounded-md border border-amber-300 bg-amber-50 p-3 text-sm text-amber-800">
                  Aucun signataire actif n&apos;est configuré.
                </p>
              )}
            </section>

            <section className="rounded-lg bg-white p-5 shadow">
              <div className="mb-4 flex items-center justify-between gap-3">
                <div>
                  <h2 className="font-bold">3. Valeurs du document</h2>
                  <p className="text-xs text-slate-500">
                    Ces changements ne modifient pas la fiche salarié.
                  </p>
                </div>
                {loadingDraft && (
                  <RefreshCw className="animate-spin text-blue-600" size={19} />
                )}
              </div>

              {!draft ? (
                <div className="rounded-md border border-dashed border-slate-300 p-5 text-center text-sm text-slate-500">
                  Sélectionnez un salarié et un signataire pour charger le formulaire.
                </div>
              ) : (
                <div className="space-y-5">
                  {selectedDocument === "autorisation-prefecture" ? (
                    <>
                      <p className="border-b pb-1 text-sm font-bold text-slate-700">Société</p>
                      <Field label="Entreprise" value={draft.entreprise ?? ""} onChange={(value) => updateDraft("entreprise", value)} />
                      <Field label="Adresse de l'entreprise" value={draft.adresseEntreprise ?? ""} onChange={(value) => updateDraft("adresseEntreprise", value)} />
                      <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-1 2xl:grid-cols-2">
                        <Field label="Téléphone" value={draft.telephoneEntreprise ?? ""} onChange={(value) => updateDraft("telephoneEntreprise", value)} />
                        <Field label="SIRET" value={draft.siret ?? ""} onChange={(value) => updateDraft("siret", value)} />
                        <Field label="N° URSSAF" value={draft.urssaf ?? ""} onChange={(value) => updateDraft("urssaf", value)} />
                      </div>
                      <p className="border-b pb-1 text-sm font-bold text-slate-700">Salarié et titre de séjour</p>
                      <Field label="Nom et prénom" value={draft.nomPrenom ?? ""} onChange={(value) => updateDraft("nomPrenom", value)} />
                      <Field label="Adresse du salarié" value={draft.adresseSalarie ?? ""} onChange={(value) => updateDraft("adresseSalarie", value)} />
                      <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-1 2xl:grid-cols-2">
                        <Field label="Date de naissance" type="date" value={draft.dateNaissance ?? ""} onChange={(value) => updateDraft("dateNaissance", value)} />
                        <Field label="Pays de naissance" value={draft.paysNaissance ?? ""} onChange={(value) => updateDraft("paysNaissance", value)} />
                        <Field label="Nationalité" value={draft.nationalite ?? ""} onChange={(value) => updateDraft("nationalite", value)} />
                        <Field label="N° Sécurité sociale" value={draft.numeroSecuriteSociale ?? ""} onChange={(value) => updateDraft("numeroSecuriteSociale", value)} />
                        <Field label="Titre de séjour" value={draft.titreSejour ?? ""} onChange={(value) => updateDraft("titreSejour", value)} />
                        <Field label="Motif du séjour" value={draft.motifSejour ?? ""} onChange={(value) => updateDraft("motifSejour", value)} />
                        <Field label="N° carte de séjour" value={draft.numeroCarteSejour ?? ""} onChange={(value) => updateDraft("numeroCarteSejour", value)} />
                        <Field label="Délivrée le" type="date" value={draft.dateDelivrance ?? ""} onChange={(value) => updateDraft("dateDelivrance", value)} />
                        <Field label="Expire le" type="date" value={draft.dateExpiration ?? ""} onChange={(value) => updateDraft("dateExpiration", value)} />
                      </div>
                      <p className="border-b pb-1 text-sm font-bold text-slate-700">Contrat de travail</p>
                      <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-1 2xl:grid-cols-2">
                        <Field label="Début du contrat" type="date" value={draft.dateDebutContrat ?? ""} onChange={(value) => updateDraft("dateDebutContrat", value)} />
                        <Field label="Durée du contrat" value={draft.dureeContrat ?? ""} onChange={(value) => updateDraft("dureeContrat", value)} />
                        <Field label="Type de contrat" value={draft.typeContrat ?? ""} onChange={(value) => updateDraft("typeContrat", value)} />
                        <Field label="Fonction" value={draft.poste ?? ""} onChange={(value) => updateDraft("poste", value)} />
                        <Field label="Heures hebdomadaires" value={draft.heuresHebdomadaires ?? ""} onChange={(value) => updateDraft("heuresHebdomadaires", value)} />
                      </div>
                      <p className="border-b pb-1 text-sm font-bold text-slate-700">Correspondant et signature</p>
                      <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-1 2xl:grid-cols-2">
                        <Field label="Nom du correspondant" value={draft.correspondantNom ?? ""} onChange={(value) => updateDraft("correspondantNom", value)} />
                        <Field label="Fonction du correspondant" value={draft.correspondantFonction ?? ""} onChange={(value) => updateDraft("correspondantFonction", value)} />
                        <Field label="Lieu" value={draft.lieuDocument ?? ""} onChange={(value) => updateDraft("lieuDocument", value)} />
                        <Field label="Date du document" type="date" value={draft.dateDocument ?? ""} onChange={(value) => updateDraft("dateDocument", value)} />
                      </div>
                    </>
                  ) : (
                    <>
                      <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-1 2xl:grid-cols-2">
                        <Field label="Identité du salarié" value={draft.titreNomPrenom ?? ""} onChange={(value) => updateDraft("titreNomPrenom", value)} />
                        <Field label="Formule de domiciliation" value={draft.domicilie ?? ""} onChange={(value) => updateDraft("domicilie", value)} />
                      </div>
                      <Field label="Adresse" value={draft.adresseLigne ?? ""} onChange={(value) => updateDraft("adresseLigne", value)} />
                      <Field label="Entreprise" value={draft.entreprise ?? ""} onChange={(value) => updateDraft("entreprise", value)} />

                      {selectedDocument === "attestation-emploi" ? (
                        <TextAreaField label="Historique des contrats (une ligne par contrat)" value={draft.contratsTexte ?? ""} onChange={(value) => updateDraft("contratsTexte", value)} />
                      ) : (
                        <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-1 2xl:grid-cols-2">
                          <Field label="Type de contrat" value={draft.typeContrat ?? ""} onChange={(value) => updateDraft("typeContrat", value)} />
                          {selectedDocument !== "attestation-prolongation-mutuelle" && (
                            <Field label="Poste" value={draft.poste ?? ""} onChange={(value) => updateDraft("poste", value)} />
                          )}
                          <Field label="Date d'embauche" type="date" value={draft.dateEmbauche ?? ""} onChange={(value) => updateDraft("dateEmbauche", value)} />
                          {(selectedDocument === "attestation-impots" || selectedDocument === "attestation-mutuelle") && (
                            <Field label="Date de fin" type="date" required={false} value={draft.dateFinContrat ?? ""} onChange={(value) => updateDraft("dateFinContrat", value)} />
                          )}
                          {selectedDocument === "attestation-retraite" && (
                            <>
                              <Field label="Date de sortie prévue" type="date" value={draft.dateSortiePrevue ?? ""} onChange={(value) => updateDraft("dateSortiePrevue", value)} />
                              <Field label="Date de départ à la retraite" type="date" value={draft.dateRetraite ?? ""} onChange={(value) => updateDraft("dateRetraite", value)} />
                            </>
                          )}
                          {selectedDocument === "attestation-mutuelle" && (
                            <Field label="Échéance de la mutuelle personnelle" type="date" required={false} value={draft.dateEcheanceMutuelle ?? ""} onChange={(value) => updateDraft("dateEcheanceMutuelle", value)} />
                          )}
                          {selectedDocument === "attestation-prolongation-mutuelle" && (
                            <>
                              <Field label="Date de sortie prévue" type="date" value={draft.dateSortiePrevue ?? ""} onChange={(value) => updateDraft("dateSortiePrevue", value)} />
                              <Field label="Date de reprise" type="date" value={draft.dateReprise ?? ""} onChange={(value) => updateDraft("dateReprise", value)} />
                            </>
                          )}
                        </div>
                      )}

                      {(selectedDocument === "attestation-impots" || selectedDocument === "attestation-mutuelle") && (
                        <label className="flex items-start gap-3 rounded-md border border-slate-200 bg-slate-50 p-3 text-sm">
                          <input type="checkbox" checked={draft.estToujoursDansEffectifs ?? false} onChange={(event) => updateDraft("estToujoursDansEffectifs", event.target.checked)} className="mt-0.5 h-4 w-4 rounded border-slate-300" />
                          <span><strong>Toujours dans les effectifs</strong><span className="mt-0.5 block text-xs text-slate-500">Adapte automatiquement la phrase du document.</span></span>
                        </label>
                      )}

                      <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-1 2xl:grid-cols-2">
                        <Field label="Formule du signataire" value={draft.formuleSoussignataire ?? ""} onChange={(value) => updateDraft("formuleSoussignataire", value)} />
                        <Field label="Nom du signataire" value={draft.signataireNom ?? ""} onChange={(value) => updateDraft("signataireNom", value)} />
                      </div>
                      <Field label="Fonction du signataire" value={draft.signataireFonction ?? ""} onChange={(value) => updateDraft("signataireFonction", value)} />
                      <div className="grid gap-3 sm:grid-cols-2 xl:grid-cols-1 2xl:grid-cols-2">
                        <Field label="Lieu de signature" value={draft.lieuDocument ?? ""} onChange={(value) => updateDraft("lieuDocument", value)} />
                        <Field label="Date du document" type="date" value={draft.dateDocument ?? ""} onChange={(value) => updateDraft("dateDocument", value)} />
                      </div>
                    </>
                  )}
                </div>
              )}
            </section>
          </div>

          <section className="sticky top-5 rounded-lg bg-slate-800 p-4 shadow-xl">
            <div className="mb-3 flex flex-wrap items-center justify-between gap-3 text-white">
              <div className="flex items-center gap-2">
                <Eye size={19} />
                <div>
                  <h2 className="font-bold">Aperçu PDF</h2>
                  <p className="text-xs text-slate-300">
                    L&apos;aperçu correspond exactement au fichier téléchargé.
                  </p>
                </div>
              </div>
              <div className="flex flex-wrap gap-2">
                <button
                  type="button"
                  onClick={downloadPdf}
                  disabled={!previewBlob || updatingPreview}
                  className="inline-flex items-center gap-2 rounded-md bg-blue-600 px-4 py-2 text-sm font-semibold text-white hover:bg-blue-500 disabled:cursor-not-allowed disabled:bg-slate-600"
                >
                  <Download size={17} />
                  Télécharger le PDF
                </button>
                <button
                  type="button"
                  onClick={() => void downloadWord()}
                  disabled={
                    !draft ||
                    selectedCos === null ||
                    signataireId === null ||
                    missingFields.length > 0 ||
                    loadingWord
                  }
                  className="inline-flex items-center gap-2 rounded-md bg-indigo-600 px-4 py-2 text-sm font-semibold text-white hover:bg-indigo-500 disabled:cursor-not-allowed disabled:bg-slate-600"
                >
                  {loadingWord ? (
                    <RefreshCw className="animate-spin" size={17} />
                  ) : (
                    <FileDown size={17} />
                  )}
                  {loadingWord ? "Préparation..." : "Télécharger le Word"}
                </button>
                <button
                  type="button"
                  onClick={printPdf}
                  disabled={!previewUrl || updatingPreview}
                  className="inline-flex items-center gap-2 rounded-md bg-emerald-600 px-4 py-2 text-sm font-semibold text-white hover:bg-emerald-500 disabled:cursor-not-allowed disabled:bg-slate-600"
                >
                  <Printer size={17} />
                  Imprimer
                </button>
              </div>
            </div>

            <div className="relative mx-auto aspect-[210/297] w-full max-w-[850px] overflow-hidden rounded-sm bg-white shadow-2xl">
              {previewUrl ? (
                <iframe
                  ref={previewFrameRef}
                  title={`Aperçu de ${DOCUMENTS[selectedDocument].label.toLocaleLowerCase("fr")}`}
                  src={`${previewUrl}#toolbar=0&navpanes=0&scrollbar=0&view=FitH`}
                  className="h-full w-full border-0"
                />
              ) : (
                <div className="flex h-full items-center justify-center p-8 text-center text-slate-500">
                  <div>
                    {updatingPreview ? (
                      <RefreshCw
                        className="mx-auto mb-3 animate-spin text-blue-600"
                        size={34}
                      />
                    ) : (
                      <FileText
                        className="mx-auto mb-3 text-slate-300"
                        size={48}
                      />
                    )}
                    <p className="font-semibold text-slate-700">
                      {updatingPreview
                        ? "Mise à jour de l'aperçu..."
                        : "L'aperçu apparaîtra ici"}
                    </p>
                    {missingFields.length > 0 && (
                      <p className="mt-2 max-w-md text-sm">
                        Complétez :{" "}
                        {missingFields
                          .map((field) => FIELD_LABELS[field] ?? field)
                          .join(", ")}
                        .
                      </p>
                    )}
                  </div>
                </div>
              )}
              {previewUrl && updatingPreview && (
                <div className="absolute right-3 top-3 flex items-center gap-2 rounded-full bg-slate-900/80 px-3 py-1.5 text-xs font-semibold text-white shadow">
                  <RefreshCw className="animate-spin" size={14} />
                  Actualisation
                </div>
              )}
            </div>
          </section>
        </div>
      </div>
    </main>
  );
}
