"use client";

import { useState, useMemo, useEffect, useRef, useCallback } from "react";
import { useRouter } from "next/navigation";
import { useQuery } from "@tanstack/react-query";
import { api } from "@/lib/fetcher";
import { Loader2, Search, Upload, Info } from "lucide-react";
import { NotesSection } from "@/components/NotesSection";
import { PROFESSIONS_ARTISTE } from "@/components/constants/ProfessionsArtiste";

/* =========================
   Types
   ========================= */
type SalarieOption = { matricule: string; nom: string; email?: string | null };
type SpectacleOption = { id?: string; nom: string; numero_objet?: string | null };
type ProfessionOption = { code: string; label: string };
type TechnicienOption = ProfessionOption;
type ClientInfo = { id: string; name: string; api_name?: string } | null;

// Préremplissage pour le mode édition + override d'envoi
type NouveauCDDUPrefill = {
  spectacle?: string;
  numero_objet?: string | null;
  salarie?: { matricule: string; nom: string; email?: string | null } | null;
  categorie?: "Artiste" | "Technicien" | "Autre";
  profession?: { code?: string; label?: string } | null;
  date_debut?: string;   // YYYY-MM-DD
  date_fin?: string;     // YYYY-MM-DD
  nb_representations?: number | "";
  nb_services_repetition?: number | "";
  dates_representations?: string;
  dates_repetitions?: string;
  heures_total?: number | "";
  minutes_total?: "0" | "30";
  jours_travail?: string;
  type_salaire?: "Brut" | "Net avant PAS" | "Coût total employeur" | "Minimum conventionnel";
  montant?: number | "";
  panier_repas?: "Oui" | "Non";
  notes?: string;
  reference?: string;
  multi_mois?: boolean;
  nb_heures_annexes?: number | string;
};

/* =========================
   Constantes & helpers
   ========================= */
const NEW_SALARIE_PATH =
  process.env.NEXT_PUBLIC_NEW_SALARIE_PATH || "/salaries/nouveau?embed=1";

const EURO = new Intl.NumberFormat("fr-FR", { style: "currency", currency: "EUR" });

function todayYmd() {
  const d = new Date();
  const tzOff = d.getTimezoneOffset();
  const local = new Date(d.getTime() - tzOff * 60000);
  return local.toISOString().slice(0, 10); // YYYY-MM-DD
}

function formatFr(d: string) {
  const [y, m, day] = d.split("-");
  return `${day}/${m}/${y}`;
}

function generateReference() {
  const letters = "ABCDEFGHIKLMNPQRSTUVWXYZ"; // sans O
  const digits = "123456789";               // sans 0
  const pool = letters + digits;
  const pick = (s: string) => s[Math.floor(Math.random() * s.length)];
  while (true) {
    let ref = "";
    for (let i = 0; i < 8; i++) ref += pick(pool);
    if (ref.startsWith("RG")) continue;     // ne pas commencer par RG
    if (!/[A-Z]/.test(ref)) continue;       // au moins une lettre
    if (!/[1-9]/.test(ref)) continue;       // au moins un chiffre
    return ref;
  }
}

// Helper: parse base64-encoded JSON safely
function parseBase64Json<T = any>(b64: string | null): T | null {
  if (!b64) return null;
  try {
    const json = atob(b64);
    return JSON.parse(json) as T;
  } catch {
    return null;
  }
}

function norm(s: string){
  return s
    .toLowerCase()
    .normalize('NFD')
    .replace(/\p{Diacritic}/gu, '')
    .replace(/[^a-z0-9\s]/g, ' ')
    .replace(/\s+/g, ' ')
    .trim();
}

// Petit hook local de debounce (réutilisable)
function useDebouncedValue<T>(value: T, delay = 300) {
  const [debounced, setDebounced] = useState<T>(value);
  useEffect(() => {
    const id = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(id);
  }, [value, delay]);
  return debounced;
}

/* =========================
   Hook: blocage navigation si brouillon
   ========================= */
function useUnsavedChangesPrompt(enabled: boolean) {
  const allowNavRef = useRef(false);
  const pendingHrefRef = useRef<string | null>(null);
  const [open, setOpen] = useState(false);
  const [, forceRender] = useState(0);

  useEffect(() => {
    function onBeforeUnload(e: BeforeUnloadEvent) {
      if (!enabled || allowNavRef.current) return;
      e.preventDefault();
      e.returnValue = ""; // Chrome a besoin d'une valeur
    }
    if (enabled) window.addEventListener("beforeunload", onBeforeUnload);
    return () => window.removeEventListener("beforeunload", onBeforeUnload);
  }, [enabled]);

  useEffect(() => {
    function onDocClick(ev: MouseEvent) {
      if (!enabled || allowNavRef.current) return;
      const target = ev.target as HTMLElement | null;
      if (!target) return;
      const a = target.closest?.("a[href]") as HTMLAnchorElement | null;
      if (!a) return;
      const url = new URL(a.href, window.location.href);
      const sameOrigin = url.origin === window.location.origin;
      if (!sameOrigin) return; // laisser sortir du site sans bloquer
      if (url.pathname === window.location.pathname && url.hash) return; // autoriser ancres
      ev.preventDefault();
      pendingHrefRef.current = url.toString();
      setOpen(true);
    }
    document.addEventListener("click", onDocClick, true);
    return () => document.removeEventListener("click", onDocClick, true);
  }, [enabled]);

  useEffect(() => {
    if (!enabled) return;
    history.pushState({ _block: true }, "");
    function onPopState(ev: PopStateEvent) {
      if (allowNavRef.current || !enabled) return;
      ev.preventDefault?.();
      history.pushState({ _block: true }, "");
      setOpen(true);
    }
    window.addEventListener("popstate", onPopState);
    return () => window.removeEventListener("popstate", onPopState);
  }, [enabled]);

  const confirmLeave = useCallback(() => {
    allowNavRef.current = true;
    const href = pendingHrefRef.current;
    setOpen(false);
    if (href) { window.location.assign(href); } else { history.back(); }
  }, []);

  const cancelLeave = useCallback(() => {
    pendingHrefRef.current = null;
    setOpen(false);
    forceRender((n) => n + 1);
  }, []);

  return { open, confirmLeave, cancelLeave, allowNavRef };
}

/* =========================
   UI atoms
   ========================= */
function Section({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <section className="rounded-2xl border bg-white">
      <div className="px-4 py-3 border-b font-medium text-slate-700 bg-slate-50/60">
        {title}
      </div>
      <div className="p-4 space-y-4">{children}</div>
    </section>
  );
}
function Label({ children, required = false }: { children: React.ReactNode; required?: boolean }) {
  return (
    <label className="text-xs text-slate-600 block">
      {children} {required && <span className="text-rose-600">*</span>}
    </label>
  );
}
function FieldRow({ children }: { children: React.ReactNode }) {
  return <div className="grid grid-cols-1 md:grid-cols-2 gap-4">{children}</div>;
}

/* =========================
   API searches
   ========================= */
function useSearchSalaries(q: string, orgId?: string | null) {
  const { data: clientInfo } = useQuery({
    queryKey: ["client-info"],
    queryFn: async () => {
      try {
        const res = await fetch("/api/me", { cache: "no-store", headers: { Accept: "application/json" }, credentials: "include" });
        if (!res.ok) return null;
        const me = await res.json();
  return { id: me.active_org_id || null, name: me.active_org_name || "Organisation", api_name: me.active_org_api_name } as ClientInfo;
      } catch { return null; }
    },
    staleTime: 30_000,
  });

  const params = new URLSearchParams();
  params.set("page", "1");
  params.set("limit", "10");
  if (q.trim()) params.set("q", q.trim());
  // Utiliser l'org_id fourni ou celui du clientInfo
  if (orgId) params.set("org_id", orgId);

  return useQuery({
    queryKey: ["search-salaries", q, orgId || clientInfo?.id],
    queryFn: () =>
      api<{ items: SalarieOption[] }>(`/salaries?${params.toString()}`, {}, clientInfo).then((r) => ({
        items: r.items?.map((s) => ({ matricule: s.matricule, nom: s.nom, email: s.email ?? undefined })) ?? [],
      })),
    enabled: q.trim().length > 1 && (!!orgId || !!clientInfo),
    staleTime: 10_000,
  });
}

function useSearchSpectacles(q: string, orgId?: string | null) {
  const { data: clientInfo } = useQuery({
    queryKey: ["client-info"],
    queryFn: async () => {
      try {
        const res = await fetch("/api/me", { cache: "no-store", headers: { Accept: "application/json" }, credentials: "include" });
        if (!res.ok) return null;
        const me = await res.json();
  return { id: me.active_org_id || null, name: me.active_org_name || "Organisation", api_name: me.active_org_api_name } as ClientInfo;
      } catch { return null; }
    },
    staleTime: 30_000,
  });

  const params = new URLSearchParams();
  params.set("page", "1");
  params.set("limit", "10");
  if (q.trim()) params.set("q", q.trim());
  // Utiliser l'org_id fourni ou celui du clientInfo
  if (orgId) params.set("org_id", orgId);

  return useQuery({
    queryKey: ["search-spectacles", q, orgId || clientInfo?.id],
    queryFn: () =>
      api<{ items: SpectacleOption[] }>(`/spectacles?${params.toString()}`, {}, clientInfo).then((r) => ({
        items:
          r.items?.map((s) => ({
            id: (s as any).id || null,
            nom: (s as any).nom || (s as any).Spectacle || (s as any).titre || "",
            numero_objet: (s as any).numero_objet || (s as any)["n° d'objet"] || (s as any).numero || null,
          })) ?? [],
      })),
    enabled: q.trim().length > 1 && !!clientInfo,
    staleTime: 10_000,
  });
}

/* =========================
   Formulaire principal
   ========================= */
