"use client";

import { useState, useMemo, useEffect, useRef, useCallback } from "react";
import { useRouter } from "next/navigation";
import { useQuery } from "@tanstack/react-query";
import { usePostHog } from "posthog-js/react";
import { api } from "@/lib/fetcher";
import { Loader2, Search, Info, Calculator as CalculatorIcon, ExternalLink } from "lucide-react";
import { NotesSection } from "@/components/NotesSection";
import { PROFESSIONS_ARTISTE } from "@/components/constants/ProfessionsArtiste";
import { useDemoMode } from "@/hooks/useDemoMode";
import Calculator from "@/components/Calculator";
import DatePickerCalendar from "@/components/DatePickerCalendar";
import DatesQuantityModal from "@/components/DatesQuantityModal";
import { parseDateString, parseFrenchedDate, generateDateRange, formatDateFr } from "@/lib/dateFormatter";
import { Tooltip } from "@/components/ui/tooltip";

/* =========================
   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();
}

/**
 * Parse une chaîne formatée (ex: "1 représentation par jour du 24/11 au 26/11 ; 2 représentations le 28/11.")
 * et extrait toutes les dates individuelles avec leurs quantités.
 * 
 * @param dateStr - Chaîne formatée avec dates et quantités
 * @param yearContext - Contexte de l'année (ex: "2025-11-01")
 * @returns Array de {date: "DD/MM", quantity: number, key: string} 
 */
function parseFormattedDatesWithQuantities(
  dateStr: string,
  yearContext: string,
  prefix: "rep" | "serv" | "jour"
): Array<{ date: string; quantity: number; index: number; key: string }> {
  if (!dateStr || !dateStr.trim()) return [];
  
  const result: Array<{ date: string; quantity: number; index: number; key: string }> = [];
  const groups = dateStr.split(" ; ");
  
  groups.forEach((group, groupIdx) => {
    // Extraire la quantité (ex: "1 représentation", "2 services")
    const qtyMatch = group.match(/^(\d+)\s+/);
    const quantity = qtyMatch ? parseInt(qtyMatch[1]) : 1;
    
    // Vérifier si c'est une plage (contient "du ... au ...")
    const rangeMatch = group.match(/du\s+(\d{2}\/\d{2})\s+au\s+(\d{2}\/\d{2})/);
    if (rangeMatch) {
      // C'est une plage : générer toutes les dates intermédiaires
      const startFr = rangeMatch[1];
      const endFr = rangeMatch[2];
      
      // Convertir en ISO
      const startIso = parseFrenchedDate(startFr, yearContext);
      const endIso = parseFrenchedDate(endFr, yearContext);
      
      // Générer toutes les dates de la plage
      const allDatesIso = generateDateRange(startIso, endIso);
      
      // Ajouter chaque date avec sa quantité
      allDatesIso.forEach((iso, dateIdx) => {
        const dateFr = formatDateFr(iso);
        result.push({
          date: dateFr,
          quantity: quantity,
          index: dateIdx,
          key: `${prefix}_${groupIdx}_${dateIdx}`
        });
      });
    } else {
      // Date isolée (ex: "le 28/11")
      const dateMatch = group.match(/(\d{2}\/\d{2})/);
      if (dateMatch) {
        result.push({
          date: dateMatch[1],
          quantity: quantity,
          index: 0,
          key: `${prefix}_${groupIdx}_0`
        });
      }
    }
  });
  
  return result;
}

/**
 * Extrait uniquement les dates (format DD/MM) d'une chaîne formatée PDFMonkey
 * Utile pour initialDates des modales de calendrier
 * 
 * @param dateStr - Chaîne formatée (ex: "1 représentation par jour du 24/11 au 26/11 ; 2 représentations le 28/11.")
 * @param yearContext - Contexte de l'année (ex: "2025-11-01")
 * @returns Array de dates au format "DD/MM"
 */
function extractDatesFromFormatted(dateStr: string, yearContext: string): string[] {
  if (!dateStr || !dateStr.trim()) return [];
  
  const dates: string[] = [];
  const groups = dateStr.split(" ; ");
  
  groups.forEach((group) => {
    // Vérifier si c'est une plage (contient "du ... au ...")
    const rangeMatch = group.match(/du\s+(\d{2}\/\d{2})\s+au\s+(\d{2}\/\d{2})/);
    if (rangeMatch) {
      // C'est une plage : générer toutes les dates intermédiaires
      const startFr = rangeMatch[1];
      const endFr = rangeMatch[2];
      
      // Convertir en ISO
      const startIso = parseFrenchedDate(startFr, yearContext);
      const endIso = parseFrenchedDate(endFr, yearContext);
      
      // Générer toutes les dates de la plage
      const allDatesIso = generateDateRange(startIso, endIso);
      
      // Convertir en format DD/MM
      allDatesIso.forEach((iso) => {
        dates.push(formatDateFr(iso));
      });
    } else {
      // Date isolée (ex: "le 28/11")
      const dateMatch = group.match(/(\d{2}\/\d{2})/);
      if (dateMatch) {
        dates.push(dateMatch[1]);
      }
    }
  });
  
  return dates;
}

// 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;
      // Autoriser les liens qui ouvrent dans un nouvel onglet
      if (a.target === "_blank") 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: (!!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: !!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();
  const posthog = usePostHog();
  const { isDemoMode } = useDemoMode();

  // --- 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 [manualDatesMode, setManualDatesMode] = useState(false); // Mode manuel pour les dates
  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 [nbRepMetteur, setNbRepMetteur] = useState<number | "">("");  // Cachets pour metteur en scène
  const [durationServices, setDurationServices] = useState<"3" | "4">("4"); // Durée des services (3 ou 4 heures)
  const [datesRep, setDatesRep] = useState("");
  const [datesRepDisplay, setDatesRepDisplay] = useState("");
  const [datesRepOpen, setDatesRepOpen] = useState(false);
  
  const [datesServ, setDatesServ] = useState("");
  const [datesServDisplay, setDatesServDisplay] = useState("");
  const [datesServOpen, setDatesServOpen] = useState(false);
  
  const [joursTravailDisplay, setJoursTravailDisplay] = useState("");
  const [joursTravailOpen, setJoursTravailOpen] = useState(false);
  const [joursTravailRaw, setJoursTravailRaw] = useState<string[]>([]); // Format input ["12/10", "13/10"]
  
  // États pour les modales de quantités après sélection des dates
  const [quantityModalOpen, setQuantityModalOpen] = useState(false);
  const [quantityModalType, setQuantityModalType] = useState<"representations" | "repetitions" | "jours_travail">("representations");
  const [pendingDates, setPendingDates] = useState<string[]>([]);
  
  const [typeSalaire, setTypeSalaire] = useState<"Brut" | "Net avant PAS" | "Coût total employeur" | "Minimum conventionnel">("Brut");
  const [montantSalaire, setMontantSalaire] = useState<number | "">("");
  // Indique si la valeur vient de la calculatrice pour forcer l'affichage en 2 décimales
  const [montantFromCalculator, setMontantFromCalculator] = useState<boolean>(false);
  const [panierRepas, setPanierRepas] = useState<"Oui" | "Non">("Non");
  const [nombrePaniersRepas, setNombrePaniersRepas] = useState<number | "">("");
  const [panierRepasCCN, setPanierRepasCCN] = useState<"Oui" | "Non">("Oui");
  const [montantParPanier, setMontantParPanier] = useState<number | "">("");
  
  // Mode de saisie du salaire : "global" ou "par_date"
  const [salaryMode, setSalaryMode] = useState<"global" | "par_date">("global");
  // Salaires par date : Record<dateISO, montant>
  const [salariesByDate, setSalariesByDate] = useState<Record<string, number | "">>({});
  
  const [notes, setNotes] = useState(""); 
  const [validerDirect, setValiderDirect] = useState<"Oui" | "Non">("Oui");
  // Confirmation e-mail à la création
  const [emailConfirm, setEmailConfirm] = useState<"Oui" | "Non">("Oui");
  
  // Calculatrice
  const [isCalculatorOpen, setIsCalculatorOpen] = useState(false);
  
  // É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() !== "" || 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, isMultiMois,
    isRegimeRG, typeContratRG, motifCDD, nomPersonneRemplacee, situationPersonneRemplacee, motifAccroissement,
  ]);

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

  // Handlers pour les calendriers de dates
  // Au lieu d'appliquer directement, on ouvre la modale de quantités
  const handleDatesRepApply = (result: {
    selectedDates: string[];
    hasMultiMonth: boolean;
    pdfFormatted: string;
  }) => {
    setPendingDates(result.selectedDates);
    setQuantityModalType("representations");
    setQuantityModalOpen(true);
    if (result.hasMultiMonth) {
      setIsMultiMois("Oui");
    }
  };

  const handleDatesServApply = (result: {
    selectedDates: string[];
    hasMultiMonth: boolean;
    pdfFormatted: string;
  }) => {
    setPendingDates(result.selectedDates);
    setQuantityModalType("repetitions");
    setQuantityModalOpen(true);
    if (result.hasMultiMonth) {
      setIsMultiMois("Oui");
    }
  };

  const handleJoursTravailApply = (result: {
    selectedDates: string[];
    hasMultiMonth: boolean;
    pdfFormatted: string;
  }) => {
    setPendingDates(result.selectedDates);
    setQuantityModalType("jours_travail");
    setQuantityModalOpen(true);
    setIsMultiMois(result.hasMultiMonth ? "Oui" : "Non");
  };

  // Handler pour la modale de quantités (applique les données finales)
  const handleQuantityApply = (result: {
    selectedDates: string[];
    hasMultiMonth: boolean;
    pdfFormatted: string;
    globalQuantity?: number;
    globalDuration?: "3" | "4";
    totalHours?: number;
    totalQuantities?: number;
  }) => {
    // Si un nombre global est fourni, l'utiliser; sinon utiliser la somme des quantités; sinon calculer le nombre de dates
    const quantity = result.globalQuantity || result.totalQuantities || result.selectedDates.length;
    
    // Convertir les dates sélectionnées en ISO (result.selectedDates sont au format "12/10, 13/10...")
    const currentYearContext = dateDebut || new Date().toISOString().slice(0, 10);
    const currentIsos = result.selectedDates
      .map(d => parseFrenchedDate(d.trim(), currentYearContext))
      .filter(iso => iso && iso.length === 10);
    
    // Récupérer toutes les dates ISO existantes selon le type
    let allIsos: string[] = [];
    
    if (quantityModalType === "representations") {
      // Ajouter les nouvelles représentations
      allIsos.push(...currentIsos);
      // Ajouter les répétitions existantes
      if (datesServ) {
        const servIsos = datesServ.split(/[;,]/)
          .map(d => parseFrenchedDate(d.trim().replace(/^(le|du|au)\s+/i, '').replace(/\.$/, ''), currentYearContext))
          .filter(iso => iso && iso.length === 10);
        allIsos.push(...servIsos);
      }
      // Ajouter les jours de travail existants
      if (joursTravail) {
        const jtIsos = joursTravail.split(/[;,]/)
          .map(d => parseFrenchedDate(d.trim().replace(/^(le|du|au)\s+/i, '').replace(/\.$/, ''), currentYearContext))
          .filter(iso => iso && iso.length === 10);
        allIsos.push(...jtIsos);
      }
    } else if (quantityModalType === "repetitions") {
      // Ajouter les représentations existantes
      if (datesRep) {
        const repIsos = datesRep.split(/[;,]/)
          .map(d => parseFrenchedDate(d.trim().replace(/^(le|du|au)\s+/i, '').replace(/\.$/, ''), currentYearContext))
          .filter(iso => iso && iso.length === 10);
        allIsos.push(...repIsos);
      }
      // Ajouter les nouvelles répétitions
      allIsos.push(...currentIsos);
      // Ajouter les jours de travail existants
      if (joursTravail) {
        const jtIsos = joursTravail.split(/[;,]/)
          .map(d => parseFrenchedDate(d.trim().replace(/^(le|du|au)\s+/i, '').replace(/\.$/, ''), currentYearContext))
          .filter(iso => iso && iso.length === 10);
        allIsos.push(...jtIsos);
      }
    } else if (quantityModalType === "jours_travail") {
      // Ajouter les représentations existantes
      if (datesRep) {
        const repIsos = datesRep.split(/[;,]/)
          .map(d => parseFrenchedDate(d.trim().replace(/^(le|du|au)\s+/i, '').replace(/\.$/, ''), currentYearContext))
          .filter(iso => iso && iso.length === 10);
        allIsos.push(...repIsos);
      }
      // Ajouter les répétitions existantes
      if (datesServ) {
        const servIsos = datesServ.split(/[;,]/)
          .map(d => parseFrenchedDate(d.trim().replace(/^(le|du|au)\s+/i, '').replace(/\.$/, ''), currentYearContext))
          .filter(iso => iso && iso.length === 10);
        allIsos.push(...servIsos);
      }
      // Ajouter les nouveaux jours de travail
      allIsos.push(...currentIsos);
    }
    
    // Trier et dédupliquer
    const isos = [...new Set(allIsos)].sort();
    
    // Calculer les dates min/max et multi-mois
    let newDateDebut = dateDebut;
    let newDateFin = dateFin;
    let newIsMultiMois = isMultiMois;
    
    if (isos.length > 0) {
      newDateDebut = isos[0];
      newDateFin = isos[isos.length - 1];
      
      // Déterminer multi-mois
      const hasMultiMonth = isos.some((iso, idx) => {
        if (idx === 0) return false;
        const prevMonth = isos[0].slice(0, 7);
        const currMonth = iso.slice(0, 7);
        return currMonth !== prevMonth;
      });
      
      newIsMultiMois = hasMultiMonth ? "Oui" : "Non";
    }
    
    // Maintenant faire tous les setState
    switch (quantityModalType) {
      case "representations":
        setDatesRep(result.pdfFormatted);
        setDatesRepDisplay(result.pdfFormatted);
        setNbRep(quantity);
        break;
      case "repetitions":
        setDatesServ(result.pdfFormatted);
        setDatesServDisplay(result.pdfFormatted);
        setNbServ(quantity);
        if (result.globalDuration) {
          setDurationServices(result.globalDuration);
        }
        break;
      case "jours_travail":
        setJoursTravail(result.pdfFormatted);
        setJoursTravailDisplay(result.pdfFormatted);
        setJoursTravailRaw(result.selectedDates); // Stocker les dates au format input
        
        // Mettre à jour le total d'heures depuis la modale
        // Si totalHours est fourni (heures par jour), on l'utilise
        // Sinon si globalQuantity est fourni (mode "Ne pas appliquer d'heures par jour"), on l'utilise
        const hoursToSet = result.totalHours ?? result.globalQuantity;
        
        if (hoursToSet !== undefined) {
          const hours = Math.floor(hoursToSet);
          const remainder = hoursToSet - hours;
          setHeuresTotal(hours);
          // Si on a une demi-heure, on met 30 minutes
          if (remainder >= 0.5) {
            setMinutesTotal("30");
          } else {
            setMinutesTotal("0");
          }
        }
        break;
    }
    
    // Mettre à jour les dates et multi-mois seulement si on n'est pas en mode manuel ET pas en mode RG
    if (!manualDatesMode && !isRegimeRG) {
      setDateDebut(newDateDebut);
      setDateFin(newDateFin);
      setIsMultiMois(newIsMultiMois);
    }
    
    setQuantityModalOpen(false);
    setPendingDates([]);
  };

  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 ?? "");
    
    // Initialiser les dates avec formatage smart
    if (prefill.dates_representations) {
      const dateStr = String(prefill.dates_representations);
      const yearContext = prefill.date_debut || new Date().toISOString().slice(0, 10);
      const parsed = parseDateString(dateStr, yearContext);
      setDatesRep(dateStr);
      setDatesRepDisplay(parsed.pdfFormatted);
    }
    
    if (prefill.dates_repetitions) {
      const dateStr = String(prefill.dates_repetitions);
      const yearContext = prefill.date_debut || new Date().toISOString().slice(0, 10);
      const parsed = parseDateString(dateStr, yearContext);
      setDatesServ(dateStr);
      setDatesServDisplay(parsed.pdfFormatted);
    }
    
    setHeuresTotal(prefill.heures_total ?? "");
    setMinutesTotal(prefill.minutes_total ?? "0");
    
    if (prefill.jours_travail) {
      const dateStr = String(prefill.jours_travail);
      const yearContext = prefill.date_debut || new Date().toISOString().slice(0, 10);
      const parsed = parseDateString(dateStr, yearContext);
      setJoursTravail(dateStr);
      setJoursTravailDisplay(parsed.pdfFormatted);
      // Extraire les dates au format input pour initialDates
      setJoursTravailRaw(parsed.allDatesFr);
    }
    
    if (typeof prefill.multi_mois === "boolean") setIsMultiMois(prefill.multi_mois ? "Oui" : "Non");
    setTypeSalaire(prefill.type_salaire ?? "Brut");
  setMontantSalaire(prefill.montant ?? "");
  setMontantFromCalculator(false);
    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));
        setDatesRepDisplay(String(payload.dates_representations));
      }
      if (payload.dates_repetitions) {
        setDatesServ(String(payload.dates_repetitions));
        setDatesServDisplay(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);
        setMontantFromCalculator(false);
      }
      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 - Ne pas pré-remplir automatiquement en mode RG
  if (!isRegimeRG && !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 (!isRegimeRG && !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);
      setDatesRepDisplay(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);
      setDatesServDisplay(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);
      setMontantFromCalculator(false);
      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]);

  // Générer automatiquement une note système pour les paniers repas
  const panierRepasNote = useMemo(() => {
    if (panierRepas !== "Oui") return "";
    
    const details: string[] = [];
    
    // Nombre de paniers
    if (nombrePaniersRepas !== "" && nombrePaniersRepas > 0) {
      details.push(`Nombre : ${nombrePaniersRepas} panier${nombrePaniersRepas > 1 ? "s" : ""}`);
    }
    
    // Type de panier (CCN ou montant personnalisé)
    if (panierRepasCCN === "Oui") {
      details.push("Type : Au minima CCN");
    } else if (panierRepasCCN === "Non" && montantParPanier !== "" && montantParPanier > 0) {
      details.push(`Type : Montant personnalisé (${EURO.format(Number(montantParPanier))} / panier)`);
    }
    
    if (details.length === 0) return "";
    
    return `Panier(s) repas demandé(s)\n${details.join(" • ")}`;
  }, [panierRepas, nombrePaniersRepas, panierRepasCCN, montantParPanier]);

  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);
    }
  }

  // Upload de fichiers supprimé

  // Fonction de conversion des salaires par date en JSONB
  function convertSalariesByDateToJSON(): any {
    console.log("🔍 [convertSalariesByDateToJSON] Début de la conversion");
    console.log("🔍 salaryMode:", salaryMode);
    console.log("🔍 salariesByDate:", salariesByDate);
    console.log("🔍 datesRep:", datesRep);
    console.log("🔍 datesServ:", datesServ);
    console.log("🔍 joursTravail:", joursTravail);
    
    if (salaryMode !== "par_date") {
      console.log("❌ salaryMode n'est pas 'par_date', retour null");
      return null;
    }

    const representations: any[] = [];
    const repetitions: any[] = [];
    const jours_travail: any[] = [];
    
    const yearContext = dateDebut || new Date().toISOString().slice(0, 10);

    // Parser les représentations
    if (datesRep && datesRep.length > 0) {
      const allRepDates = parseFormattedDatesWithQuantities(datesRep, yearContext, "rep");
      
      allRepDates.forEach((dateInfo) => {
        const items: any[] = [];
        for (let i = 0; i < dateInfo.quantity; i++) {
          const key = `${dateInfo.key}_${i}`;
          const montant = salariesByDate[key];
          if (montant && typeof montant === "number") {
            items.push({
              numero: i + 1,
              montant: montant,
            });
          }
        }
        if (items.length > 0) {
          representations.push({
            date: dateInfo.date,
            items: items,
          });
        }
      });
    }

    // Parser les répétitions
    if (datesServ && datesServ.length > 0) {
      const allServDates = parseFormattedDatesWithQuantities(datesServ, yearContext, "serv");
      
      allServDates.forEach((dateInfo) => {
        const items: any[] = [];
        for (let i = 0; i < dateInfo.quantity; i++) {
          const key = `${dateInfo.key}_${i}`;
          const montant = salariesByDate[key];
          if (montant && typeof montant === "number") {
            items.push({
              numero: i + 1,
              montant: montant,
              duree_heures: parseInt(durationServices) || 4,
            });
          }
        }
        if (items.length > 0) {
          repetitions.push({
            date: dateInfo.date,
            items: items,
          });
        }
      });
    }

    // Parser les jours travaillés
    if (joursTravail && joursTravail.length > 0) {
      const allJoursDates = parseFormattedDatesWithQuantities(joursTravail, yearContext, "jour");
      
      allJoursDates.forEach((dateInfo) => {
        const key = `${dateInfo.key}_0`;
        const montant = salariesByDate[key];
        if (montant && typeof montant === "number") {
          jours_travail.push({
            date: dateInfo.date,
            montant: montant,
            heures: dateInfo.quantity, // La quantité représente les heures pour les jours travaillés
          });
        }
      });
    }

    // Calculer le total
    const total_calcule = Object.values(salariesByDate).reduce((sum: number, val) => {
      return sum + (typeof val === "number" ? val : 0);
    }, 0);

    const result = {
      mode: "par_date",
      type_salaire: typeSalaire,
      representations: representations,
      repetitions: repetitions,
      jours_travail: jours_travail,
      total_calcule: total_calcule,
    };

    console.log("✅ [convertSalariesByDateToJSON] Résultat:", result);
    return result;
  }

  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é.");

    // Validation du salaire selon le mode
    if (salaryMode === "par_date") {
      // En mode par date, vérifier qu'au moins un montant a été saisi
      const hasAtLeastOneAmount = Object.values(salariesByDate).some(val => typeof val === "number" && val > 0);
      if (!hasAtLeastOneAmount) {
        return setErr("Veuillez saisir au moins un montant de salaire pour les dates.");
      }
    } else {
      // En mode global
      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 ? (useHeuresMode && professionPick?.code === "MET040" ? nbRepMetteur : 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 : (!isRegimeRG && typeof nbServ === "number" && nbServ > 0 ? nbServ * parseInt(durationServices) : undefined),
      minutes_travail: !isRegimeRG && useHeuresMode ? minutesTotal : undefined,
      jours_travail: !isRegimeRG && useHeuresMode ? (joursTravail || undefined) : undefined,
      jours_travail_non_artiste: !isRegimeRG && useHeuresMode && (categoriePro === "Technicien" || professionPick?.code === "MET040") ? (joursTravail || undefined) : undefined,
      type_salaire: typeSalaire,
      montant: salaryMode === "par_date" ? undefined : (typeSalaire !== "Minimum conventionnel" ? (montantSalaire === "" ? undefined : montantSalaire) : undefined),
      salaires_par_date: !isRegimeRG && salaryMode === "par_date" ? convertSalariesByDateToJSON() : undefined,
      panier_repas: panierRepas,
      nombre_paniers_repas: panierRepas === "Oui" && nombrePaniersRepas !== "" ? nombrePaniersRepas : undefined,
      panier_repas_ccn: panierRepas === "Oui" ? panierRepasCCN : undefined,
      si_non_montant_par_panier: panierRepas === "Oui" && panierRepasCCN === "Non" && montantParPanier !== "" ? montantParPanier : undefined,
      reference,
      notes: notes || undefined,
      panier_repas_note: panierRepasNote || undefined, // Note spécifique pour les paniers repas
      send_email_confirmation: emailConfirm === "Oui",
      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,
          // Préférence d'envoi d'e-mail de confirmation
          send_email_confirmation: emailConfirm === "Oui",
          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,
          panier_repas_note: payload.panier_repas_note, // Note spécifique paniers repas
          // 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,
            jours_travail_non_artiste: payload.jours_travail_non_artiste,
            multi_mois: payload.multi_mois,
            salaires_par_date: payload.salaires_par_date,
          }),
          
          // Champs paniers repas (communs aux deux régimes)
          nombre_paniers_repas: payload.nombre_paniers_repas,
          panier_repas_ccn: payload.panier_repas_ccn,
          si_non_montant_par_panier: payload.si_non_montant_par_panier,
        };

        console.log("🚀 [onSubmit] contractData envoyé à l'API:", contractData);
        console.log("🚀 [onSubmit] salaires_par_date dans contractData:", (contractData as any).salaires_par_date);

        // 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}`);
        }

        // 🎯 Tracker l'événement de création de contrat avec PostHog
        const result = await res.json().catch(() => ({}));
        posthog?.capture('contract_created', {
          contract_type: isRegimeRG ? 'RG' : 'CDDU',
          regime: isRegimeRG ? 'Régime Général' : payload.regime,
          multi_mois: payload.multi_mois,
          categorie_professionnelle: payload.categorie_professionnelle,
          contract_id: result?.contract?.id || result?.contract?.contract_number,
          has_notes: !!payload.notes,
          validation_immediate: payload.valider_direct,
        });
      }

      // 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">
              {isRegimeRG 
                ? "Ce formulaire est dédié aux contrats en régime général."
                : "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 (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…"
                          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 && (
                        <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 (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é…"
                      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 && (
                    <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)
            <>
          {/* Question multi-mois masquée - la logique reste active en arrière-plan */}
            </>
          )}

          {/* Sections spécifiques aux CDDU - masquées en mode RG */}
          {!isRegimeRG && (
            !useHeuresMode ? (
              <>
                <FieldRow>
                  <div>
                    <Label>Indiquez les dates de représentations</Label>
                    <div className="flex items-center gap-2">
                      <div 
                        onClick={() => setDatesRepOpen(true)}
                        className="flex-1 px-3 py-2 rounded-lg border bg-slate-50 text-sm text-slate-700 min-h-[42px] flex items-center cursor-pointer hover:bg-slate-100 transition"
                      >
                        {datesRepDisplay || "Cliquez pour sélectionner…"}
                      </div>
                      <button
                        type="button"
                        onClick={() => setDatesRepOpen(true)}
                        className="px-3 py-2 rounded-lg border bg-white text-sm hover:bg-slate-50 transition whitespace-nowrap"
                      >
                        Modifier
                      </button>
                      {datesRep && (
                        <button
                          type="button"
                          onClick={() => {
                            setDatesRep("");
                            setDatesRepDisplay("");
                          }}
                          className="px-3 py-2 rounded-lg border border-red-200 bg-white text-sm text-red-600 hover:bg-red-50 transition whitespace-nowrap"
                        >
                          Effacer
                        </button>
                      )}
                    </div>
                  </div>
                  <div>
                    <Label>Indiquez les dates de répétitions</Label>
                    <div className="flex items-center gap-2">
                      <div 
                        onClick={() => setDatesServOpen(true)}
                        className="flex-1 px-3 py-2 rounded-lg border bg-slate-50 text-sm text-slate-700 min-h-[42px] flex items-center cursor-pointer hover:bg-slate-100 transition"
                      >
                        {datesServDisplay || "Cliquez pour sélectionner…"}
                      </div>
                      <button
                        type="button"
                        onClick={() => setDatesServOpen(true)}
                        className="px-3 py-2 rounded-lg border bg-white text-sm hover:bg-slate-50 transition whitespace-nowrap"
                      >
                        Modifier
                      </button>
                      {datesServ && (
                        <button
                          type="button"
                          onClick={() => {
                            setDatesServ("");
                            setDatesServDisplay("");
                          }}
                          className="px-3 py-2 rounded-lg border border-red-200 bg-white text-sm text-red-600 hover:bg-red-50 transition whitespace-nowrap"
                        >
                          Effacer
                        </button>
                      )}
                    </div>
                  </div>
                </FieldRow>

                {/* Calendriers pour représentations et répétitions */}
                <DatePickerCalendar
                  isOpen={datesRepOpen}
                  onClose={() => setDatesRepOpen(false)}
                  onApply={handleDatesRepApply}
                  initialDates={datesRep ? extractDatesFromFormatted(datesRep, dateDebut || new Date().toISOString().slice(0, 10)) : []}
                  title="Sélectionner les dates de représentations"
                />
                <DatePickerCalendar
                  isOpen={datesServOpen}
                  onClose={() => setDatesServOpen(false)}
                  onApply={handleDatesServApply}
                  initialDates={datesServ ? extractDatesFromFormatted(datesServ, dateDebut || new Date().toISOString().slice(0, 10)) : []}
                  title="Sélectionner les dates de répétitions"
                />
              </>
            ) : (
              <>
                <FieldRow>
                  <div>
                    <Label>Indiquez les jours de travail</Label>
                    <div className="flex items-center gap-2">
                      <div 
                        onClick={() => setJoursTravailOpen(true)}
                        className="flex-1 px-3 py-2 rounded-lg border bg-slate-50 text-sm text-slate-700 min-h-[42px] flex items-center cursor-pointer hover:bg-slate-100 transition"
                      >
                        {joursTravailDisplay || "Cliquez pour sélectionner…"}
                      </div>
                      <button
                        type="button"
                        onClick={() => setJoursTravailOpen(true)}
                        className="px-3 py-2 rounded-lg border bg-white text-sm hover:bg-slate-50 transition whitespace-nowrap"
                      >
                        Modifier
                      </button>
                    </div>
                  </div>

                  <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>
                </FieldRow>

                {/* Section cachets pour metteur en scène */}
                {professionPick?.code === "MET040" && (
                  <FieldRow>
                    <div>
                      <Label>Nombre de représentations (cachets)</Label>
                      <input
                        type="number"
                        min={0}
                        value={nbRepMetteur}
                        onChange={(e) => setNbRepMetteur(e.target.value === "" ? "" : Number(e.target.value))}
                        placeholder="ex : 2"
                        className="w-full px-3 py-2 rounded-lg border bg-white text-sm"
                      />
                      <p className="text-[11px] text-slate-500 mt-1">
                        Nombre de cachets de représentation pour le metteur en scène.
                      </p>
                    </div>
                  </FieldRow>
                )}

                {/* Calendrier pour jours de travail */}
                <DatePickerCalendar
                  isOpen={joursTravailOpen}
                  onClose={() => setJoursTravailOpen(false)}
                  onApply={handleJoursTravailApply}
                  initialDates={joursTravailRaw.length > 0 ? joursTravailRaw : (joursTravail ? extractDatesFromFormatted(joursTravail, dateDebut || new Date().toISOString().slice(0, 10)) : [])}
                  title="Sélectionner les jours de travail"
                />
              </>
            )
          )}

          {/* Sous-card avec les champs auto-remplis */}
          <div className="bg-slate-50 rounded-lg p-4 border border-slate-200">
            <div className="flex items-center justify-between mb-3">
              <div className="flex items-center gap-2">
                <div className="w-2 h-2 rounded-full bg-indigo-500"></div>
                <p className="text-xs font-medium text-slate-600">Se rempli automatiquement selon vos sélections de dates</p>
              </div>
              <button
                type="button"
                onClick={() => setManualDatesMode(!manualDatesMode)}
                className="px-2 py-1 text-xs rounded border bg-white hover:bg-slate-50 transition"
              >
                {manualDatesMode ? "Mode automatique" : "Remplir manuellement"}
              </button>
            </div>
            
            <FieldRow>
              <div>
                <Label required>Date de début du contrat</Label>
                <input
                  type="date"
                  value={dateDebut}
                  onChange={(e) => {
                    if (manualDatesMode) {
                      const v = e.target.value;
                      setDateDebut(v);
                      setConfirmPastStart(false);
                      if (dateFin && v && dateFin < v) setDateFin(v);
                    }
                  }}
                  disabled={!manualDatesMode}
                  className={`w-full px-3 py-2 rounded-lg border text-sm ${
                    manualDatesMode 
                      ? 'bg-white text-slate-900' 
                      : 'bg-slate-100 text-slate-600 cursor-not-allowed'
                  }`}
                />
              </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) => manualDatesMode && setDateFin(e.target.value)}
                    disabled={!manualDatesMode}
                    className={`w-full px-3 py-2 rounded-lg border text-sm ${
                      manualDatesMode 
                        ? 'bg-white text-slate-900' 
                        : 'bg-slate-100 text-slate-600 cursor-not-allowed'
                    }`}
                  />
                </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) => manualDatesMode && setNbRep(e.target.value === "" ? "" : Number(e.target.value))}
                    disabled={!manualDatesMode}
                    className={`w-full px-3 py-2 rounded-lg border text-sm ${
                      manualDatesMode 
                        ? 'bg-white text-slate-900' 
                        : 'bg-slate-100 text-slate-600 cursor-not-allowed'
                    }`}
                  />
                </div>
                <div>
                  <Label>Combien de services de répétition ? / Durée</Label>
                  <div className="flex gap-2 items-center">
                    <input
                      type="number"
                      min={0}
                      value={nbServ}
                      onChange={(e) => manualDatesMode && setNbServ(e.target.value === "" ? "" : Number(e.target.value))}
                      disabled={!manualDatesMode}
                      placeholder="Nombre"
                      className={`flex-1 px-3 py-2 rounded-lg border text-sm ${
                        manualDatesMode 
                          ? 'bg-white text-slate-900' 
                          : 'bg-slate-100 text-slate-600 cursor-not-allowed'
                      }`}
                    />
                    <span className="text-slate-400 font-medium">×</span>
                    {typeof nbServ === "number" && nbServ > 0 && (
                      <select
                        value={durationServices}
                        onChange={(e) => manualDatesMode && setDurationServices(e.target.value as "3" | "4")}
                        disabled={!manualDatesMode}
                        className={`flex-1 px-3 py-2 rounded-lg border text-sm ${
                          manualDatesMode 
                            ? 'bg-white text-slate-900' 
                            : 'bg-slate-100 text-slate-600 cursor-not-allowed'
                        }`}
                        title="Durée des services de répétition"
                      >
                        <option value="3">3 heures</option>
                        <option value="4">4 heures</option>
                      </select>
                    )}
                  </div>
                </div>
              </FieldRow>
            )}

            {/* Affichage du type de contrat */}
            {!isRegimeRG && (
              <p className="text-xs text-slate-500 mt-2">
                Type : <span className="font-medium text-slate-700">{isMultiMois === "Oui" ? "CDDU multi-mois" : "CDDU mono-mois"}</span>
              </p>
            )}
          </div>
        </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 et Minima - Conteneur deux colonnes */}
        <div className="flex gap-6">
          {/* Rémunération - 50% de largeur */}
          <div className="flex-1">
          <Section title="Rémunération">
          {/* Onglets pour choisir le mode de saisie du salaire */}
          {typeSalaire !== "Minimum conventionnel" && (
            <div className="mb-4 flex gap-2 border-b border-slate-200">
              <button
                type="button"
                onClick={() => setSalaryMode("global")}
                className={`px-4 py-2 font-medium text-sm transition-colors ${
                  salaryMode === "global"
                    ? "text-indigo-600 border-b-2 border-indigo-600 -mb-0.5"
                    : "text-slate-600 hover:text-slate-900"
                }`}
              >
                Saisir le salaire global
              </button>
              <button
                type="button"
                onClick={() => setSalaryMode("par_date")}
                className={
                  `px-4 py-2 font-medium text-sm transition-colors ` +
                  (salaryMode === "par_date"
                    ? "text-indigo-600 border-b-2 border-indigo-600 -mb-0.5"
                    : "text-slate-600 hover:text-slate-900")
                }
              >
                Saisir le salaire par date
              </button>
            </div>
          )}

          {/* Mode salaire global */}
          {salaryMode === "global" && (
            <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("");
                      setMontantFromCalculator(false);
                    }
                  }}
                  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={
                          montantFromCalculator && montantSalaire !== ""
                            ? Number(montantSalaire).toFixed(2)
                            : montantSalaire
                        }
                        onChange={(e) => {
                          setMontantFromCalculator(false);
                          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>
                      
                      {/* Bouton Calculatrice avec gradient */}
                      <button
                        type="button"
                        onClick={() => setIsCalculatorOpen(true)}
                        className="px-3 py-2 rounded-lg border-0 bg-gradient-to-r from-blue-500 to-indigo-600 hover:from-blue-600 hover:to-indigo-700 transition-all flex items-center justify-center gap-2 text-sm flex-shrink-0 shadow-sm hover:shadow-md"
                        title="Ouvrir la calculatrice"
                        aria-label="Calculatrice"
                      >
                        <CalculatorIcon className="w-4 h-4 text-white flex-shrink-0" />
                        <span className="text-white font-medium whitespace-nowrap">Calculatrice</span>
                      </button>
                      
                      {/* Bouton Minima */}
                      <a
                        href="/minima-ccn"
                        target="_blank"
                        rel="noopener noreferrer"
                        className="px-3 py-2 rounded-lg border-0 bg-gradient-to-r from-emerald-500 to-teal-600 hover:from-emerald-600 hover:to-teal-700 transition-all flex items-center justify-center gap-2 text-sm flex-shrink-0 shadow-sm hover:shadow-md"
                        title="Consulter les minima conventionnels"
                      >
                        <span className="text-white font-medium whitespace-nowrap">Minima</span>
                        <ExternalLink className="w-3.5 h-3.5 text-white flex-shrink-0" />
                      </a>
                    </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>
                
                {/* Champs conditionnels si panier repas = Oui */}
                {panierRepas === "Oui" && (
                  <div className="mt-4 space-y-3 pl-4 border-l-2 border-slate-200">
                    <div>
                      <Label>Nombre de paniers</Label>
                      <input
                        type="number"
                        min="0"
                        step="1"
                        value={nombrePaniersRepas}
                        onChange={(e) => setNombrePaniersRepas(e.target.value === "" ? "" : Number(e.target.value))}
                        className="w-full px-3 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500"
                        placeholder="Ex: 5"
                      />
                    </div>
                    
                    <div>
                      <Label>Au minima CCN ?</Label>
                      <div className="flex items-center gap-6 mt-2">
                        <label className="inline-flex items-center gap-2 text-sm">
                          <input type="radio" checked={panierRepasCCN === "Oui"} onChange={() => setPanierRepasCCN("Oui")} />
                          Oui
                        </label>
                        <label className="inline-flex items-center gap-2 text-sm">
                          <input type="radio" checked={panierRepasCCN === "Non"} onChange={() => setPanierRepasCCN("Non")} />
                          Non
                        </label>
                      </div>
                    </div>
                    
                    {panierRepasCCN === "Non" && (
                      <div>
                        <Label>Montant par panier (en €)</Label>
                        <input
                          type="number"
                          min="0"
                          step="0.01"
                          value={montantParPanier}
                          onChange={(e) => setMontantParPanier(e.target.value === "" ? "" : Number(e.target.value))}
                          className="w-full px-3 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500"
                          placeholder="Ex: 20.50"
                        />
                      </div>
                    )}
                    
                    <p className="text-[11px] text-slate-500 italic">
                      N'hésitez pas à nous préciser vos besoins en termes de défraiements dans la zone Notes ci-dessous.
                    </p>
                  </div>
                )}
                
                {/* Affichage de la note générée pour les paniers repas */}
                {panierRepas === "Oui" && panierRepasNote && (
                  <div className="mt-4 p-4 bg-amber-50 border border-amber-200 rounded-lg">
                    <div className="flex items-start gap-2">
                      <Info className="w-4 h-4 text-amber-600 mt-0.5 flex-shrink-0" />
                      <div className="flex-1">
                        <p className="text-xs font-semibold text-amber-900 mb-1">Note automatique - Paniers repas</p>
                        <p className="text-xs text-amber-800 whitespace-pre-line">{panierRepasNote}</p>
                      </div>
                    </div>
                  </div>
                )}
              </div>
            </FieldRow>
          )}

          {/* Mode salaire par date (désactivé temporairement) */}
          {salaryMode === "par_date" && (
            <div>
              <div className="mb-4">
                <Label required>Type de salaire</Label>
                <div className="flex items-center gap-2">
                  <select
                    value={typeSalaire}
                    onChange={(e) => {
                      const v = e.target.value as typeof typeSalaire;
                      setTypeSalaire(v);
                    }}
                    className="flex-1 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>
                  </select>
                  
                  {/* Bouton Calculatrice */}
                  <button
                    type="button"
                    onClick={() => setIsCalculatorOpen(true)}
                    className="px-3 py-2 rounded-lg border-0 bg-gradient-to-r from-blue-500 to-indigo-600 hover:from-blue-600 hover:to-indigo-700 transition-all flex items-center justify-center gap-2 text-sm flex-shrink-0 shadow-sm hover:shadow-md"
                    title="Ouvrir la calculatrice"
                    aria-label="Calculatrice"
                  >
                    <CalculatorIcon className="w-4 h-4 text-white flex-shrink-0" />
                    <span className="text-white font-medium whitespace-nowrap">Calculatrice</span>
                  </button>
                  
                  {/* Bouton Minima */}
                  <a
                    href="/minima-ccn"
                    target="_blank"
                    rel="noopener noreferrer"
                    className="px-3 py-2 rounded-lg border-0 bg-gradient-to-r from-emerald-500 to-teal-600 hover:from-emerald-600 hover:to-teal-700 transition-all flex items-center justify-center gap-2 text-sm flex-shrink-0 shadow-sm hover:shadow-md"
                    title="Consulter les minima conventionnels"
                  >
                    <span className="text-white font-medium whitespace-nowrap">Minima</span>
                    <ExternalLink className="w-3.5 h-3.5 text-white flex-shrink-0" />
                  </a>
                </div>
              </div>

              {/* Tableau des dates avec salaires */}
              {(datesRep.length > 0 || datesServ.length > 0 || joursTravail.length > 0) ? (
                <>
                  {/* Tableau des dates avec salaires - version compacte */}
                  <div className="space-y-3 mb-4">
                    {/* Représentations */}
                    {datesRep && datesRep.length > 0 && (() => {
                      const yearContext = dateDebut || new Date().toISOString().slice(0, 10);
                      const allRepDates = parseFormattedDatesWithQuantities(datesRep, yearContext, "rep");
                      
                      return (
                        <div className="bg-white rounded-lg border border-slate-200 overflow-hidden">
                          <div className="bg-indigo-50 px-3 py-2 border-b border-indigo-100">
                            <span className="text-xs font-semibold text-indigo-900 uppercase tracking-wide">Représentations</span>
                          </div>
                          <div className="p-2 space-y-1.5">
                            {allRepDates.map((dateInfo) => (
                              <div key={dateInfo.key} className="flex items-center gap-2 py-1.5 px-2 rounded hover:bg-slate-50">
                                <div className="text-xs font-medium text-slate-700 w-14 shrink-0">{dateInfo.date}</div>
                                <div className="flex items-center gap-1.5 flex-wrap">
                                  {Array.from({ length: dateInfo.quantity }).map((_, i) => (
                                    <div key={`${dateInfo.key}_${i}`} className="flex items-center gap-1">
                                      <span className="text-xs text-slate-500">R{i + 1}</span>
                                      <input
                                        type="number"
                                        min="0.01"
                                        step="0.01"
                                        value={salariesByDate[`${dateInfo.key}_${i}`] ?? ""}
                                        onChange={(e) =>
                                          setSalariesByDate({
                                            ...salariesByDate,
                                            [`${dateInfo.key}_${i}`]: e.target.value === "" ? "" : Number(e.target.value),
                                          })
                                        }
                                        placeholder="0.00"
                                        className="w-20 px-2 py-1 rounded border border-slate-300 bg-white text-xs text-right focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"
                                        title={`Représentation #${i + 1}`}
                                      />
                                      <span className="text-xs text-slate-400">€</span>
                                    </div>
                                  ))}
                                </div>
                              </div>
                            ))}
                          </div>
                        </div>
                      );
                    })()}
                    
                    {/* Répétitions */}
                    {datesServ && datesServ.length > 0 && (() => {
                      const yearContext = dateDebut || new Date().toISOString().slice(0, 10);
                      const allServDates = parseFormattedDatesWithQuantities(datesServ, yearContext, "serv");
                      
                      return (
                        <div className="bg-white rounded-lg border border-slate-200 overflow-hidden">
                          <div className="bg-purple-50 px-3 py-2 border-b border-purple-100">
                            <span className="text-xs font-semibold text-purple-900 uppercase tracking-wide">Répétitions</span>
                          </div>
                          <div className="p-2 space-y-1.5">
                            {allServDates.map((dateInfo) => (
                              <div key={dateInfo.key} className="flex items-center gap-2 py-1.5 px-2 rounded hover:bg-slate-50">
                                <div className="text-xs font-medium text-slate-700 w-14 shrink-0">{dateInfo.date}</div>
                                <div className="flex items-center gap-1.5 flex-wrap">
                                  {Array.from({ length: dateInfo.quantity }).map((_, i) => (
                                    <div key={`${dateInfo.key}_${i}`} className="flex items-center gap-1">
                                      <span className="text-xs text-slate-500">S{i + 1}</span>
                                      <input
                                        type="number"
                                        min="0.01"
                                        step="0.01"
                                        value={salariesByDate[`${dateInfo.key}_${i}`] ?? ""}
                                        onChange={(e) =>
                                          setSalariesByDate({
                                            ...salariesByDate,
                                            [`${dateInfo.key}_${i}`]: e.target.value === "" ? "" : Number(e.target.value),
                                          })
                                        }
                                        placeholder="0.00"
                                        className="w-20 px-2 py-1 rounded border border-slate-300 bg-white text-xs text-right focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-purple-500"
                                        title={`Répétition #${i + 1}`}
                                      />
                                      <span className="text-xs text-slate-400">€</span>
                                    </div>
                                  ))}
                                </div>
                              </div>
                            ))}
                          </div>
                        </div>
                      );
                    })()}
                    
                    {/* Jours travaillés */}
                    {joursTravail && joursTravail.length > 0 && (() => {
                      const yearContext = dateDebut || new Date().toISOString().slice(0, 10);
                      const allJoursDates = parseFormattedDatesWithQuantities(joursTravail, yearContext, "jour");
                      
                      return (
                        <div className="bg-white rounded-lg border border-slate-200 overflow-hidden">
                          <div className="bg-green-50 px-3 py-2 border-b border-green-100">
                            <span className="text-xs font-semibold text-green-900 uppercase tracking-wide">Jours travaillés</span>
                          </div>
                          <div className="p-2 space-y-1.5">
                            {allJoursDates.map((dateInfo) => (
                              <div key={dateInfo.key} className="flex items-center gap-2 py-1.5 px-2 rounded hover:bg-slate-50">
                                <div className="text-xs font-medium text-slate-700 w-14 shrink-0">{dateInfo.date}</div>
                                <div className="flex items-center gap-1.5">
                                  <div className="flex items-center gap-1">
                                    <span className="text-xs text-slate-500">Jour</span>
                                    <input
                                      type="number"
                                      min="0.01"
                                      step="0.01"
                                      value={salariesByDate[`${dateInfo.key}_0`] ?? ""}
                                      onChange={(e) =>
                                        setSalariesByDate({
                                          ...salariesByDate,
                                          [`${dateInfo.key}_0`]: e.target.value === "" ? "" : Number(e.target.value),
                                        })
                                      }
                                      placeholder="0.00"
                                      className="w-20 px-2 py-1 rounded border border-slate-300 bg-white text-xs text-right focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500"
                                    />
                                    <span className="text-xs text-slate-400">€</span>
                                  </div>
                                </div>
                              </div>
                            ))}
                          </div>
                        </div>
                      );
                    })()}
                  </div>

                  {/* Total du salaire */}
                  <div className="p-4 bg-gradient-to-r from-indigo-50 to-purple-50 rounded-lg border-2 border-indigo-200 mb-4">
                    <div className="flex items-baseline justify-between">
                      <div>
                        <div className="text-xs uppercase tracking-wide text-indigo-700 font-semibold">Salaire total ({typeSalaire})</div>
                        <div className="text-3xl font-bold text-indigo-900 mt-1">
                          {(Object.values(salariesByDate).reduce((sum: number, val) => {
                            return sum + (typeof val === "number" ? val : 0);
                          }, 0) as number).toFixed(2)} €
                        </div>
                      </div>
                    </div>
                  </div>
                </>
              ) : (
                <div className="p-4 bg-slate-50 rounded-lg text-sm text-slate-600 text-center mb-4">
                  Veuillez sélectionner des dates avant de saisir les salaires par date.
                </div>
              )}

              <div className="mt-4">
                <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>
                
                {/* Champs conditionnels si panier repas = Oui */}
                {panierRepas === "Oui" && (
                  <div className="mt-4 space-y-3 pl-4 border-l-2 border-slate-200">
                    <div>
                      <Label>Nombre de paniers</Label>
                      <input
                        type="number"
                        min="0"
                        step="1"
                        value={nombrePaniersRepas}
                        onChange={(e) => setNombrePaniersRepas(e.target.value === "" ? "" : Number(e.target.value))}
                        className="w-full px-3 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500"
                        placeholder="Ex: 5"
                      />
                    </div>
                    
                    <div>
                      <Label>Au minima CCN ?</Label>
                      <div className="flex items-center gap-6 mt-2">
                        <label className="inline-flex items-center gap-2 text-sm">
                          <input type="radio" checked={panierRepasCCN === "Oui"} onChange={() => setPanierRepasCCN("Oui")} />
                          Oui
                        </label>
                        <label className="inline-flex items-center gap-2 text-sm">
                          <input type="radio" checked={panierRepasCCN === "Non"} onChange={() => setPanierRepasCCN("Non")} />
                          Non
                        </label>
                      </div>
                    </div>
                    
                    {panierRepasCCN === "Non" && (
                      <div>
                        <Label>Montant par panier (en €)</Label>
                        <input
                          type="number"
                          min="0"
                          step="0.01"
                          value={montantParPanier}
                          onChange={(e) => setMontantParPanier(e.target.value === "" ? "" : Number(e.target.value))}
                          className="w-full px-3 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500"
                          placeholder="Ex: 20.50"
                        />
                      </div>
                    )}
                    
                    <p className="text-[11px] text-slate-500 italic">
                      N'hésitez pas à nous préciser vos besoins en termes de défraiements dans la zone Notes ci-dessous.
                    </p>
                  </div>
                )}
              </div>
            </div>
          )}

          {/* Type de salaire pour le mode global */}
          {salaryMode === "global" && typeSalaire === "Minimum conventionnel" && (
            <div className="mt-4 p-3 bg-blue-50 border border-blue-200 rounded-lg text-sm text-blue-800">
              Le salaire sera calculé selon le minimum conventionnel applicable.
            </div>
          )}
          </Section>
          </div>

          {/* Encart Minima CCN entièrement masqué temporairement */}
        </div>

        {/* 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>
                {/* Envoi de fichiers retiré */}
              </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>
                <Label required>Voulez-vous recevoir une confirmation par e-mail ?</Label>
                <div className="flex items-center gap-6 mt-2">
                  <label className="inline-flex items-center gap-2 text-sm">
                    <input type="radio" checked={emailConfirm === "Oui"} onChange={() => setEmailConfirm("Oui")} />
                    Oui
                  </label>
                  <label className="inline-flex items-center gap-2 text-sm">
                    <input type="radio" checked={emailConfirm === "Non"} onChange={() => setEmailConfirm("Non")} />
                    Non
                  </label>
                </div>
                <p className="text-[11px] text-slate-500 mt-1">
                  Si vous choisissez “Non”, aucune notification e-mail ne sera envoyée à la création du contrat.
                </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 || isDemoMode}
            className="px-4 py-2 rounded-lg bg-emerald-600 text-white hover:bg-emerald-700 disabled:opacity-50 disabled:cursor-not-allowed"
            title={isDemoMode ? "Désactivé en mode démo" : ""}
          >
            {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>
      )}

      {/* Calculatrice */}
      <Calculator 
        isOpen={isCalculatorOpen}
        onClose={() => setIsCalculatorOpen(false)}
        onUseResult={salaryMode === "global" ? (value) => {
          const rounded = Math.round((value + Number.EPSILON) * 100) / 100;
          setMontantSalaire(rounded);
          setMontantFromCalculator(true);
          setIsCalculatorOpen(false);
        } : undefined}
      />

      {/* Modale de quantités pour les dates sélectionnées */}
      <DatesQuantityModal
        isOpen={quantityModalOpen}
        onClose={() => {
          setQuantityModalOpen(false);
          setPendingDates([]);
        }}
        onApply={handleQuantityApply}
        selectedDates={pendingDates}
        dateType={quantityModalType}
        minDate={dateDebut}
        maxDate={dateFin}
        allowSkipHoursByDay={true}
        repetitionDuration={durationServices}
      />
    </>
  );
}