export function NouveauCDDUForm({
  prefill,
  onSubmitOverride,
  contractIdForNotes,
}: {
  prefill?: NouveauCDDUPrefill;
  onSubmitOverride?: (payload: {
    regime: "CDDU_MONO" | "CDDU_MULTI";
    multi_mois: boolean;
    spectacle: string;
    numero_objet?: string | null;
    salarie: { matricule: string; nom: string; email?: string | null };
    categorie_professionnelle: "Artiste" | "Technicien" | "Autre";
    profession: string;
    profession_code?: string;
    date_debut: string;
    date_fin?: string;
    nb_representations?: number | "";
    nb_services_repetition?: number | "";
    dates_representations?: string;
    dates_repetitions?: string;
    heures_travail?: number | "";
    minutes_travail?: "0" | "30";
    jours_travail?: string;
    type_salaire: "Brut" | "Net avant PAS" | "Coût total employeur" | "Minimum conventionnel";
    montant?: number | "";
    panier_repas: "Oui" | "Non";
    reference: string;
    notes?: string;
    valider_direct: boolean;
  }) => Promise<void>;
  contractIdForNotes?: string;
}) {
  const router = useRouter();

  // --- form state
  const [reference, setReference] = useState<string>("");
  const [spectacle, setSpectacle] = useState("");
  const [objet, setObjet] = useState("");
  const [spectacleQuery, setSpectacleQuery] = useState("");
  const [spectaclePick, setSpectaclePick] = useState<SpectacleOption | null>(null);
  const [spectacleManual, setSpectacleManual] = useState(false);
  const spectacleInputRef = useRef<HTMLInputElement | null>(null);
  const [salarieQuery, setSalarieQuery] = useState("");
  const [salarie, setSalarie] = useState<SalarieOption | null>(null);
  // L'utilisateur a explicitement cliqué sur "Changer" (ne plus forcer le salarie depuis l'URL)
  const [urlSalarieDismissed, setUrlSalarieDismissed] = useState(false);
  const [categoriePro, setCategoriePro] = useState<"Artiste" | "Technicien" | "Autre" | "Cadre" | "Non Cadre" | "Je ne sais pas">("Artiste");
  const [profession, setProfession] = useState("");
  const [professionQuery, setProfessionQuery] = useState("");
  const [professionPick, setProfessionPick] = useState<ProfessionOption | null>(null);
  // Index actif (navigation clavier) pour les listes de résultats
  const [spectacleActive, setSpectacleActive] = useState(0);
  const [salarieActive, setSalarieActive] = useState(0);
  const [professionActive, setProfessionActive] = useState(0);
  const [techniciens, setTechniciens] = useState<TechnicienOption[] | null>(null);
  const [techLoading, setTechLoading] = useState(false);
  const techLoadedRef = useRef(false);
  const [isMultiMois, setIsMultiMois] = useState<"Oui" | "Non">("Non");
  const [dateDebut, setDateDebut] = useState("");
  const [dateFin, setDateFin] = useState("");
  const [confirmPastStart, setConfirmPastStart] = useState(false);
  const [heuresTotal, setHeuresTotal] = useState<number | "">("");
  const [minutesTotal, setMinutesTotal] = useState<"0" | "30">("0");
  const [joursTravail, setJoursTravail] = useState("");
  const [nbRep, setNbRep] = useState<number | "">("");
  const [nbServ, setNbServ] = useState<number | "">("");
  const [datesRep, setDatesRep] = useState("");
  const [datesServ, setDatesServ] = useState("");
  const [typeSalaire, setTypeSalaire] = useState<"Brut" | "Net avant PAS" | "Coût total employeur" | "Minimum conventionnel">("Brut");
  const [montantSalaire, setMontantSalaire] = useState<number | "">("");
  const [panierRepas, setPanierRepas] = useState<"Oui" | "Non">("Non");
  const [notes, setNotes] = useState("");
  const [fichiers, setFichiers] = useState<File[]>([]);
  const [validerDirect, setValiderDirect] = useState<"Oui" | "Non">("Oui");
  const [recevoirEmail, setRecevoirEmail] = useState<"Oui" | "Non">("Oui");
  
  // États spécifiques au Régime Général
  const [isRegimeRG, setIsRegimeRG] = useState(false);
  const [typeContratRG, setTypeContratRG] = useState<"CDD de droit commun" | "CDI" | "Stage" | "Contrat de professionnalisation" | "Contrat d'apprentissage" | "Autre">("CDD de droit commun");
  const [motifCDD, setMotifCDD] = useState<"Remplacement d'une absence" | "Accroissement temporaire d'activité">("Remplacement d'une absence");
  const [nomPersonneRemplacee, setNomPersonneRemplacee] = useState("");
  const [situationPersonneRemplacee, setSituationPersonneRemplacee] = useState<"Absent temporairement ou contrat suspendu (maladie, maternité, congés payés, congé parental, etc...)" | "Salarié provisoirement à temps partiel (congé parental, congé création d'entreprise, etc...)" | "Salarié ayant quitté définitivement l'entreprise, poste en attente de suppression" | "Remplacement du chef d'entreprise">("Absent temporairement ou contrat suspendu (maladie, maternité, congés payés, congé parental, etc...)");
  const [motifAccroissement, setMotifAccroissement] = useState("");
  
  // États pour la gestion des organisations (staff)
  const [selectedOrg, setSelectedOrg] = useState<{ id: string; name: string } | null>(null);
  const [isStaff, setIsStaff] = useState(false);
  const [organizations, setOrganizations] = useState<{ id: string; name: string }[]>([]);
  const [loading, setLoading] = useState(false);
  const [redirecting, setRedirecting] = useState(false);
  const [err, setErr] = useState<string | null>(null);
  // Empêcher la re-application du préremplissage via ?dupe= après modifications utilisateur
  const [dupeApplied, setDupeApplied] = useState(false);
  // Afficher un modal de chargement pendant le pré-remplissage (duplication)
  const [prefillLoading, setPrefillLoading] = useState(false);

  // Détection de saisie en cours (dirty)
  const isDirty = useMemo(() => {
    const hasSpectacle = spectacle.trim() !== "" || spectaclePick !== null || spectacleManual;
    const hasSalarie = salarie !== null || salarieQuery.trim() !== "";
    const hasProfession = profession.trim() !== "" || professionPick !== null || professionQuery.trim() !== "";
    const hasDates = !!dateDebut || !!dateFin;
    const hasVolumes = (nbRep !== "" && Number(nbRep) > 0) || (nbServ !== "" && Number(nbServ) > 0) || (heuresTotal !== "") || (joursTravail.trim() !== "") || (datesRep.trim() !== "") || (datesServ.trim() !== "");
    const hasSalaire = typeSalaire !== "Brut" || (montantSalaire !== "" && Number(montantSalaire) > 0) || panierRepas !== "Non";
    const hasAutres = objet.trim() !== "" || notes.trim() !== "" || fichiers.length > 0 || isMultiMois === "Oui";
    const hasRG = isRegimeRG && (
      typeContratRG !== "CDD de droit commun" ||
      (typeContratRG === "CDD de droit commun" && motifCDD === "Remplacement d'une absence" && (nomPersonneRemplacee.trim() !== "" || situationPersonneRemplacee !== "Absent temporairement ou contrat suspendu (maladie, maternité, congés payés, congé parental, etc...)")) ||
      (typeContratRG === "CDD de droit commun" && motifCDD === "Accroissement temporaire d'activité" && motifAccroissement.trim() !== "")
    );
    return hasSpectacle || hasSalarie || hasProfession || hasDates || hasVolumes || hasSalaire || hasAutres || hasRG;
  }, [
    spectacle, spectaclePick, spectacleManual,
    salarie, salarieQuery,
    profession, professionPick, professionQuery,
    dateDebut, dateFin,
    nbRep, nbServ, heuresTotal, joursTravail, datesRep, datesServ,
    typeSalaire, montantSalaire, panierRepas,
    objet, notes, fichiers, isMultiMois,
    isRegimeRG, typeContratRG, motifCDD, nomPersonneRemplacee, situationPersonneRemplacee, motifAccroissement,
  ]);

  // Modal "Nouveau salarié"
  const [newSalarieOpen, setNewSalarieOpen] = useState(false);

  useEffect(() => {
    if (!newSalarieOpen) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => {
      document.body.style.overflow = prev;
    };
  }, [newSalarieOpen]);

  // Hydrate le formulaire si des valeurs initiales sont fournies (mode édition)
  useEffect(() => {
    if (!prefill) return;
    setSpectacle(prefill.spectacle || "");
    setObjet(String(prefill.numero_objet ?? ""));
    // Afficher la production dans la zone sélectionnée (lecture seule) quand on connaît le nom/numéro
    if (prefill.spectacle) {
      setSpectaclePick({ nom: prefill.spectacle, numero_objet: prefill.numero_objet ?? null });
      setSpectacleManual(false);
      setSpectacleQuery("");
    }
    setSalarie(prefill.salarie ?? null);
    setCategoriePro(prefill.categorie ?? "Artiste");
    setProfession(prefill.profession?.label || "");
    setProfessionPick(
      prefill.profession?.label
        ? { code: prefill.profession.code || "", label: prefill.profession.label }
        : null
    );
    setDateDebut(prefill.date_debut || "");
    setDateFin(prefill.date_fin || "");
    setNbRep(prefill.nb_representations ?? "");
    setNbServ(prefill.nb_services_repetition ?? "");
    setDatesRep(prefill.dates_representations || "");
    setDatesServ(prefill.dates_repetitions || "");
    setHeuresTotal(prefill.heures_total ?? "");
    setMinutesTotal(prefill.minutes_total ?? "0");
    setJoursTravail(prefill.jours_travail || "");
    if (typeof prefill.multi_mois === "boolean") setIsMultiMois(prefill.multi_mois ? "Oui" : "Non");
    setTypeSalaire(prefill.type_salaire ?? "Brut");
    setMontantSalaire(prefill.montant ?? "");
    setPanierRepas(prefill.panier_repas ?? "Non");
    setNotes(prefill.notes || "");
    // Si technicien: préremplir heures/minutes depuis nb_heures_annexes si fourni
    const cat = prefill.categorie ?? "Artiste";
    if (
      cat === "Technicien" &&
      prefill.nb_heures_annexes !== undefined &&
      prefill.nb_heures_annexes !== null &&
      prefill.nb_heures_annexes !== "" &&
      (prefill.heures_total === undefined || prefill.heures_total === "")
    ) {
      const raw = String(prefill.nb_heures_annexes).replace(",", ".");
      const total = parseFloat(raw);
      if (Number.isFinite(total)) {
        const h = Math.floor(total);
        const frac = total - h;
        // Si décimale, on met +30 min (comportement demandé)
        const mins: "0" | "30" = frac > 0 ? "30" : "0";
        setHeuresTotal(h);
        setMinutesTotal(mins);
      }
    }
    if (prefill.reference) setReference(prefill.reference);
  }, [prefill]);

  // Détection du paramètre regime=RG dans l'URL
  useEffect(() => {
    let search = "";
    try {
      search = window.location.search || "";
    } catch {
      return;
    }
    const urlParams = new URLSearchParams(search);
    const regime = urlParams.get("regime");
    
    if (regime === "RG") {
      setIsRegimeRG(true);
      // Adapter les valeurs par défaut pour le RG
      setCategoriePro("Non Cadre");
      setIsMultiMois("Non"); // Pas de multi-mois en RG
    } else {
      setIsRegimeRG(false);
      setCategoriePro("Artiste");
    }
  }, []);

  // Pré-remplissage du salarié via paramètre d'URL ?salarie=MATRICULE (ou ?matricule=)
  useEffect(() => {
    // Si déjà défini (via prefill ou choix manuel), ou si l'utilisateur a explicitement cliqué sur "Changer", ne rien faire
    if (urlSalarieDismissed || salarie || prefill?.salarie) return;

    // Lecture du paramètre d'URL (SSR safe)
    let search = "";
    try {
      search = window.location.search || "";
    } catch {
      return;
    }
    const urlParams = new URLSearchParams(search);
    const matriculeParam = urlParams.get("salarie") || urlParams.get("matricule");
    if (!matriculeParam) return;

    let cancelled = false;

    (async () => {
      // Récupérer le contexte client (même logique que dans les hooks)
      let clientInfo: ClientInfo = null;
      try {
        const res = await fetch("/api/me", {
          cache: "no-store",
          headers: { Accept: "application/json" },
          credentials: "include",
        });
        if (res.ok) {
          const me = await res.json();
          clientInfo = {
            id: me.active_org_id || null,
            name: me.active_org_name || "Organisation",
            api_name: me.active_org_api_name,
          } as ClientInfo;
        }
      } catch {}

      // 1) Essai par endpoint détail
      try {
        const detail: any = await api(`/salaries/${encodeURIComponent(matriculeParam)}`, {}, clientInfo);
        if (!cancelled && detail) {
          const displayName = (
            [detail.prenom, detail.nom_usage || detail.nom]
              .filter(Boolean)
              .join(" ")
              .trim()
          ) ||
          detail.nom_usage ||
          detail.nom ||
          detail.pseudo ||
          matriculeParam;

          setSalarie({
            matricule: detail.matricule ?? matriculeParam,
            nom: displayName,
            email: detail.email ?? undefined,
          });
          return;
        }
      } catch {
        // 2) Fallback: recherche générique
        try {
          const p = new URLSearchParams();
          p.set("page", "1");
          p.set("limit", "1");
          p.set("q", matriculeParam);
          const result: any = await api(`/salaries?${p.toString()}`, {}, clientInfo);
          const it = result?.items?.[0];
          if (!cancelled && it) {
            const displayName = ([it.prenom, it.nom].filter(Boolean).join(" ") || it.nom || it.pseudo || it.matricule).trim();
            setSalarie({ matricule: it.matricule, nom: displayName, email: it.email ?? undefined });
          }
        } catch {}
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [salarie, prefill?.salarie, urlSalarieDismissed]);

// Dans /components/contrats/NouveauCDDUForm.tsx
// Remplacez la section useEffect de duplication (lignes ~195-270) par ce code amélioré :

// Duplication via URL par identifiant : ?dupe_id=UUID
useEffect(() => {
  // Ne pas appliquer si on est déjà en mode édition avec prefill ou si déjà appliqué
  if (prefill || dupeApplied) return;

  // Lecture sécurisée du paramètre
  let search = "";
  try { search = window.location.search || ""; } catch { return; }
  const params = new URLSearchParams(search);
  const dupeId = params.get("dupe_id");
  if (!dupeId) return;

  setPrefillLoading(true);
  let cancelled = false;

  (async () => {
    try {
      // 1) Contexte client
      let clientInfo: ClientInfo = null;
      try {
        const res = await fetch("/api/me", { cache: "no-store", headers: { Accept: "application/json" }, credentials: "include" });
        if (res.ok) {
          const me = await res.json();
          clientInfo = { id: me.active_org_id || null, name: me.active_org_name || "Organisation", api_name: me.active_org_api_name } as ClientInfo;
        }
      } catch {}

      // 2) Récupération du contrat complet
      const contrat: any = await api(`/contrats/${encodeURIComponent(dupeId)}`, {}, clientInfo);
      if (cancelled || !contrat) { setPrefillLoading(false); return; }

      // 3) Mapping vers le format de pré-remplissage du formulaire
      const payload = {
        spectacle: contrat.production || "",
        numero_objet: contrat.objet ?? "",
        salarie: (contrat.salarie_matricule || contrat.salarie) ? {
          matricule: contrat.salarie_matricule || "",
          nom: (contrat.salarie?.nom || contrat.salarie_nom || "").toString(),
          email: contrat.salarie?.email || undefined,
        } : null,
        categorie: (() => {
          const c = (contrat.categorie_prof || "").toString().toLowerCase();
          return c.includes("tech") ? "Technicien" : "Artiste";
        })(),
        profession: { label: contrat.profession || "", code: contrat.profession_code || "" },
        date_debut: contrat.date_debut || "",
        date_fin: contrat.date_fin || "",
        nb_representations: Number.isFinite(Number(contrat.nb_representations)) ? Number(contrat.nb_representations) : "",
        nb_services_repetition: Number.isFinite(Number(contrat.nb_services_repetitions)) ? Number(contrat.nb_services_repetitions) : "",
        dates_representations: contrat.dates_representations || "",
        dates_repetitions: contrat.dates_repetitions || "",
        heures_total: (() => {
          const aem = Number(contrat.nb_heures_aem);
          if (Number.isFinite(aem) && aem >= 0) return aem;
          const rep = Number(contrat.nb_heures_repetitions || 0);
          const ann = Number(contrat.nb_heures_annexes || 0);
          const total = rep + ann;
          return Number.isFinite(total) && total > 0 ? total : "";
        })(),
        minutes_total: (contrat.minutes_total === "30" ? "30" : "0") as "0" | "30",
        jours_travail: typeof contrat.jours_travailles === "number" ? String(contrat.jours_travailles) : (contrat.jours_travail || ""),
        type_salaire: (() => {
          const t = (contrat.type_salaire || "").toString().toLowerCase();
          if (t.includes("net") && t.includes("pas")) return "Net avant PAS" as const;
          if (t.includes("coût") || t.includes("cout") || t.includes("total")) return "Coût total employeur" as const;
          if (t.includes("minimum") || t.includes("conventionnel")) return "Minimum conventionnel" as const;
          return "Brut" as const;
        })(),
        montant: (() => {
          const raw = (contrat.salaire_demande || contrat.montant || "").toString();
          const cleaned = raw.replace(/[^0-9,.-]/g, '').replace(/,(?=\d{1,2}$)/, '.').replace(/,/g, '.');
          const num = parseFloat(cleaned);
          return Number.isFinite(num) && num > 0 ? num : "";
        })(),
        panier_repas: (() => {
          const v = (contrat.panier_repas || "").toString().toLowerCase();
          if (["oui","true","1"].includes(v)) return "Oui" as const;
          if (["non","false","0"].includes(v)) return "Non" as const;
          return "Non" as const;
        })(),
        notes: contrat.notes || "",
        multi_mois: !!(contrat.is_multi_mois || (contrat.regime && String(contrat.regime).toUpperCase()==="CDDU_MULTI")),
      };

      // 4) Appliquer au formulaire (mêmes setters que pour ?dupe=)
      if (payload.spectacle) {
        setSpectacle(String(payload.spectacle));
        setSpectaclePick({ nom: String(payload.spectacle), numero_objet: (payload.numero_objet as any) ?? null });
        setSpectacleManual(false);
        setSpectacleQuery("");
      }
      if (payload.numero_objet !== undefined) setObjet(String(payload.numero_objet ?? ""));

      if (payload.salarie) setSalarie({ matricule: payload.salarie.matricule, nom: payload.salarie.nom, email: payload.salarie.email });
      if (payload.categorie) setCategoriePro(payload.categorie as any);

      if (payload.profession?.label) {
        setProfession(String(payload.profession.label));
        setProfessionPick({ code: String(payload.profession.code || ""), label: String(payload.profession.label) });
      }

      if (payload.date_debut) setDateDebut(String(payload.date_debut));
      if (payload.date_fin) setDateFin(String(payload.date_fin));

      if (payload.nb_representations !== "") setNbRep(payload.nb_representations as any);
      if (payload.nb_services_repetition !== "") setNbServ(payload.nb_services_repetition as any);

      if (payload.dates_representations) setDatesRep(String(payload.dates_representations));
      if (payload.dates_repetitions) setDatesServ(String(payload.dates_repetitions));

      if (payload.heures_total !== "") setHeuresTotal(payload.heures_total as any);
      if (payload.minutes_total) setMinutesTotal(payload.minutes_total);
      if (payload.jours_travail) setJoursTravail(String(payload.jours_travail));

      if (payload.type_salaire) setTypeSalaire(payload.type_salaire);
      if (payload.montant !== "") setMontantSalaire(payload.montant as any);
      if (payload.panier_repas) setPanierRepas(payload.panier_repas);
      if (payload.notes) setNotes(String(payload.notes));
      setIsMultiMois(payload.multi_mois ? "Oui" : "Non");

      // 5) Nouvelle référence systématique
      setReference(generateReference());

      // 6) Marquer appliqué
      setDupeApplied(true);
      setPrefillLoading(false);
    } catch (e) {
      console.warn("⚠️ Duplication par id échouée:", e);
      setPrefillLoading(false);
    }
  })();

  return () => { cancelled = true; setPrefillLoading(false); };
}, [prefill, dupeApplied]);

// Duplication via URL: ?dupe=base64(json) ou ?duplicate=base64(json)
useEffect(() => {
  // Ne pas appliquer si on est déjà en mode édition avec prefill ou si déjà appliqué
  if (prefill || dupeApplied) return;

  // SSR safe-guard
  let search = "";
  try {
    search = window.location.search || "";
  } catch {
    return;
  }
  const params = new URLSearchParams(search);
  const dupe = params.get("dupe") || params.get("duplicate");
  if (!dupe) return;

  const data = parseBase64Json<Partial<NouveauCDDUPrefill>>(dupe);
  if (!data) {
    console.warn("❌ Impossible de décoder les données de duplication");
    return;
  }

  setPrefillLoading(true);
  console.log("🔄 Données de duplication reçues:", data); // Debug

  // Application des données avec vérifications
  // ========================================

  // Production/Spectacle
  if (data.spectacle) {
    const spectacleName = String(data.spectacle).trim();
    if (spectacleName) {
      setSpectacle(spectacleName);
      setSpectaclePick({ nom: spectacleName, numero_objet: (data.numero_objet as any) ?? null });
      setSpectacleManual(false);
      setSpectacleQuery("");
      console.log("✅ Production pré-remplie:", spectacleName);
    }
  }

  // Numéro d'objet
  if (!objet && data.numero_objet !== undefined && data.numero_objet !== null) {
    const objetValue = String(data.numero_objet).trim();
    setObjet(objetValue);
    if (objetValue) {
      console.log("✅ Numéro d'objet pré-rempli:", objetValue);
    }
  }

  // Salarié
  if (!salarie && data.salarie) {
    const salarieData = {
      matricule: String(data.salarie.matricule || "").trim(),
      nom: String(data.salarie.nom || "").trim(),
      email: data.salarie.email ? String(data.salarie.email).trim() : undefined,
    };
    
    if (salarieData.matricule && salarieData.nom) {
      setSalarie(salarieData);
      console.log("✅ Salarié pré-rempli:", salarieData);
      
      // Si l'email n'est pas fourni dans la duplication, tenter un enrichissement
      if (!salarieData.email || salarieData.email === "") {
        (async () => {
          try {
            let clientInfo: ClientInfo = null;
            const res = await fetch("/api/me", {
              cache: "no-store",
              headers: { Accept: "application/json" },
              credentials: "include",
            });
            if (res.ok) {
              const me = await res.json();
              clientInfo = {
                id: me.active_org_id || null,
                name: me.active_org_name || "Organisation",
                api_name: me.active_org_api_name,
              } as ClientInfo;
            }
            
            const detail: any = await api(`/salaries/${encodeURIComponent(salarieData.matricule)}`, {}, clientInfo);
            if (detail?.email) {
              setSalarie((prev) => (prev ? { ...prev, email: detail.email } : prev));
              console.log("✅ Email salarié enrichi:", detail.email);
            }
          } catch (e) {
            console.warn("⚠️ Impossible d'enrichir l'email du salarié:", e);
          }
        })();
      }
    }
  }

  // Catégorie professionnelle avec vérification améliorée
  if (data.categorie) {
    const categorieStr = String(data.categorie).trim().toLowerCase();
    let newCategorie: "Artiste" | "Technicien" | "Autre" = "Artiste";
    
    if (categorieStr.includes("technicien") || categorieStr === "technicien") {
      newCategorie = "Technicien";
    } else if (categorieStr.includes("artiste") || categorieStr === "artiste") {
      newCategorie = "Artiste";
    } else if (categorieStr.includes("autre") || categorieStr === "autre") {
      newCategorie = "Autre";
    }
    
    setCategoriePro(newCategorie);
    console.log("✅ Catégorie professionnelle pré-remplie:", newCategorie);
  }

  // Profession
  if (!profession && (data.profession?.label || data.profession)) {
    const professionData = data.profession?.label ? data.profession : { label: String(data.profession), code: "" };
    const professionLabel = String(professionData.label).trim();
    
    if (professionLabel) {
      setProfession(professionLabel);
      setProfessionPick({
        code: String(professionData.code || "").trim(),
        label: professionLabel,
      });
      console.log("✅ Profession pré-remplie:", professionLabel);
    }
  }

  // Dates
  if (!dateDebut && data.date_debut) {
    const debutValue = String(data.date_debut).trim();
    if (debutValue.match(/^\d{4}-\d{2}-\d{2}$/)) {
      setDateDebut(debutValue);
      console.log("✅ Date début pré-remplie:", debutValue);
    }
  }
  
  if (!dateFin && data.date_fin) {
    const finValue = String(data.date_fin).trim();
    if (finValue.match(/^\d{4}-\d{2}-\d{2}$/)) {
      setDateFin(finValue);
      console.log("✅ Date fin pré-remplie:", finValue);
    }
  }

  // Nombres avec vérifications
  if (nbRep === "" && data.nb_representations !== undefined && data.nb_representations !== null) {
    const repValue = Number(data.nb_representations);
    if (Number.isInteger(repValue) && repValue >= 0) {
      setNbRep(repValue);
      console.log("✅ Nb représentations pré-rempli:", repValue);
    }
  }

  if (nbServ === "" && data.nb_services_repetition !== undefined && data.nb_services_repetition !== null) {
    const servValue = Number(data.nb_services_repetition);
    if (Number.isInteger(servValue) && servValue >= 0) {
      setNbServ(servValue);
      console.log("✅ Nb services répétition pré-rempli:", servValue);
    }
  }

  // Dates textuelles
  if (!datesRep && data.dates_representations) {
    const datesRepValue = String(data.dates_representations).trim();
    if (datesRepValue) {
      setDatesRep(datesRepValue);
      console.log("✅ Dates représentations pré-remplies:", datesRepValue);
    }
  }

  if (!datesServ && data.dates_repetitions) {
    const datesServValue = String(data.dates_repetitions).trim();
    if (datesServValue) {
      setDatesServ(datesServValue);
      console.log("✅ Dates répétitions pré-remplies:", datesServValue);
    }
  }

  // Heures et minutes
  if (heuresTotal === "" && data.heures_total !== undefined && data.heures_total !== null) {
    const heuresValue = Number(data.heures_total);
    if (Number.isFinite(heuresValue) && heuresValue >= 0) {
      setHeuresTotal(Math.floor(heuresValue)); // Arrondir à l'entier inférieur
      console.log("✅ Heures total pré-remplies:", Math.floor(heuresValue));
    }
  }

  if (data.minutes_total && (data.minutes_total === "0" || data.minutes_total === "30")) {
    setMinutesTotal(data.minutes_total);
    console.log("✅ Minutes total pré-remplies:", data.minutes_total);
  }

  if (!joursTravail && data.jours_travail) {
    const joursTravailValue = String(data.jours_travail).trim();
    if (joursTravailValue) {
      setJoursTravail(joursTravailValue);
      console.log("✅ Jours travail pré-remplis:", joursTravailValue);
    }
  }

  // Type de salaire avec vérification
  if (data.type_salaire) {
    const typeValue = String(data.type_salaire).trim();
    const validTypes: Array<"Brut" | "Net avant PAS" | "Coût total employeur" | "Minimum conventionnel"> = 
      ["Brut", "Net avant PAS", "Coût total employeur", "Minimum conventionnel"];
    
    if (validTypes.includes(typeValue as any)) {
      setTypeSalaire(typeValue as any);
      console.log("✅ Type salaire pré-rempli:", typeValue);
    } else {
      console.warn("⚠️ Type de salaire invalide:", typeValue);
    }
  }

  // Montant avec validation
  if (montantSalaire === "" && data.montant !== undefined && data.montant !== null) {
    const montantValue = Number(data.montant);
    if (Number.isFinite(montantValue) && montantValue > 0) {
      setMontantSalaire(montantValue);
      console.log("✅ Montant pré-rempli:", montantValue);
    }
  }

  // Panier repas
  if (data.panier_repas && (data.panier_repas === "Oui" || data.panier_repas === "Non")) {
    setPanierRepas(data.panier_repas);
    console.log("✅ Panier repas pré-rempli:", data.panier_repas);
  }

  // Multi-mois
  if (typeof data.multi_mois === "boolean") {
    setIsMultiMois(data.multi_mois ? "Oui" : "Non");
    console.log("✅ Multi-mois pré-rempli:", data.multi_mois ? "Oui" : "Non");
  }

  // Toujours régénérer une nouvelle référence pour la duplication
  const newRef = generateReference();
  setReference(newRef);
  console.log("✅ Nouvelle référence générée:", newRef);

  // Marquer comme appliqué pour ne pas réécraser les changements utilisateur
  setDupeApplied(true);
  setPrefillLoading(false);

}, [prefill, dupeApplied]);

  const { open: showLeaveConfirm, confirmLeave, cancelLeave, allowNavRef } = useUnsavedChangesPrompt(isDirty && !redirecting && !loading);

useEffect(() => {
  // En création seulement : pas de prefill.reference -> on génère
  if (!prefill?.reference) {
    setReference(generateReference());
  }
}, [prefill?.reference]);

  const filteredProfessions = useMemo(() => {
    const q = professionQuery.trim().toLowerCase();
    if (!q) return PROFESSIONS_ARTISTE;
    return PROFESSIONS_ARTISTE.filter(p =>
      p.code.toLowerCase().includes(q) || p.label.toLowerCase().includes(q)
    ).slice(0, 20);
  }, [professionQuery]);

  const filteredTechniciens = useMemo(() => {
    if (!techniciens) return [] as TechnicienOption[];
    const q = norm(professionQuery);
    if (!q) return techniciens.slice(0, 30);
    return techniciens
      .filter(p => norm(p.code).includes(q) || norm(p.label).includes(q))
      .slice(0, 30);
  }, [techniciens, professionQuery]);

  const useHeuresMode = useMemo(() => {
    return (
      categoriePro === "Technicien" ||
      (categoriePro === "Artiste" && professionPick?.code === "MET040")
    );
  }, [categoriePro, professionPick]);

  const debouncedSalarieQuery = useDebouncedValue(salarieQuery, 300);
  const { data: salarieSearch, isFetching: fetchingSalaries } = useSearchSalaries(debouncedSalarieQuery, selectedOrg?.id);
  const { data: spectacleSearch, isFetching: fetchingSpectacles } = useSearchSpectacles(spectacleQuery, selectedOrg?.id);

  // Vérifier si l'utilisateur est staff et récupérer les organisations
  useEffect(() => {
    const checkStaffAndLoadOrgs = async () => {
      try {
        const res = await fetch("/api/me", { 
          cache: "no-store", 
          headers: { Accept: "application/json" }, 
          credentials: "include" 
        });
        
        if (res.ok) {
          const me = await res.json();
          const userIsStaff = me.is_staff || false;
          setIsStaff(userIsStaff);
          
          // Si l'utilisateur est staff, récupérer la liste des organisations
          if (userIsStaff) {
            const orgRes = await fetch("/api/organizations", {
              headers: { Accept: "application/json" },
              credentials: "include"
            });
            
            if (orgRes.ok) {
              const orgData = await orgRes.json();
              setOrganizations(orgData.items || []);
            }
          }
        }
      } catch (error) {
        console.error("Erreur lors de la vérification staff:", error);
      }
    };
    
    checkStaffAndLoadOrgs();
  }, []);

  // Réinitialiser l'index actif quand la query ou le nombre de résultats change
  useEffect(() => {
    setSpectacleActive(0);
  }, [spectacleQuery, spectacleSearch?.items?.length]);

  useEffect(() => {
    setSalarieActive(0);
  }, [salarieQuery, salarieSearch?.items?.length]);

  const currentProfList = (categoriePro === 'Artiste' ? filteredProfessions : filteredTechniciens);
  useEffect(() => {
    setProfessionActive(0);
  }, [professionQuery, currentProfList.length, categoriePro]);

  const isPastStart = useMemo(() => {
    if (!dateDebut) return false;
    return dateDebut < todayYmd();
  }, [dateDebut]);

  async function ensureTechniciensLoaded(){
    if (techLoadedRef.current || techniciens) return;
    try {
      setTechLoading(true);
      const res = await fetch('/data/professions-techniciens.json', { cache: 'force-cache' });
      if (!res.ok) throw new Error('HTTP '+res.status);
      const list: TechnicienOption[] = await res.json();
      setTechniciens(list);
      techLoadedRef.current = true;
    } finally {
      setTechLoading(false);
    }
  }

  function onFilesSelected(files: FileList | null) {
    if (!files) return;
    const ok: File[] = [];
    for (const f of Array.from(files)) {
      if (f.size > 20 * 1024 * 1024) {
        setErr(`Le fichier "${f.name}" dépasse 20 Mo`);
        return;
      }
      ok.push(f);
    }
    setFichiers(ok);
  }

  async function onSubmit() {
    setErr(null);

    // validations minimales
    if (!isRegimeRG && !spectacle.trim()) return setErr("Le champ Spectacle est obligatoire.");
    if (!salarie) return setErr("Veuillez sélectionner un·e salarié·e.");
    if (!profession.trim()) return setErr("La profession est obligatoire.");
    if (!dateDebut) return setErr("La date de début du contrat est obligatoire.");

    // Validations spécifiques au RG
    if (isRegimeRG) {
      if (typeContratRG === "CDD de droit commun") {
        if (motifCDD === "Remplacement d'une absence") {
          if (!nomPersonneRemplacee.trim()) return setErr("Veuillez indiquer le nom de la personne remplacée.");
        }
        if (motifCDD === "Accroissement temporaire d'activité") {
          if (!motifAccroissement.trim()) return setErr("Veuillez décrire le motif de l'accroissement d'activité.");
        }
      }
      // Pour CDI, pas de date de fin obligatoire
      if (typeContratRG !== "CDI" && !dateFin) {
        return setErr("La date de fin est obligatoire pour ce type de contrat.");
      }
    }

    if (!isRegimeRG && useHeuresMode) {
      if (heuresTotal === "" || Number(heuresTotal) < 0)
        return setErr("Veuillez indiquer le nombre d'heures de travail.");
    }
    if (dateFin && dateDebut && dateFin < dateDebut)
      return setErr("La date de fin doit être postérieure ou égale à la date de début.");
    if (isPastStart && !confirmPastStart)
      return setErr("Veuillez cocher la case de confirmation liée au démarrage dans le passé.");

    if (typeSalaire !== "Minimum conventionnel") {
      if (montantSalaire === "" || Number(montantSalaire) <= 0)
        return setErr("Veuillez saisir un montant de rémunération valide.");
    }

    // Valeurs structurées communes (PATCH ou webhook)
    const payload = {
      regime: isRegimeRG ? "RG" : (isMultiMois === "Oui" ? "CDDU_MULTI" : "CDDU_MONO"),
      multi_mois: !isRegimeRG && isMultiMois === "Oui",
      spectacle: isRegimeRG ? undefined : spectacle,
      numero_objet: isRegimeRG ? undefined : (objet || undefined),
      // Champs spécifiques au RG
      type_contrat_rg: isRegimeRG ? typeContratRG : undefined,
      motif_cdd: isRegimeRG && typeContratRG === "CDD de droit commun" ? motifCDD : undefined,
      nom_personne_remplacee: isRegimeRG && typeContratRG === "CDD de droit commun" && motifCDD === "Remplacement d'une absence" ? nomPersonneRemplacee : undefined,
      situation_personne_remplacee: isRegimeRG && typeContratRG === "CDD de droit commun" && motifCDD === "Remplacement d'une absence" ? situationPersonneRemplacee : undefined,
      motif_accroissement: isRegimeRG && typeContratRG === "CDD de droit commun" && motifCDD === "Accroissement temporaire d'activité" ? motifAccroissement : undefined,
      // Champs communs
      salarie: salarie!, // validé plus haut
      categorie_professionnelle: categoriePro,
      profession,
      profession_code: !isRegimeRG ? (professionPick?.code || undefined) : undefined,
      date_debut: dateDebut,
      date_fin: (isRegimeRG && typeContratRG === "CDI") ? undefined : (dateFin || undefined),
      nb_representations: !isRegimeRG ? nbRep : undefined,
      nb_services_repetition: !isRegimeRG ? nbServ : undefined,
      dates_representations: !isRegimeRG ? (datesRep || undefined) : undefined,
      dates_repetitions: !isRegimeRG ? (datesServ || undefined) : undefined,
      heures_travail: !isRegimeRG && useHeuresMode ? heuresTotal : undefined,
      minutes_travail: !isRegimeRG && useHeuresMode ? minutesTotal : undefined,
      jours_travail: !isRegimeRG && useHeuresMode ? (joursTravail || undefined) : undefined,
      type_salaire: typeSalaire,
      montant: typeSalaire !== "Minimum conventionnel" ? (montantSalaire === "" ? undefined : montantSalaire) : undefined,
      panier_repas: panierRepas,
      reference,
      notes: notes || undefined,
      valider_direct: validerDirect === "Oui",
    } as const;

    setLoading(true);
    try {
      if (onSubmitOverride) {
        // MODE ÉDITION → PATCH via l'API Next (proxy Lambda)
        await onSubmitOverride(payload as any);
      } else {
        // MODE CRÉATION → utiliser l'API appropriée selon le régime
        const contractData = {
          // Champs communs
          salarie_matricule: payload.salarie.matricule,
          salarie_nom: payload.salarie.nom,
          salarie_email: payload.salarie.email,
          categorie: payload.categorie_professionnelle,
          profession: payload.profession,
          date_debut: payload.date_debut,
          date_fin: payload.date_fin,
          type_salaire: payload.type_salaire,
          montant: payload.montant,
          panier_repas: payload.panier_repas,
          reference: payload.reference,
          notes: payload.notes,
          // Ajouter l'organisation sélectionnée si staff
          org_id: selectedOrg?.id || null,
          
          // Champs spécifiques selon le régime
          ...(isRegimeRG ? {
            // Champs RG
            regime: "RG",
            type_contrat: payload.type_contrat_rg,
            motif_cdd: payload.motif_cdd,
            nom_personne_remplacee: payload.nom_personne_remplacee,
            situation_personne_remplacee: payload.situation_personne_remplacee,
            motif_accroissement: payload.motif_accroissement,
          } : {
            // Champs CDDU
            regime: payload.regime,
            production_id: spectaclePick?.id || null,
            spectacle: payload.spectacle,
            numero_objet: payload.numero_objet,
            profession_code: payload.profession_code,
            profession_label: payload.profession,
            nb_representations: payload.nb_representations,
            nb_services_repetition: payload.nb_services_repetition,
            dates_representations: payload.dates_representations,
            dates_repetitions: payload.dates_repetitions,
            heures_total: payload.heures_travail,
            minutes_total: payload.minutes_travail,
            jours_travail: payload.jours_travail,
            multi_mois: payload.multi_mois,
          })
        };

        // Utiliser l'endpoint approprié
        const apiEndpoint = isRegimeRG ? "/api/rg-contracts" : "/api/cddu-contracts";
        
        const res = await fetch(apiEndpoint, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(contractData)
        });
        
        if (!res.ok) {
          const errorData = await res.json().catch(() => ({}));
          throw new Error(errorData.error || `Erreur HTTP ${res.status}`);
        }
      }

      // Autoriser la navigation après soumission + feedback
      allowNavRef.current = true;
      setRedirecting(true);
      setTimeout(() => {
        router.push("/contrats");
      }, 3000);
    } catch (e: any) {
      setErr(e?.message || "Impossible d’envoyer le formulaire.");
    } finally {
      setLoading(false);
    }
  }

  return (
    <>
      <div className="space-y-5">
        {!prefill && (
          <div className="rounded-2xl border bg-white p-4">
            <div className="text-lg font-semibold">{isRegimeRG ? "Nouveau contrat Régime Général" : "Nouveau CDDU"}</div>
            <p className="text-sm text-slate-600 mt-1">
              Ce formulaire est dédié aux CDD d’usage (intermittents du spectacle).
            </p>
          </div>
        )}

        {/* Référence */}
        <Section title="Référence Contrat">
          <div className="grid grid-cols-1 md:grid-cols-[240px_1fr] items-center gap-4">
            <Label>Référence</Label>
            <div className="flex items-center gap-2 text-sm">
              <input
                value={reference || "(génération en cours…)"}
                onFocus={() => {
  if (!reference && !prefill?.reference) {
    setReference(generateReference());
  }
}}
                onChange={isStaff ? (e) => setReference(e.target.value) : undefined}
                readOnly={!isStaff}
                className={`w-full px-3 py-2 rounded-lg border text-sm ${
                  isStaff 
                    ? "bg-white" 
                    : "bg-slate-50"
                }`}
              />
              <span className="inline-flex items-center gap-1 text-xs text-slate-500">
                <Info className="w-3.5 h-3.5" />
                {isStaff ? "Générée automatiquement - modifiable par Staff" : "Générée automatiquement par l'Espace Paie"}
              </span>
            </div>
          </div>
        </Section>

        {/* Sélection d'organisation (pour les utilisateurs staff) */}
        {isStaff && (
          <Section title="Organisation">
            <div className="grid grid-cols-1 md:grid-cols-[240px_1fr] items-center gap-4">
              <Label required>Structure</Label>
              <div>
                <select
                  value={selectedOrg?.id || ""}
                  onChange={(e) => {
                    const orgId = e.target.value;
                    const org = organizations.find(o => o.id === orgId);
                    setSelectedOrg(org || null);
                  }}
                  className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                  required
                >
                  <option value="">Sélectionner une structure...</option>
                  {organizations.map((org) => (
                    <option key={org.id} value={org.id}>
                      {org.name}
                    </option>
                  ))}
                </select>
              </div>
            </div>
          </Section>
        )}

        {/* Production - Masquée en mode Régime Général */}
        {!isRegimeRG && (
          <Section title="Production">
          <FieldRow>
            <div>
              <Label required>Production</Label>
              {spectaclePick ? (
                <div className="flex items-center gap-2">
                  <input
                    readOnly
                    value={`${spectaclePick.nom}${spectaclePick.numero_objet ? ` — ${spectaclePick.numero_objet}` : ""}`}
                    className="w-full px-3 py-2 rounded-lg border bg-slate-50 text-sm"
                  />
                  <button
                    type="button"
                    onClick={() => { setSpectaclePick(null); setSpectacleQuery(""); }}
                    className="text-xs px-2 py-2 rounded-lg border"
                  >
                    Changer
                  </button>
                </div>
              ) : (
                <div>
                  {spectacleManual ? (
                    <>
                      <input
                        ref={spectacleInputRef}
                        value={spectacle}
                        onChange={(e) => setSpectacle(e.target.value)}
                        placeholder="Saisir le nom de la nouvelle production…"
                        className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                      />
                      <div className="mt-2 flex items-center gap-2">
                        <button
                          type="button"
                          onClick={() => { setSpectacleManual(false); setSpectacleQuery(""); setSpectaclePick(null); }}
                          className="inline-flex items-center gap-2 text-xs px-2 py-1 rounded-lg bg-gradient-to-r from-blue-500 to-indigo-600 text-white shadow hover:opacity-90 transition"
                        >
                          Rechercher une production existante
                        </button>
                      </div>
                    </>
                  ) : (
                    <>
                      <div className="relative">
                        <Search className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" />
                        <input
                          value={spectacleQuery}
                          onChange={(e) => setSpectacleQuery(e.target.value)}
                          onKeyDown={(e) => {
                            const items = spectacleSearch?.items || [];
                            if (spectacleQuery.length <= 1 || items.length === 0) return;
                            if (e.key === 'ArrowDown') { e.preventDefault(); setSpectacleActive(i => Math.min(i + 1, items.length - 1)); }
                            if (e.key === 'ArrowUp') { e.preventDefault(); setSpectacleActive(i => Math.max(i - 1, 0)); }
                            if (e.key === 'Enter') {
                              e.preventDefault();
                              const s = items[spectacleActive];
                              if (s) {
                                setSpectaclePick(s);
                                setSpectacle(s.nom);
                                if (s.numero_objet) setObjet(String(s.numero_objet));
                              }
                            }
                            if (e.key === 'Escape') {
                              e.preventDefault();
                              (e.currentTarget as HTMLInputElement).blur();
                            }
                          }}
                          placeholder="Rechercher une production (min. 2 lettres)…"
                          className="w-full pl-9 px-3 py-2 rounded-lg border bg-white text-sm"
                        />
                      </div>

                      <div className="mt-2">
                        <button
                          type="button"
                          onClick={() => {
                            setSpectacleManual(true);
                            setSpectaclePick(null);
                            setSpectacleQuery("");
                            setSpectacle("");
                            setTimeout(() => spectacleInputRef.current?.focus(), 0);
                          }}
                          className="inline-flex items-center gap-2 text-xs px-2 py-1 rounded-lg bg-gradient-to-r from-blue-500 to-indigo-600 text-white shadow hover:opacity-90 transition"
                        >
                          Nouvelle production
                        </button>
                      </div>

                      {fetchingSpectacles && (
                        <div className="text-xs text-slate-500 mt-2">
                          <Loader2 className="w-3.5 h-3.5 inline animate-spin mr-1" />
                          Recherche…
                        </div>
                      )}
                      {spectacleSearch?.items && spectacleQuery.length > 1 && (
                        <div className="mt-2 max-h-56 overflow-auto rounded-lg border">
                          {spectacleSearch.items.length === 0 ? (
                            <div className="p-3 text-sm text-slate-500">Aucun résultat.</div>
                          ) : (
                            spectacleSearch.items.map((s, idx) => (
                              <button
                                type="button"
                                key={`${s.nom}-${s.numero_objet ?? idx}`}
                                onClick={() => {
                                  setSpectaclePick(s);
                                  setSpectacle(s.nom);
                                  if (s.numero_objet) setObjet(String(s.numero_objet));
                                }}
                                className={`w-full text-left px-3 py-2 text-sm ${idx === spectacleActive ? 'bg-slate-50' : 'hover:bg-slate-50'}`}
                                onMouseEnter={() => setSpectacleActive(idx)}
                              >
                                <div className="font-medium">{s.nom}</div>
                                <div className="text-xs text-slate-500">{s.numero_objet ? `n° d’objet : ${s.numero_objet}` : "Sans n° d’objet"}</div>
                              </button>
                            ))
                          )}
                        </div>
                      )}
                    </>
                  )}
                </div>
              )}
            </div>

            <div>
              <Label>Avez-vous déjà un n° d’objet ?</Label>
              <input
                value={objet}
                onChange={(e) => setObjet(e.target.value)}
                placeholder="ex : 2B728735689"
                className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
              />
              <p className="text-[11px] text-slate-500 mt-1">
                Si vous choisissez une production existante, le numéro se remplit automatiquement s’il est connu. Si vous n'avez pas encore de n° d'objet pour une nouvelle production, nous nous occuperons gratuitement de la démarche.
              </p>
            </div>
          </FieldRow>
        </Section>
        )}

        {/* Salarié·e */}
        <Section title="Salarié">
          <FieldRow>
            <div>
              <Label required>Salarié</Label>
              {salarie ? (
                <div className="flex items-center gap-2">
                  <input
                    readOnly
                    value={`${salarie.nom} — ${salarie.matricule}`}
                    className="w-full px-3 py-2 rounded-lg border bg-slate-50 text-sm"
                  />
                  <button
                    type="button"
                    onClick={() => { setUrlSalarieDismissed(true); setSalarie(null); setSalarieQuery(""); }}
                    className="text-xs px-2 py-2 rounded-lg border"
                  >
                    Changer
                  </button>
                </div>
              ) : (
                <div>
                  <div className="relative">
                    <Search className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" />
                    <input
                      value={salarieQuery}
                      onChange={(e) => setSalarieQuery(e.target.value)}
                      onKeyDown={(e) => {
                        const items = salarieSearch?.items || [];
                        if (salarieQuery.length <= 1 || items.length === 0) return;
                        if (e.key === 'ArrowDown') { e.preventDefault(); setSalarieActive(i => Math.min(i + 1, items.length - 1)); }
                        if (e.key === 'ArrowUp') { e.preventDefault(); setSalarieActive(i => Math.max(i - 1, 0)); }
                        if (e.key === 'Enter') {
                          e.preventDefault();
                          const s = items[salarieActive];
                          if (s) setSalarie(s);
                        }
                        if (e.key === 'Escape') {
                          e.preventDefault();
                          (e.currentTarget as HTMLInputElement).blur();
                        }
                      }}
                      placeholder="Rechercher un salarié (min. 2 lettres)…"
                      className="w-full pl-9 px-3 py-2 rounded-lg border bg-white text-sm"
                    />
                  </div>
                  <div className="mt-2">
                    <button
                      type="button"
                      onClick={() => setNewSalarieOpen(true)}
                      className="inline-flex items-center gap-2 text-xs px-2 py-1 rounded-lg bg-gradient-to-r from-blue-500 to-indigo-600 text-white shadow hover:opacity-90 transition"
                    >
                      Nouveau salarié
                    </button>
                  </div>
                  {fetchingSalaries && (
                    <div className="text-xs text-slate-500 mt-2">
                      <Loader2 className="w-3.5 h-3.5 inline animate-spin mr-1" />
                      Recherche…
                    </div>
                  )}
                  {salarieSearch?.items && salarieQuery.length > 1 && (
                    <div className="mt-2 max-h-56 overflow-auto rounded-lg border">
                      {salarieSearch.items.length === 0 ? (
                        <div className="p-3 text-sm text-slate-500">Aucun résultat.</div>
                      ) : (
                        salarieSearch.items.map((s, idx) => (
                          <button
                            type="button"
                            key={s.matricule}
                            onClick={() => setSalarie(s)}
                            className={`w-full text-left px-3 py-2 text-sm ${idx === salarieActive ? 'bg-slate-50' : 'hover:bg-slate-50'}`}
                            onMouseEnter={() => setSalarieActive(idx)}
                          >
                            <div className="font-medium">{s.nom}</div>
                            <div className="text-xs text-slate-500">{s.matricule} {s.email ? `• ${s.email}` : ""}</div>
                          </button>
                        ))
                      )}
                    </div>
                  )}
                </div>
              )}
            </div>

            <div>
              <Label>Son adresse email</Label>
              <input
                value={salarie?.email || ""}
                readOnly
                placeholder="—"
                className="w-full px-3 py-2 rounded-lg border bg-slate-50 text-sm"
              />
              <p className="text-[11px] text-slate-500 mt-1">
                Nous utilisons l'adresse e-mail de votre salarié pour lui envoyer une demande de justificatifs et d'état-civil, puis les notifications afférentes à la gestion de son contrat de travail. Cette zone peut être laissée vide si le salarié est déjà connu de nos services.
              </p>
            </div>
          </FieldRow>

          <FieldRow>
            <div>
              <Label required>Catégorie professionnelle</Label>
              <select
                value={categoriePro}
                onChange={(e) => setCategoriePro(e.target.value as any)}
                className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
              >
                {isRegimeRG ? (
                  <>
                    <option>Cadre</option>
                    <option>Non Cadre</option>
                    <option>Je ne sais pas</option>
                  </>
                ) : (
                  <>
                    <option>Artiste</option>
                    <option>Technicien</option>
                  </>
                )}
              </select>
            </div>
            <div>
              <Label required>Profession pour ce contrat — {categoriePro}</Label>
              {isRegimeRG ? (
                // En mode RG, simple champ de saisie libre
                <div>
                  <input
                    value={profession}
                    onChange={(e) => setProfession(e.target.value)}
                    placeholder="Saisissez la profession..."
                    className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                  />
                  <p className="text-[11px] text-slate-500 mt-1">
                    Saisissez librement la profession du salarié pour ce contrat.
                  </p>
                </div>
              ) : (
                // Mode CDDU avec listes de professions
                (categoriePro === "Artiste" || categoriePro === "Technicien") ? (
                professionPick ? (
                  <>
                    <div className="flex items-center gap-2">
                      <input
                        readOnly
                        value={`${professionPick.label} — ${professionPick.code}`}
                        className="w-full px-3 py-2 rounded-lg border bg-slate-50 text-sm"
                      />
                      <button
                        type="button"
                        onClick={() => { setProfessionPick(null); setProfessionQuery(""); setProfession(""); }}
                        className="text-xs px-2 py-2 rounded-lg border"
                      >
                        Changer
                      </button>       
                    </div>
                    <p className="text-[11px] text-slate-500 mt-1">
                      Cette liste contient l'ensemble des professions de l'Annexe 8 (Techniciens) ou 10 (Artistes) et leur Code Emploi. Si une profession n'apparaît pas, il n'est pas possible de réaliser un CDDU pour ce contrat.
                    </p>
                  </>
                ) : (
                  <div>
                    <div className="relative">
                      <Search className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-slate-400" />
                      <input
                        value={professionQuery}
                        onFocus={() => { if (categoriePro === 'Technicien') ensureTechniciensLoaded(); }}
                        onChange={(e) => { setProfessionQuery(e.target.value); if (categoriePro === 'Technicien') ensureTechniciensLoaded(); }}
                        onKeyDown={(e) => {
                          const items = (categoriePro === 'Artiste' ? filteredProfessions : filteredTechniciens);
                          if (items.length === 0) return;
                          if (e.key === 'ArrowDown') { e.preventDefault(); setProfessionActive(i => Math.min(i + 1, items.length - 1)); }
                          if (e.key === 'ArrowUp') { e.preventDefault(); setProfessionActive(i => Math.max(i - 1, 0)); }
                          if (e.key === 'Enter') {
                            e.preventDefault();
                            const p = items[professionActive];
                            if (p) { setProfessionPick(p as any); setProfession((p as any).label); }
                          }
                          if (e.key === 'Escape') { e.preventDefault(); (e.currentTarget as HTMLInputElement).blur(); }
                        }}
                        placeholder={`Rechercher une profession ${categoriePro.toLowerCase()} (min. 1 lettre)…`}
                        className="w-full pl-9 px-3 py-2 rounded-lg border bg-white text-sm"
                      />
                    </div>
                    {techLoading && categoriePro === 'Technicien' && (
                      <div className="text-xs text-slate-500 mt-2">
                        <Loader2 className="w-3.5 h-3.5 inline animate-spin mr-1" />
                        Chargement de la liste des professions…
                      </div>
                    )}
                    <div className="mt-2 max-h-56 overflow-auto rounded-lg border">
                      {(
                        (categoriePro === 'Artiste' ? filteredProfessions : filteredTechniciens)
                      ).length === 0 ? (
                        <div className="p-3 text-sm text-slate-500">Aucun résultat.</div>
                      ) : (
                        (categoriePro === 'Artiste' ? filteredProfessions : filteredTechniciens).map((p, idx) => (
                          <button
                            type="button"
                            key={p.code}
                            onClick={() => { setProfessionPick(p); setProfession(p.label); }}
                            className={`w-full text-left px-3 py-2 text-sm ${idx === professionActive ? 'bg-slate-50' : 'hover:bg-slate-50'}`}
                            onMouseEnter={() => setProfessionActive(idx)}
                          >
                            <div className="font-medium">{p.label}</div>
                            <div className="text-xs text-slate-500">{p.code}</div>
                          </button>
                        ))
                      )}
                    </div>
                    <p className="text-[11px] text-slate-500 mt-1">
                      Cette liste contient l'ensemble des professions de l'Annexe 8 (Techniciens) ou 10 (Artistes) et leur Code Emploi. Si une profession n'apparaît pas, il n'est pas possible de réaliser un CDDU pour ce contrat.
                    </p>
                  </div>
                )
              ) : (
                <>
                  <input
                    value={profession}
                    onChange={(e) => setProfession(e.target.value)}
                    placeholder="ex : Régisseur.se, …"
                    className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                  />
                  <p className="text-[11px] text-slate-500 mt-1">
                    Si une profession n’apparaît pas dans l’annexe, indique-la précisément (ex: « Régisseur.se plateau »).
                  </p>
                </>
              )
              )}
            </div>
          </FieldRow>
        </Section>

        {/* Période / volumes en mode CDDU, Contrat en mode RG */}
        <Section title={isRegimeRG ? "Contrat" : "Période et volumes"}>
          {isRegimeRG ? (
            // Contenu pour Régime Général
            <>
              <FieldRow>
                <div>
                  <Label required>Type de contrat</Label>
                  <select
                    value={typeContratRG}
                    onChange={(e) => setTypeContratRG(e.target.value as any)}
                    className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                  >
                    <option>CDD de droit commun</option>
                    <option>CDI</option>
                    <option>Stage</option>
                    <option>Contrat de professionnalisation</option>
                    <option>Contrat d'apprentissage</option>
                    <option>Autre</option>
                  </select>
                </div>
              </FieldRow>

              {/* Motif CDD si CDD sélectionné */}
              {typeContratRG === "CDD de droit commun" && (
                <FieldRow>
                  <div>
                    <Label required>Motif du CDD</Label>
                    <select
                      value={motifCDD}
                      onChange={(e) => setMotifCDD(e.target.value as any)}
                      className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                    >
                      <option>Remplacement d'une absence</option>
                      <option>Accroissement temporaire d'activité</option>
                    </select>
                  </div>
                </FieldRow>
              )}

              {/* Champs conditionnels selon le motif CDD */}
              {typeContratRG === "CDD de droit commun" && motifCDD === "Remplacement d'une absence" && (
                <FieldRow>
                  <div>
                    <Label required>Nom de la personne remplacée</Label>
                    <input
                      value={nomPersonneRemplacee}
                      onChange={(e) => setNomPersonneRemplacee(e.target.value)}
                      placeholder="Nom et prénom de la personne remplacée"
                      className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                    />
                  </div>
                  <div>
                    <Label required>Situation de la personne remplacée</Label>
                    <select
                      value={situationPersonneRemplacee}
                      onChange={(e) => setSituationPersonneRemplacee(e.target.value as any)}
                      className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                    >
                      <option>Absent temporairement ou contrat suspendu (maladie, maternité, congés payés, congé parental, etc...)</option>
                      <option>Salarié provisoirement à temps partiel (congé parental, congé création d'entreprise, etc...)</option>
                      <option>Salarié ayant quitté définitivement l'entreprise, poste en attente de suppression</option>
                      <option>Remplacement du chef d'entreprise</option>
                    </select>
                  </div>
                </FieldRow>
              )}

              {typeContratRG === "CDD de droit commun" && motifCDD === "Accroissement temporaire d'activité" && (
                <FieldRow>
                  <div>
                    <Label required>Décrivez le motif de l'accroissement d'activité</Label>
                    <textarea
                      value={motifAccroissement}
                      onChange={(e) => setMotifAccroissement(e.target.value)}
                      placeholder="Détaillez les raisons de l'accroissement temporaire d'activité..."
                      rows={3}
                      className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                    />
                  </div>
                </FieldRow>
              )}
            </>
          ) : (
            // Contenu pour CDDU (existant)
            <>
          <FieldRow>
            <div>
              <Label required>Le contrat est-il multi-mois ?</Label>
              <div className="flex items-center gap-6 mt-2">
                <label className="inline-flex items-center gap-2 text-sm">
                  <input type="radio" checked={isMultiMois === "Oui"} onChange={() => setIsMultiMois("Oui")} />
                  Oui
                </label>
                <label className="inline-flex items-center gap-2 text-sm">
                  <input type="radio" checked={isMultiMois === "Non"} onChange={() => setIsMultiMois("Non")} />
                  Non
                </label>
              </div>
            </div>
          </FieldRow>
            </>
          )}

          <FieldRow>
            <div>
              <Label required>Date de début du contrat</Label>
              <input
                type="date"
                value={dateDebut}
                onChange={(e) => {
                  const v = e.target.value;
                  setDateDebut(v);
                  setConfirmPastStart(false);
                  if (dateFin && v && dateFin < v) setDateFin(v);
                }}
                className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
              />
            </div>
            {/* Masquer la date de fin si CDI en mode RG */}
            {!(isRegimeRG && typeContratRG === "CDI") && (
              <div>
                <Label>Date de fin du contrat</Label>
                <input
                  type="date"
                  value={dateFin}
                  min={dateDebut || undefined}
                  onChange={(e) => setDateFin(e.target.value)}
                  className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                />
                <p className="text-[11px] text-slate-500 mt-1">Pour un contrat d'une journée, sélectionnez la même date que début.</p>
              </div>
            )}
          </FieldRow>

          {/* Sections spécifiques aux CDDU - masquées en mode RG */}
          {!isRegimeRG && (
            !useHeuresMode ? (
              <>
                <FieldRow>
                  <div>
                    <Label>Combien de représentations ?</Label>
                    <input
                      type="number"
                      min={0}
                      value={nbRep}
                      onChange={(e) => setNbRep(e.target.value === "" ? "" : Number(e.target.value))}
                      className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                    />
                  </div>
                  <div>
                    <Label>Combien de services de répétition ?</Label>
                    <input
                      type="number"
                      min={0}
                      value={nbServ}
                      onChange={(e) => setNbServ(e.target.value === "" ? "" : Number(e.target.value))}
                      className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                    />
                  </div>
                </FieldRow>

                <FieldRow>
                  <div>
                    <Label>Indiquez les dates de représentations</Label>
                    <input
                      value={datesRep}
                      onChange={(e) => setDatesRep(e.target.value)}
                      placeholder="ex : 12/10, 13/10, 24/10"
                      className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                    />
                  </div>
                  <div>
                    <Label>Indiquez les dates de répétitions</Label>
                    <input
                      value={datesServ}
                      onChange={(e) => setDatesServ(e.target.value)}
                      placeholder="ex : 10/10, 11/10"
                      className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                    />
                  </div>
                </FieldRow>
              </>
            ) : (
              <>
                <FieldRow>
                  <div>
                    <Label required>Combien d'heures de travail au total ?</Label>
                    <div className="flex items-center gap-2">
                      <input
                        type="number"
                        min={0}
                        value={heuresTotal}
                        onChange={(e) => setHeuresTotal(e.target.value === "" ? "" : Number(e.target.value))}
                        placeholder="ex : 3"
                        className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                      />
                      <select
                        value={minutesTotal}
                        onChange={(e) => setMinutesTotal(e.target.value as "0" | "30")}
                        className="px-3 py-2 rounded-lg border bg-white text-sm"
                        aria-label="Minutes"
                      >
                        <option value="0">+ 00 min</option>
                        <option value="30">+ 30 min</option>
                      </select>
                    </div>
                    <p className="text-[11px] text-slate-500 mt-1">
                      Utilisez le menu pour ajouter 30 minutes (ex. 3 h 30).
                    </p>
                  </div>

                  <div>
                    <Label>Indiquez les jours de travail</Label>
                    <input
                      value={joursTravail}
                      onChange={(e) => setJoursTravail(e.target.value)}
                      placeholder="ex : 12/10, 13/10, 24/10"
                      className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                    />
                    <p className="text-[11px] text-slate-500 mt-1">Listez les jours travaillés séparés par des virgules.</p>
                  </div>
                </FieldRow>
              </>
            )
          )}
        </Section>

        {isPastStart && (
          <div className="rounded-2xl border border-amber-300 bg-amber-50 text-amber-950 p-4">
            <div className="text-lg font-semibold flex items-center gap-2">
              <span className="inline-block text-amber-600">⚠️</span>
              Attention
            </div>

            <div className="mt-3 space-y-3 text-sm leading-relaxed">
              <p>Vous avez saisi une date de démarrage du contrat dans le passé.</p>
              <p>
                Si vous validez la demande avec cette date, nous effectuerons la DPAE dans les 24 heures ouvrées, mais veuillez noter que
                nous recevrons une alerte de l'URSSAF.
              </p>
              <p>
                En effet, conformément aux articles L1221-10 à L1221-12-1 du Code du travail, la <strong>Déclaration Préalable à l'Embauche</strong> est
                obligatoire et doit être effectuée dans les <strong>7 jours qui précèdent</strong> le commencement du contrat. Tout manquement peut être
                sanctionné administrativement d'une pénalité de 300 fois le taux horaire du minimum garanti, soit en 2025, de <strong>1266€ par DPAE
                manquante</strong>.
              </p>
              <p>Nous vous recommandons donc vivement d'anticiper vos demandes de contrats.</p>
            </div>

            <label className="mt-4 flex items-start gap-2 text-sm">
              <input
                type="checkbox"
                checked={confirmPastStart}
                onChange={(e) => setConfirmPastStart(e.target.checked)}
                className="mt-1"
              />
              <span>
                J'ai lu et compris l'alerte ci-dessus et valide la date de début de contrat au <strong>{formatFr(dateDebut)}</strong>.
              </span>
            </label>
          </div>
        )}

        {/* Rémunération */}
        <Section title="Rémunération">
          <FieldRow>
            <div>
              <Label required>Type de salaire</Label>
              <select
                value={typeSalaire}
                onChange={(e) => {
                  const v = e.target.value as typeof typeSalaire;
                  setTypeSalaire(v);
                  if (v === "Minimum conventionnel") setMontantSalaire("");
                }}
                className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
              >
                <option value="Brut">Brut</option>
                <option value="Net avant PAS">Net avant PAS</option>
                <option value="Coût total employeur">Coût total employeur</option>
                <option value="Minimum conventionnel">Minimum conventionnel</option>
              </select>

              {typeSalaire !== "Minimum conventionnel" && (
                <div className="mt-2">
                  <Label required>Montant</Label>
                  <div className="flex items-center gap-2">
                    <input
                      type="number"
                      min={0}
                      step="0.01"
                      value={montantSalaire}
                      onChange={(e) => setMontantSalaire(e.target.value === "" ? "" : Number(e.target.value))}
                      placeholder="ex : 250,00"
                      className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                    />
                    <span className="text-sm text-slate-600">€</span>
                  </div>
                  <p className="text-[11px] text-slate-500 mt-1">
                    Saisissez le montant en euros correspondant au type sélectionné.
                  </p>
                </div>
              )}
            </div>
            <div>
              <Label required>Panier(s) repas</Label>
              <div className="flex items-center gap-6 mt-2">
                <label className="inline-flex items-center gap-2 text-sm">
                  <input type="radio" checked={panierRepas === "Oui"} onChange={() => setPanierRepas("Oui")} />
                  Oui
                </label>
                <label className="inline-flex items-center gap-2 text-sm">
                  <input type="radio" checked={panierRepas === "Non"} onChange={() => setPanierRepas("Non")} />
                  Non
                </label>
              </div>
            </div>
          </FieldRow>
        </Section>

        {/* Autres infos */}
        <Section title="Autres informations">
          <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
            {/* Colonne gauche: champs du formulaire */}
            <div className="space-y-4">
              <div>
                <Label>Notes</Label>
                <textarea
                  rows={4}
                  value={notes}
                  onChange={(e) => setNotes(e.target.value)}
                  className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                />
                <p className="text-[11px] text-slate-500 mt-1">Utilisez ce champ pour toute info complémentaire.</p>
              </div>

              <div>
                <Label>Envoi de fichiers (20 Mo max / fichier)</Label>
                <div className="flex items-center gap-3">
                  <label className="inline-flex items-center gap-2 px-3 py-2 rounded-lg border cursor-pointer">
                    <Upload className="w-4 h-4" />
                    <span className="text-sm">Choisir un ou des fichiers</span>
                    <input type="file" multiple className="hidden" onChange={(e) => onFilesSelected(e.target.files)} />
                  </label>
                  {fichiers.length > 0 && (
                    <div className="text-xs text-slate-600">
                      {fichiers.length} fichier{fichiers.length > 1 ? "s" : ""} sélectionné{fichiers.length > 1 ? "s" : ""}
                    </div>
                  )}
                </div>
              </div>

              <div>
                <Label required>Voulez-vous directement valider cette demande ?</Label>
                <div className="flex items-center gap-6 mt-2">
                  <label className="inline-flex items-center gap-2 text-sm">
                    <input type="radio" checked={validerDirect === "Oui"} onChange={() => setValiderDirect("Oui")} />
                    Oui
                  </label>
                  <label className="inline-flex items-center gap-2 text-sm">
                    <input type="radio" checked={validerDirect === "Non"} onChange={() => setValiderDirect("Non")} />
                    Non
                  </label>
                </div>
                <p className="text-[11px] text-slate-500 mt-1">
                  Si vous choisissez “Non”, la demande sera enregistrée en brouillon. Vous devrez la valider ultérieurement pour que nous puissions la traiter.
                </p>
              </div>
            </div>

            {/* Colonne droite: Notes du contrat (mode édition uniquement) */}
            <div>
              {contractIdForNotes ? (
                <NotesSection contractId={contractIdForNotes} title="Notes du contrat" showAddButton={false} compact />
              ) : null}
            </div>
          </div>
        </Section>

        {/* Actions */}
        <div className="flex items-center justify-end gap-3">
          {err && <div className="text-sm text-rose-600 mr-auto">{err}</div>}
          <button
            type="button"
            onClick={() => router.push("/contrats")}
            className="px-4 py-2 rounded-lg border"
            disabled={loading}
          >
            Revenir sans envoyer
          </button>
          <button
            type="button"
            onClick={onSubmit}
            disabled={loading}
            className="px-4 py-2 rounded-lg bg-emerald-600 text-white hover:bg-emerald-700 disabled:opacity-50"
          >
            {loading ? (<><Loader2 className="w-4 h-4 inline animate-spin mr-2" /> Envoi…</>) : "Envoyer"}
          </button>
        </div>
      </div>

      {/* Overlays */}
      {prefillLoading && (
        <div className="fixed inset-0 z-[55] flex items-center justify-center bg-white/70">
          <div className="rounded-2xl border bg-white p-6 text-center shadow-xl">
            <Loader2 className="w-6 h-6 animate-spin mx-auto mb-3" />
            <div className="font-medium">Pré-remplissage en cours…</div>
            <p className="text-sm text-slate-600 mt-1">Merci de patienter pendant que nous chargeons les informations du contrat.</p>
          </div>
        </div>
      )}
      {redirecting && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-white/70">
          <div className="rounded-2xl border bg-white p-6 text-center shadow-xl">
            <Loader2 className="w-6 h-6 animate-spin mx-auto mb-3" />
            <div className="font-medium">Envoi réussi</div>
            <p className="text-sm text-slate-600 mt-1">Redirection dans quelques secondes…</p>
          </div>
        </div>
      )}

      {showLeaveConfirm && (
        <div className="fixed inset-0 z-[60] flex items-center justify-center bg-black/40">
          <div className="w-full max-w-md rounded-2xl border bg-white p-5 shadow-xl">
            <div className="text-base font-semibold">Quitter cette page ?</div>
            <p className="text-sm text-slate-600 mt-2">
              Vous avez une saisie en cours. En quittant maintenant, vous perdrez les informations non envoyées.
            </p>
            <div className="mt-4 flex items-center justify-end gap-2">
              <button onClick={cancelLeave} className="px-3 py-2 rounded-lg border">Rester</button>
              <button onClick={confirmLeave} className="px-3 py-2 rounded-lg bg-rose-600 text-white hover:bg-rose-700">Quitter sans enregistrer</button>
            </div>
          </div>
        </div>
      )}

      {newSalarieOpen && (
        <div className="fixed inset-0 z-[70] flex items-center justify-center">
          <div className="absolute inset-0 bg-black/40" />
          <div className="relative w-[96vw] max-w-3xl h-[90vh] rounded-2xl overflow-hidden shadow-2xl border border-slate-200 bg-white flex flex-col">
            <div className="px-5 py-3 bg-gradient-to-r from-emerald-600 to-teal-600 text-white flex items-center justify-between">
              <div className="text-lg font-semibold truncate">Créer un nouveau salarié</div>
              <button
                type="button"
                onClick={() => setNewSalarieOpen(false)}
                className="px-3 py-1.5 rounded-lg bg-white/10 hover:bg-white/20 text-white text-sm"
              >
                Fermer
              </button>
            </div>
            <div className="flex-1 overflow-y-auto">
              <iframe
                src={NEW_SALARIE_PATH}
                className="w-full h-full min-h-[600px] border-0 bg-white"
                title="Nouveau salarié"
              />
            </div>
          </div>
        </div>
      )}
    </>
  );
}
