// components/staff/contracts/ContractEditor.tsx
"use client";

import { useMemo, useState, useEffect, useRef, useCallback } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Separator } from "@/components/ui/separator";
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet";
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { toast } from "sonner";
import { CalendarRange, FilePlus2, FileText, Save, Search, FileDown, PenTool, RefreshCw, Mail, Clock, CheckCircle2, XCircle, Users, Send, Check, Upload, Ban, Euro, StickyNote } from "lucide-react";
import PayslipForm from "./PayslipForm";
import { api } from "@/lib/fetcher";
import { PROFESSIONS_ARTISTE } from "@/components/constants/ProfessionsArtiste";
import { LoadingModal } from "@/components/ui/loading-modal";
import { PayslipModal } from "./PayslipModal";
import { EmployerReminderModal } from "./EmployerReminderModal";
import { PayslipCard } from "./PayslipCard";
import { NotesSection } from "@/components/NotesSection";
import ESignConfirmModal from "./ESignConfirmModal";
import DatePickerCalendar from "@/components/DatePickerCalendar";
import DatesQuantityModal from "@/components/DatesQuantityModal";
import { parseDateString } from "@/lib/dateFormatter";
import { supabase } from "@/lib/supabaseClient";
import { ManualSignedContractUpload } from "./ManualSignedContractUpload";
import CancelContractModal from "./CancelContractModal";
import { SalaireParDateEditor } from "./SalaireParDateEditor";

type AnyObj = Record<string, any>;

// Types from NouveauCDDUForm
type SalarieOption = { 
  matricule: string; 
  nom: string; 
  email?: string | null;
  code_salarie?: string | null;
  prenom?: string | null;
  civilite?: string | null;
};
type SpectacleOption = { 
  id?: string;
  nom: string; 
  numero_objet?: string | null;
  prod_type?: string | null;
  director?: string | null;
};
type ProfessionOption = { code: string; label: string };
type TechnicienOption = ProfessionOption;
type ClientInfo = { id: string; name: string; api_name?: string } | null;

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

// Helper function to parse monetary amounts with French decimal notation (comma)
function parseMonetaryAmount(value: string | number): number | null {
  if (!value) return null;
  const str = String(value).trim();
  if (!str) return null;
  
  // Replace comma with dot for proper parseFloat
  const normalized = str.replace(',', '.');
  const parsed = parseFloat(normalized);
  
  return isNaN(parsed) ? null : parsed;
}

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

// Search hooks from NouveauCDDUForm
function useSearchSalaries(q: string) {
  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());

  return useQuery({
    queryKey: ["search-salaries", q, clientInfo?.id],
    queryFn: async () => {
      const result = await api<{ items: SalarieOption[] }>(`/salaries?${params.toString()}`, {}, clientInfo);
      return {
        items: result.items ?? [],
      };
    },
    enabled: q.trim().length > 1 && !!clientInfo,
    staleTime: 10_000,
  });
}

function useSearchSpectacles(q: string) {
  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());

  return useQuery({
    queryKey: ["search-spectacles", q, clientInfo?.id],
    queryFn: async () => {
      const result = await api<{ items: SpectacleOption[] }>(`/spectacles?${params.toString()}`, {}, clientInfo);
      return {
        items: result.items ?? [],
      };
    },
    enabled: q.trim().length > 1 && !!clientInfo,
    staleTime: 10_000,
  });
}

function slugify(input: string) {
  return (input || "")
    .toLowerCase()
    .normalize("NFD")
    .replace(/\p{Diacritic}/gu, "")
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/(^-|-$)/g, "");
}

// Hook pour récupérer les informations d'organisation avec la CCN
function useOrganizationDetails() {
  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,
  });

  return useQuery({
    queryKey: ["organization-details", clientInfo?.id],
    queryFn: async () => {
      if (!clientInfo?.id) return null;
      
      try {
        const res = await fetch(`/api/organizations/${clientInfo.id}/details`, {
          cache: "no-store",
          headers: { Accept: "application/json" },
          credentials: "include"
        });
        
        if (!res.ok) return null;
        const orgData = await res.json();
        return orgData;
      } catch (error) {
        console.error("Error fetching organization details:", error);
        return null;
      }
    },
    enabled: !!clientInfo?.id,
    staleTime: 60_000, // Cache plus long car ces données changent rarement
  });
}

export default function ContractEditor({
  contract,
  payslips,
  organizationDetails: serverOrganizationDetails,
}: {
  contract: AnyObj;
  payslips: AnyObj[];
  organizationDetails?: any;
}) {
  const queryClient = useQueryClient();
  
  // État local pour l'URL et le filename du PDF (pour mise à jour sans refresh)
  const [contractPdfUrl, setContractPdfUrl] = useState(contract.contract_pdf_url);
  const [contractPdfFilename, setContractPdfFilename] = useState(contract.contract_pdf_filename);
  
  // Récupération des informations d'organisation avec la CCN
  const { data: clientOrganizationDetails } = useOrganizationDetails();
  
  // Utiliser les données serveur en priorité, sinon les données client
  const organizationDetails = serverOrganizationDetails || clientOrganizationDetails;
  
  // Préremplissages pour aligner l'affichage avec le formulaire de création CDDU
  const prefill = useMemo(() => {
    const spectacle = contract.production_name || contract.nom_du_spectacle || "";
    const numero_objet = contract.objet_spectacle || contract.numero_objet || "";
    // Priorité: salaries.salarie > salaries.nom+prenom > employee_name fallback
    const salarie_nom = contract.salaries?.salarie 
      || (contract.salaries?.nom 
          ? `${contract.salaries.nom.toUpperCase()}${contract.salaries.prenom ? ' ' + contract.salaries.prenom.charAt(0).toUpperCase() + contract.salaries.prenom.slice(1) : ''}`
          : contract.employee_name || "");
    const salarie_matricule = contract.employee_matricule || contract.matricule || contract.salaries?.code_salarie || "";
    const salarie_email = contract.salaries?.adresse_mail || null;
    const salarie_prenom = contract.salaries?.prenom || null;
    const salarie_code = contract.salaries?.code_salarie || null;
    const categorie = contract.categorie_pro || contract.categorie_professionnelle || "";
    const profession = contract.profession || "";
    const date_debut = (contract.start_date || contract.debut_contrat || "").slice?.(0, 10) || "";
    const date_fin = (contract.end_date || contract.fin_contrat || "").slice?.(0, 10) || "";
    const jours_travail = contract.jours_travail || "";
    const heures_total = contract.nombre_d_heures || contract.heures_travail || "";
    const heures_annexe_8 = contract.heures_annexe_8 || "";
    const type_salaire = contract.type_salaire || (contract.gross_pay ? "Brut" : contract.net_pay ? "Net avant PAS" : "");
    const montant = contract.salaire || contract.gross_pay || contract.net_pay || "";
    const panier_repas = contract.paniers_repas || contract.panier_repas || "";
    const reference = contract.reference || contract.contract_number || "";
    const analytique = contract.analytique || "";
    const multi_mois = String(contract.multi_mois || "");
    return {
      spectacle,
      numero_objet,
      salarie_nom,
      salarie_matricule,
      salarie_email,
      salarie_prenom,
      salarie_code,
      categorie,
      profession,
      date_debut,
      date_fin,
      jours_travail,
      heures_total,
      heures_annexe_8,
      type_salaire,
      montant,
      panier_repas,
      reference,
      analytique,
      multi_mois,
    };
  }, [contract]);

  // CDDU form state
  const [spectacleQuery, setSpectacleQuery] = useState("");
  const [spectaclePick, setSpectaclePick] = useState<SpectacleOption | null>(
    prefill.spectacle ? { nom: prefill.spectacle, numero_objet: prefill.numero_objet } : null
  );
  const [salarieQuery, setSalarieQuery] = useState("");
  const [salarie, setSalarie] = useState<SalarieOption | null>(
    prefill.salarie_nom && prefill.salarie_matricule ? 
    { 
      nom: prefill.salarie_nom, 
      matricule: prefill.salarie_matricule,
      email: prefill.salarie_email,
      prenom: prefill.salarie_prenom,
      code_salarie: prefill.salarie_code
    } : null
  );
  const [categoriePro, setCategoriePro] = useState<"Artiste" | "Technicien">(
    (prefill.categorie as "Artiste" | "Technicien") || "Artiste"
  );
  const [professionQuery, setProfessionQuery] = useState("");
  const [professionInputFocused, setProfessionInputFocused] = useState(false);
  const [professionPick, setProfessionPick] = useState<ProfessionOption | null>(() => {
    if (!prefill.profession) return null;
    
    // Chercher le code dans les professions artistes
    const artisteProfession = PROFESSIONS_ARTISTE.find(p => 
      p.label.toLowerCase() === prefill.profession.toLowerCase()
    );
    
    if (artisteProfession) {
      return artisteProfession;
    }
    
    // Si pas trouvé, créer avec un code vide (sera résolu plus tard pour les techniciens)
    return { label: prefill.profession, code: "" };
  });
  const [professionFeminine, setProfessionFeminine] = useState("");
  const [isSavingFeminisation, setIsSavingFeminisation] = useState(false);
  const [techniciens, setTechniciens] = useState<TechnicienOption[] | null>(null);
  const techLoadedRef = useRef(false);
  
  // États pour les champs conditionnels (heures vs répétitions/représentations)
  const [nbRepresentations, setNbRepresentations] = useState<number | "">(contract.cachets_representations || "");
  const [nbServicesRepetition, setNbServicesRepetition] = useState<number | "">(contract.services_repetitions || "");
  const [durationServices, setDurationServices] = useState<"3" | "4">("4"); // Durée des services (3 ou 4 heures)
  const [datesRepresentations, setDatesRepresentations] = useState(contract.jours_representations || "");
  const [datesRepresentationsDisplay, setDatesRepresentationsDisplay] = useState("");
  const [datesRepresentationsOpen, setDatesRepresentationsOpen] = useState(false);
  const [datesRepetitions, setDatesRepetitions] = useState(contract.jours_repetitions || "");
  const [datesRepetitionsDisplay, setDatesRepetitionsDisplay] = useState("");
  const [datesRepetitionsOpen, setDatesRepetitionsOpen] = useState(false);
  const [heuresTotal, setHeuresTotal] = useState<number | "">(contract.nombre_d_heures || "");
  const [minutesTotal, setMinutesTotal] = useState<"0" | "30">((contract.minutes_total || "0") as "0" | "30");
  const [joursTravail, setJoursTravail] = useState(contract.jours_travail || "");
  const [joursTravailDisplay, setJoursTravailDisplay] = useState("");
  const [joursTravailOpen, setJoursTravailOpen] = useState(false);
  
  // États pour la modale de précision des quantités
  const [quantityModalOpen, setQuantityModalOpen] = useState(false);
  const [quantityModalType, setQuantityModalType] = useState<"representations" | "repetitions" | "jours_travail" | "">(""); 
  const [pendingDates, setPendingDates] = useState<string[]>([]);
  
  const [nombreHeuresTotal, setNombreHeuresTotal] = useState<number | "">(contract.nombre_d_heures || "");
  const [nombreHeuresParJour, setNombreHeuresParJour] = useState<number | "">(contract.nombre_d_heures_par_jour || "");
  
  // États pour le temps de travail réel (informatif pour le client)
  const [joursTravailReel, setJoursTravailReel] = useState(contract.jours_travail_reel || "");
  const [joursTravailNonArtisteReel, setJoursTravailNonArtisteReel] = useState(contract.jours_travail_non_artiste_reel || "");
  const [nbRepresentationsReel, setNbRepresentationsReel] = useState<number | "">(contract.nb_representations_reel || "");
  const [datesRepresentationsReel, setDatesRepresentationsReel] = useState(contract.dates_representations_reel || "");
  const [nbServicesRepetitionsReel, setNbServicesRepetitionsReel] = useState<number | "">(contract.nb_services_repetitions_reel || "");
  const [nbHeuresRepetitionsReel, setNbHeuresRepetitionsReel] = useState<number | "">(contract.nb_heures_repetitions_reel || "");
  const [datesRepetitionsReel, setDatesRepetitionsReel] = useState(contract.dates_repetitions_reel || "");
  const [nbHeuresAnnexesReel, setNbHeuresAnnexesReel] = useState<number | "">(contract.nb_heures_annexes_reel || "");
  const [nbCachetsAemReel, setNbCachetsAemReel] = useState<number | "">(contract.nb_cachets_aem_reel || "");
  const [nbHeuresAemReel, setNbHeuresAemReel] = useState<number | "">(contract.nb_heures_aem_reel || "");
  
  // Synchroniser les états avec les données du contrat
  useEffect(() => {
    // Calculer le mode (heures vs représentations/répétitions)
    const isHeuresMode = (
      categoriePro === "Technicien" ||
      (categoriePro === "Artiste" && professionPick?.code === "MET040")
    );
    
    console.log("🔄 Synchronisation des champs avec les données du contrat:", {
      cachets_representations: contract.cachets_representations,
      services_repetitions: contract.services_repetitions,
      jours_representations: contract.jours_representations,
      jours_repetitions: contract.jours_repetitions,
      nombre_d_heures: contract.nombre_d_heures,
      minutes_total: contract.minutes_total,
      jours_travail: contract.jours_travail,
      jours_travail_non_artiste: contract.jours_travail_non_artiste,
      isHeuresMode,
      categoriePro,
      professionCode: professionPick?.code
    });
    
    // Utiliser les vrais noms de colonnes de la base de données
    setNbRepresentations(contract.cachets_representations || "");
    setNbServicesRepetition(contract.services_repetitions || "");
    
    // Initialiser les affichages avec formatage smart si présentes
    // Déterminer si c'est du texte formaté PDFMonkey ou des dates brutes
    if (contract.jours_representations) {
      // Détection améliorée du texte formaté
      const hasFormatIndicators = 
        contract.jours_representations.includes(" ; ") || 
        contract.jours_representations.includes(" le ") ||
        contract.jours_representations.includes(" du ") ||
        contract.jours_representations.includes(" au ") ||
        contract.jours_representations.includes(" par jour ") ||
        contract.jours_representations.startsWith("du ") ||
        contract.jours_representations.startsWith("le ") ||
        /^\d+ /.test(contract.jours_representations) ||
        contract.jours_representations.endsWith(".");
      if (hasFormatIndicators) {
        // C'est déjà du texte formaté, utiliser tel quel
        setDatesRepresentations(contract.jours_representations);
        setDatesRepresentationsDisplay(contract.jours_representations);
      } else {
        // C'est du texte brut (dates), parser et reformater
        const yearContext = contract.start_date || new Date().toISOString().slice(0, 10);
        const parsed = parseDateString(contract.jours_representations, yearContext);
        setDatesRepresentations(parsed.pdfFormatted);
        setDatesRepresentationsDisplay(parsed.pdfFormatted);
      }
    } else {
      setDatesRepresentations("");
      setDatesRepresentationsDisplay("");
    }
    
    if (contract.jours_repetitions) {
      const hasFormatIndicators = 
        contract.jours_repetitions.includes(" ; ") || 
        contract.jours_repetitions.includes(" le ") ||
        contract.jours_repetitions.includes(" du ") ||
        contract.jours_repetitions.includes(" au ") ||
        contract.jours_repetitions.includes(" par jour ") ||
        contract.jours_repetitions.startsWith("du ") ||
        contract.jours_repetitions.startsWith("le ") ||
        /^\d+ /.test(contract.jours_repetitions) ||
        contract.jours_repetitions.endsWith(".");
      if (hasFormatIndicators) {
        setDatesRepetitions(contract.jours_repetitions);
        setDatesRepetitionsDisplay(contract.jours_repetitions);
        // Détecter la durée des services dans le texte
        if (contract.jours_repetitions.includes("de 3 heures")) {
          setDurationServices("3");
        } else if (contract.jours_repetitions.includes("de 4 heures")) {
          setDurationServices("4");
        }
      } else {
        const yearContext = contract.start_date || new Date().toISOString().slice(0, 10);
        const parsed = parseDateString(contract.jours_repetitions, yearContext);
        setDatesRepetitions(parsed.pdfFormatted);
        setDatesRepetitionsDisplay(parsed.pdfFormatted);
      }
    } else {
      setDatesRepetitions("");
      setDatesRepetitionsDisplay("");
    }
    
    setHeuresTotal(contract.nombre_d_heures || "");
    setMinutesTotal((contract.minutes_total || "0") as "0" | "30");
    
    // Initialiser joursTravail avec formatage smart
    // En mode heures (technicien/metteur en scène), charger depuis jours_travail_non_artiste
    // En mode artiste classique, charger depuis jours_travail
    const joursTravailSource = isHeuresMode ? contract.jours_travail_non_artiste : contract.jours_travail;
    
    console.log("📍 Source pour joursTravail:", {
      isHeuresMode,
      source: isHeuresMode ? "jours_travail_non_artiste" : "jours_travail",
      valeur: joursTravailSource,
      contract_jours_travail: contract.jours_travail,
      contract_jours_travail_non_artiste: contract.jours_travail_non_artiste
    });
    
    if (joursTravailSource) {
      // Détection améliorée du texte formaté PDFMonkey
      // - Contient " ; " (séparateur de dates multiples)
      // - Contient des mots indicateurs : " le ", " du ", " au ", " par jour "
      // - Commence par des mots clés : "du ", "le ", nombre + espace
      // - Finit par un point (convention PDFMonkey)
      const hasFormatIndicators = 
        joursTravailSource.includes(" ; ") || 
        joursTravailSource.includes(" le ") ||
        joursTravailSource.includes(" du ") ||
        joursTravailSource.includes(" au ") ||
        joursTravailSource.includes(" par jour ") ||
        joursTravailSource.startsWith("du ") ||
        joursTravailSource.startsWith("le ") ||
        /^\d+ /.test(joursTravailSource) || // commence par un nombre + espace (ex: "5 heures le...")
        joursTravailSource.endsWith(".");
      
      console.log("🔍 Traitement de joursTravailSource:", {
        joursTravailSource,
        isFormatted: hasFormatIndicators,
        action: hasFormatIndicators ? "utilisation directe" : "parsing"
      });
      if (hasFormatIndicators) {
        setJoursTravail(joursTravailSource);
        setJoursTravailDisplay(joursTravailSource);
        console.log("✅ Valeurs définies (formaté):", {
          joursTravail: joursTravailSource,
          joursTravailDisplay: joursTravailSource
        });
      } else {
        const yearContext = contract.date_debut || new Date().toISOString().slice(0, 10);
        const parsed = parseDateString(joursTravailSource, yearContext);
        setJoursTravail(parsed.pdfFormatted);
        setJoursTravailDisplay(parsed.pdfFormatted);
        console.log("✅ Valeurs définies (parsé):", {
          joursTravail: parsed.pdfFormatted,
          joursTravailDisplay: parsed.pdfFormatted
        });
      }
    } else {
      setJoursTravail("");
      setJoursTravailDisplay("");
    }
    
    // Pré-remplir le nombre d'heures total
    if (contract.nombre_d_heures) {
      setNombreHeuresTotal(contract.nombre_d_heures);
    } else if (!isHeuresMode && contract.services_repetitions && contract.jours_repetitions) {
      // Si pas d'heures stockées, calculer à partir des services × durée
      const nbServices = parseInt(contract.services_repetitions) || 0;
      let duration = 4; // Durée par défaut
      if (contract.jours_repetitions.includes("de 3 heures")) {
        duration = 3;
      }
      setNombreHeuresTotal(nbServices * duration);
    } else {
      setNombreHeuresTotal("");
    }
    setNombreHeuresParJour(contract.nombre_d_heures_par_jour || "");
    
    // Pré-remplir la date de signature selon les règles :
    // - Date du jour si la date de début est le jour même ou dans le futur
    // - Égale à la date de début si celle-ci est dans le passé
    if (contract.date_signature) {
      setDateSignature(contract.date_signature.slice(0, 10));
    } else if (contract.date_debut) {
      const today = new Date().toISOString().split("T")[0];
      const dateDebut = contract.date_debut.split("T")[0];
      // Si date_debut est dans le passé (avant aujourd'hui), utiliser date_debut
      // Sinon, utiliser aujourd'hui
      setDateSignature(dateDebut < today ? dateDebut : today);
    } else {
      setDateSignature("");
    }
    
    setPrecisionsSalaire(contract.precisions_salaire || "");
    setAutrePrecisionDuree(contract.autreprecision_duree || "");
    setAutrePrecisionSalaire(contract.autreprecision_salaire || "");
    
    // Synchroniser les champs de temps de travail réel
    setJoursTravailReel(contract.jours_travail_reel || "");
    setJoursTravailNonArtisteReel(contract.jours_travail_non_artiste_reel || "");
    setNbRepresentationsReel(contract.nb_representations_reel || "");
    setDatesRepresentationsReel(contract.dates_representations_reel || "");
    setNbServicesRepetitionsReel(contract.nb_services_repetitions_reel || "");
    setNbHeuresRepetitionsReel(contract.nb_heures_repetitions_reel || "");
    setDatesRepetitionsReel(contract.dates_repetitions_reel || "");
    setNbHeuresAnnexesReel(contract.nb_heures_annexes_reel || "");
    setNbCachetsAemReel(contract.nb_cachets_aem_reel || "");
    setNbHeuresAemReel(contract.nb_heures_aem_reel || "");
  }, [contract, categoriePro, professionPick?.code]);
  
  // États pour les autres champs CDDU actuellement grisés
  const [typeSalaire, setTypeSalaire] = useState(prefill.type_salaire || "");
  const [panierRepas, setPanierRepas] = useState(prefill.panier_repas || "");
  const [reference, setReference] = useState(prefill.reference || "");
  const [analytique, setAnalytique] = useState(prefill.analytique || "");
  const [dateSignature, setDateSignature] = useState(contract.date_signature?.slice(0, 10) || "");
  const [montant, setMontant] = useState(String(prefill.montant || ""));
  const [precisionsSalaire, setPrecisionsSalaire] = useState(contract.precisions_salaire || "");
  const [autrePrecisionDuree, setAutrePrecisionDuree] = useState(contract.autreprecision_duree || "");
  const [autrePrecisionSalaire, setAutrePrecisionSalaire] = useState(contract.autreprecision_salaire || "");
  
  // Search states
  const [spectacleActive, setSpectacleActive] = useState(0);
  const [salarieActive, setSalarieActive] = useState(0);
  const [professionActive, setProfessionActive] = useState(0);
  
  // Loading states
  const [isGeneratingPdf, setIsGeneratingPdf] = useState(false);
  const [isRefreshing, setIsRefreshing] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [isLaunchingSignature, setIsLaunchingSignature] = useState(false);
  const [showPdfSuccess, setShowPdfSuccess] = useState(false);
  const [showSaveSuccess, setShowSaveSuccess] = useState(false);
  
  // Tracking des modifications
  const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);

  // Payslip modal states
  const [isPayslipModalOpen, setIsPayslipModalOpen] = useState(false);
  const [editingPayslip, setEditingPayslip] = useState<any>(null);
  
  // E-Sign confirmation modal states
  const [showESignConfirmModal, setShowESignConfirmModal] = useState(false);
  const [sendESignNotification, setSendESignNotification] = useState(true);
  const [verifiedEmployeeEmail, setVerifiedEmployeeEmail] = useState<string>("");
  const [verifiedEmployerEmail, setVerifiedEmployerEmail] = useState<string>("");
  
  // Manual upload modal state
  const [isUploadModalOpen, setIsUploadModalOpen] = useState(false);
  
  // Cancel contract modal states
  const [showCancelModal, setShowCancelModal] = useState(false);
  const [isCancelling, setIsCancelling] = useState(false);
  
  // Delete signed PDF states
  const [showDeleteSignedPdfModal, setShowDeleteSignedPdfModal] = useState(false);
  const [isDeletingSignedPdf, setIsDeletingSignedPdf] = useState(false);
  
  // Handler pour annuler le contrat
  const handleCancelContract = async () => {
    setIsCancelling(true);
    try {
      const response = await fetch(`/api/staff/contracts/${contract.id}/cancel`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
      });

      if (!response.ok) {
        const error = await response.json();
        throw new Error(error.error || "Erreur lors de l'annulation");
      }

      toast.success("Contrat annulé avec succès");
      setShowCancelModal(false);
      
      // Rafraîchir la page ou rediriger
      window.location.reload();
    } catch (error) {
      console.error("Erreur lors de l'annulation du contrat:", error);
      toast.error(error instanceof Error ? error.message : "Erreur lors de l'annulation");
    } finally {
      setIsCancelling(false);
    }
  };
  
  // Handler pour supprimer le contrat signé
  const handleDeleteSignedPdf = async () => {
    setIsDeletingSignedPdf(true);
    try {
      const response = await fetch(`/api/staff/contrats/${contract.id}/delete-signed-pdf`, {
        method: "DELETE",
      });

      if (!response.ok) {
        const error = await response.json();
        throw new Error(error.error || "Erreur lors de la suppression");
      }

      toast.success("Contrat signé supprimé avec succès");
      setShowDeleteSignedPdfModal(false);
      
      // Invalider les queries React Query pour rafraîchir les données
      queryClient.invalidateQueries({ queryKey: ["signed-contract-pdf", contract.id] });
    } catch (error) {
      console.error("Erreur lors de la suppression du contrat signé:", error);
      toast.error(error instanceof Error ? error.message : "Erreur lors de la suppression");
    } finally {
      setIsDeletingSignedPdf(false);
    }
  };
  
  // Handler pour le calendrier des dates de représentations
  // Ouvrir le modal de quantités pour permettre la précision par date
  const handleDatesRepresentationsApply = (result: {
    selectedDates: string[];
    hasMultiMonth: boolean;
    pdfFormatted: string;
  }) => {
    setPendingDates(result.selectedDates);
    setQuantityModalType("representations");
    setQuantityModalOpen(true);
  };

  // Handler pour le calendrier des dates de répétitions
  // Ouvrir le modal de quantités pour permettre la précision par date
  const handleDatesRepetitionsApply = (result: {
    selectedDates: string[];
    hasMultiMonth: boolean;
    pdfFormatted: string;
  }) => {
    setPendingDates(result.selectedDates);
    setQuantityModalType("repetitions");
    setQuantityModalOpen(true);
  };

  // Handler pour le calendrier des jours travaillés
  // Ouvrir le modal de quantités pour permettre la précision par date
  const handleJoursTravailApply = (result: {
    selectedDates: string[];
    hasMultiMonth: boolean;
    pdfFormatted: string;
  }) => {
    setPendingDates(result.selectedDates);
    setQuantityModalType("jours_travail");
    setQuantityModalOpen(true);
  };

  // Handler pour la modale de quantités (applique les données finales)
  const handleQuantityApply = (result: {
    selectedDates: string[];
    hasMultiMonth: boolean;
    pdfFormatted: string;
    totalQuantities?: number;
  }) => {
    // Calculer le nombre de jours/dates sélectionnées ou utiliser totalQuantities si disponible
    const nbDates = result.totalQuantities || result.selectedDates.length;
    
    switch (quantityModalType) {
      case "representations":
        setDatesRepresentations(result.pdfFormatted);
        setDatesRepresentationsDisplay(result.pdfFormatted);
        // Auto-remplir le nombre de représentations
        setNbRepresentations(nbDates);
        break;
      case "repetitions":
        // Ajouter la durée des services au texte formaté
        let formattedText = result.pdfFormatted;
        if (durationServices) {
          // Remplacer "service de répétition" par "service de répétition de X heures"
          formattedText = formattedText
            .replace(/service de répétition/g, `service de répétition de ${durationServices} heures`)
            .replace(/services de répétition/g, `services de répétition de ${durationServices} heures chacun`);
        }
        setDatesRepetitions(formattedText);
        setDatesRepetitionsDisplay(formattedText);
        // Auto-remplir le nombre de services de répétition
        setNbServicesRepetition(nbDates);
        break;
      case "jours_travail":
        console.log("📅 Jours travail - result:", result);
        setJoursTravail(result.pdfFormatted);
        setJoursTravailDisplay(result.pdfFormatted);
        console.log("📅 Jours travail mis à jour:", result.pdfFormatted);
        break;
    }
    setQuantityModalOpen(false);
    setPendingDates([]);
  };
  
  // Fonction pour ouvrir le PDF avec URL pré-signée
  const openPdf = async () => {
    try {
      const response = await fetch(`/api/contrats/${contract.id}/pdf-url`);
      if (!response.ok) {
        throw new Error("Erreur lors de la récupération de l'URL du PDF");
      }
      const data = await response.json();
      window.open(data.signedUrl, '_blank');
    } catch (error) {
      console.error("Erreur:", error);
      toast.error("Impossible d'ouvrir le PDF");
    }
  };

  const openSignedPdf = async () => {
    if (signedPdfData?.signedUrl) {
      window.open(signedPdfData.signedUrl, '_blank');
    } else {
      toast.error("URL du contrat signé non disponible");
    }
  };

  // Fonction pour déterminer l'état de la signature électronique
  const getSignatureStatus = () => {
    const etatDemande = form.etat_de_la_demande || contract.etat_de_la_demande;
    const contratSigneEmployeur = form.contrat_signe_par_employeur || contract.contrat_signe_par_employeur;
    const contratSigne = form.contrat_signe || contract.contrat_signe;

    if (etatDemande !== "Traitée") {
      return {
        status: "not_sent",
        label: "E-signature non envoyée",
        icon: XCircle,
        color: "text-gray-500",
        bgColor: "bg-gray-50",
        borderColor: "border-gray-200"
      };
    }

    if (contratSigneEmployeur === "Non") {
      return {
        status: "waiting_employer",
        label: "En attente employeur",
        icon: Clock,
        color: "text-orange-600",
        bgColor: "bg-orange-50",
        borderColor: "border-orange-200"
      };
    }

    if (contratSigneEmployeur === "Oui" && contratSigne === "Non") {
      return {
        status: "waiting_employee",
        label: "En attente salarié",
        icon: Users,
        color: "text-blue-600",
        bgColor: "bg-blue-50",
        borderColor: "border-blue-200"
      };
    }

    if (contratSigne === "Oui") {
      return {
        status: "completed",
        label: "E-signature finalisée",
        icon: CheckCircle2,
        color: "text-green-600",
        bgColor: "bg-green-50",
        borderColor: "border-green-200"
      };
    }

    // État par défaut
    return {
      status: "unknown",
      label: "Statut inconnu",
      icon: XCircle,
      color: "text-gray-500",
      bgColor: "bg-gray-50",
      borderColor: "border-gray-200"
    };
  };

  const [form, setForm] = useState<AnyObj>({
    role: contract.role ?? "",
    start_date: contract.start_date?.slice(0, 10) ?? "",
    end_date: contract.end_date?.slice(0, 10) ?? "",
    hours: contract.hours ?? "",
    gross_pay: contract.gross_pay ?? "",
    net_pay: contract.net_pay ?? "",
    contract_pdf_s3_key: contract.contract_pdf_s3_key ?? "",
    notes: contract.notes ?? "",
    etat_de_la_demande: contract.etat_de_la_demande ?? "",
    contrat_signe: contract.contrat_signe ?? "",
    contrat_signe_par_employeur: contract.contrat_signe_par_employeur ?? "",
    dpae: contract.dpae ?? "",
    etat_de_la_paie: contract.etat_de_la_paie ?? "",
    aem: contract.aem ?? "",
  });

  const [rows, setRows] = useState<AnyObj[]>(
    (payslips ?? []).map((p) => ({ ...p }))
  );
  
  // Stocker les valeurs initiales pour détecter les changements
  const initialValues = useMemo(() => ({
    // Form fields
    role: contract.role ?? "",
    start_date: contract.start_date?.slice(0, 10) ?? "",
    end_date: contract.end_date?.slice(0, 10) ?? "",
    hours: contract.hours ?? "",
    gross_pay: contract.gross_pay ?? "",
    net_pay: contract.net_pay ?? "",
    contract_pdf_s3_key: contract.contract_pdf_s3_key ?? "",
    notes: contract.notes ?? "",
    etat_de_la_demande: contract.etat_de_la_demande ?? "",
    contrat_signe: contract.contrat_signe ?? "",
    contrat_signe_par_employeur: contract.contrat_signe_par_employeur ?? "",
    dpae: contract.dpae ?? "",
    etat_de_la_paie: contract.etat_de_la_paie ?? "",
    aem: contract.aem ?? "",
    // CDDU fields
    spectacle: prefill.spectacle,
    numero_objet: prefill.numero_objet,
    salarie_nom: prefill.salarie_nom,
    salarie_matricule: prefill.salarie_matricule,
    categorie_pro: prefill.categorie,
    profession: prefill.profession,
    type_salaire: contract.type_salaire ?? "",
    salaire: contract.salaire ?? "",
    paniers_repas: contract.paniers_repas ?? "",
    reference: contract.reference ?? "",
    analytique: contract.analytique ?? "",
    date_signature: contract.date_signature ?? "",
    nb_representations: contract.cachets_representations ?? "",
    nb_services_repetition: contract.services_repetitions ?? "",
    dates_representations: contract.jours_representations ?? "",
    dates_repetitions: contract.jours_repetitions ?? "",
    heures_total: contract.nombre_d_heures ?? "",
    minutes_total: contract.minutes_total ?? "0",
    jours_travail: contract.jours_travail ?? "",
    jours_travail_non_artiste: contract.jours_travail_non_artiste ?? "",
    nombre_heures_total: contract.nombre_d_heures ?? "",
    nombre_heures_par_jour: contract.nombre_d_heures_par_jour ?? "",
    // Temps de travail réel
    jours_travail_reel: contract.jours_travail_reel ?? "",
    nb_representations_reel: contract.nb_representations_reel ?? "",
    nb_services_repetitions_reel: contract.nb_services_repetitions_reel ?? "",
    nb_heures_repetitions_reel: contract.nb_heures_repetitions_reel ?? "",
    nb_heures_annexes_reel: contract.nb_heures_annexes_reel ?? "",
    nb_cachets_aem_reel: contract.nb_cachets_aem_reel ?? "",
    nb_heures_aem_reel: contract.nb_heures_aem_reel ?? "",
  }), [contract, prefill]);

  // Déterminer le type de contrat pour l'affichage des paies
  const contractType = useMemo(() => {
    const typeContrat = contract.type_de_contrat || "";
    const isMultiMois = contract.multi_mois === true || contract.multi_mois === "true" || contract.multi_mois === "Oui";
    
    // RG = "CDD de droit commun" ou "CDI"
    if (typeContrat === "CDD de droit commun" || typeContrat === "CDI") {
      return "RG";
    }
    
    // CDDU multi-mois
    if (typeContrat === "CDD d'usage" && isMultiMois) {
      return "CDDU_MULTI";
    }
    
    // CDDU mono-mois (par défaut)
    return "CDDU_MONO";
  }, [contract.type_de_contrat, contract.multi_mois]);
  
  // État pour la pagination des paies (pour RG et CDDU multi)
  const [payslipPage, setPayslipPage] = useState(0);
  const payslipsPerPage = 6;
  
  // Trier et paginer les paies si nécessaire
  const displayedPayslips = useMemo(() => {
    const needsCompactView = contractType === "RG" || contractType === "CDDU_MULTI";
    
    // Trier par numéro de paie décroissant (plus récent en premier)
    const sorted = [...rows].sort((a, b) => {
      const numA = a.pay_number || 0;
      const numB = b.pay_number || 0;
      return numB - numA; // Décroissant
    });
    
    if (needsCompactView && sorted.length > payslipsPerPage) {
      const start = payslipPage * payslipsPerPage;
      const end = start + payslipsPerPage;
      return sorted.slice(start, end);
    }
    
    return sorted;
  }, [rows, contractType, payslipPage]);
  
  const totalPayslipPages = Math.ceil(rows.length / payslipsPerPage);
  const needsPagination = (contractType === "RG" || contractType === "CDDU_MULTI") && rows.length > payslipsPerPage;

  const [open, setOpen] = useState(false);

  // Search hooks
  const debouncedSpectacleQuery = useDebouncedValue(spectacleQuery, 300);
  const debouncedSalarieQuery = useDebouncedValue(salarieQuery, 300);
  const { data: spectacleSearch, isFetching: fetchingSpectacles } = useSearchSpectacles(debouncedSpectacleQuery);
  const { data: salarieSearch, isFetching: fetchingSalaries } = useSearchSalaries(debouncedSalarieQuery);

  // Hook pour récupérer l'URL pré-signée du contrat signé
  const { data: signedPdfData, isLoading: loadingSignedPdf } = useQuery({
    queryKey: ["signed-contract-pdf", contract.id],
    queryFn: async () => {
      const response = await fetch(`/api/staff/contrats/${contract.id}/signed-pdf`);
      if (!response.ok) {
        if (response.status === 404) {
          const errorData = await response.json();
          return { hasSignedPdf: false, error: errorData.error };
        }
        throw new Error('Erreur lors de la récupération du contrat signé');
      }
      return await response.json();
    },
    enabled: !!contract.id,
    staleTime: 5 * 60 * 1000, // 5 minutes
    retry: 1,
  });

  // Profession filtering
  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]);

  // Logique conditionnelle : heures pour techniciens, répétitions/représentations pour artistes
  const useHeuresMode = useMemo(() => {
    return (
      categoriePro === "Technicien" ||
      (categoriePro === "Artiste" && professionPick?.code === "MET040")
    );
  }, [categoriePro, professionPick]);
  // Auto-calculer le nombre d'heures total basé sur le nombre de services x durée
  useEffect(() => {
    if (!useHeuresMode && datesRepetitions) {
      // Extraire le nombre total de services depuis le texte formaté
      // Exemple: "1 service de répétition de 4 heures le 29/10 ; 2 services de répétition de 4 heures chacun le 30/10"
      // On doit sommer : 1 + 2 = 3
      let totalServices = 0;
      
      // Chercher tous les patterns "N service(s)"
      const servicePattern = /(\d+)\s+service/g;
      let match;
      while ((match = servicePattern.exec(datesRepetitions)) !== null) {
        totalServices += parseInt(match[1], 10);
      }
      
      if (totalServices > 0) {
        const duration = parseInt(durationServices);
        const totalHours = totalServices * duration;
        setNombreHeuresTotal(totalHours);
      }
    }
  }, [useHeuresMode, datesRepetitions, durationServices]);

  // Load technicians list
  async function ensureTechniciensLoaded() {
    if (techLoadedRef.current || techniciens) return;
    try {
      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;
    } catch (e) {
      console.warn("Could not load technicians:", e);
    }
  }

  // Functions for profession feminization
  const loadFeminisation = async (professionCode: string) => {
    try {
      const res = await fetch(`/api/professions-feminisations?code=${encodeURIComponent(professionCode)}`);
      if (!res.ok) return null;
      const data = await res.json();
      return data ? data.profession_feminine : null;
    } catch (error) {
      console.warn("Erreur lors du chargement de la féminisation:", error);
      return null;
    }
  };

  const saveFeminisation = async (professionCode: string, professionLabel: string, professionFeminine: string) => {
    try {
      const res = await fetch('/api/professions-feminisations', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          profession_code: professionCode,
          profession_label: professionLabel,
          profession_feminine: professionFeminine.trim()
        })
      });
      
      if (!res.ok) {
        const errorData = await res.json().catch(() => ({}));
        throw new Error(errorData.error || `HTTP ${res.status}`);
      }
      
      const result = await res.json();
      console.log("✅ Féminisation sauvegardée avec succès:", result);
      return true;
    } catch (error) {
      console.error("❌ Erreur lors de la sauvegarde de la féminisation:", error);
      throw error;
    }
  };

  // Load technicians on mount if needed
  useEffect(() => {
    if (categoriePro === "Technicien") {
      ensureTechniciensLoaded();
    }
  }, []); // Déclenché au montage initial

  // Load technicians when category changes to Technicien
  useEffect(() => {
    if (categoriePro === "Technicien") {
      ensureTechniciensLoaded();
    }
  }, [categoriePro]);

  // Resolve profession code if missing (for technicians)
  useEffect(() => {
    if (professionPick && !professionPick.code && categoriePro === "Technicien" && techniciens) {
      const technicienProfession = techniciens.find(p => 
        p.label.toLowerCase() === professionPick.label.toLowerCase()
      );
      if (technicienProfession) {
        console.log("🔧 Resolving technicien profession code:", technicienProfession);
        setProfessionPick(technicienProfession);
      }
    }
  }, [professionPick, categoriePro, techniciens]);

  // Load feminization when profession changes
  useEffect(() => {
    if (professionPick?.code) {
      loadFeminisation(professionPick.code).then(feminine => {
        if (feminine) {
          setProfessionFeminine(feminine);
        } else {
          setProfessionFeminine("");
        }
      });
    } else {
      setProfessionFeminine("");
    }
  }, [professionPick]);

  // Save feminization when profession feminine is changed
  const handleFeminineChange = (value: string) => {
    console.log("📝 handleFeminineChange called with:", value);
    setProfessionFeminine(value);
  };

  // Manual save feminization function  
  const saveCurrentFeminisation = async () => {
    console.log("🔧 saveCurrentFeminisation called");
    console.log("📊 Current state:", {
      professionPick,
      professionFeminine: `"${professionFeminine}"`,
      professionFeminineTrimmed: `"${professionFeminine.trim()}"`,
      hasCode: !!professionPick?.code,
      hasLabel: !!professionPick?.label,
      hasTrimmedFeminine: !!professionFeminine.trim()
    });
    
    // Ensure technicians are loaded if needed
    if (categoriePro === "Technicien") {
      await ensureTechniciensLoaded();
    }
    
    // Fallback: try to resolve code if missing
    let codeToUse = professionPick?.code;
    if (!codeToUse && professionPick?.label) {
      console.log("🔍 Trying to resolve missing code for:", professionPick.label);
      
      // Check in artiste professions
      const artisteProfession = PROFESSIONS_ARTISTE.find(p => 
        p.label.toLowerCase() === professionPick.label.toLowerCase()
      );
      if (artisteProfession) {
        codeToUse = artisteProfession.code;
        console.log("✅ Found artiste code:", codeToUse);
      }
      
      // Check in technicien professions if loaded
      if (!codeToUse && techniciens) {
        const technicienProfession = techniciens.find(p => 
          p.label.toLowerCase() === professionPick.label.toLowerCase()
        );
        if (technicienProfession) {
          codeToUse = technicienProfession.code;
          console.log("✅ Found technicien code:", codeToUse);
        }
      }
    }
    
    if (!codeToUse || !professionPick?.label || !professionFeminine.trim()) {
      console.log("❌ Missing required data - detailed check:");
      console.log("  - resolved code:", codeToUse);
      console.log("  - professionPick?.label:", professionPick?.label);
      console.log("  - professionFeminine.trim():", `"${professionFeminine.trim()}"`);
      toast.error("Veuillez sélectionner une profession et saisir sa forme féminine");
      return;
    }

    console.log("✅ Starting save process with code:", codeToUse);
    setIsSavingFeminisation(true);
    
    try {
      await saveFeminisation(codeToUse, professionPick.label, professionFeminine);
      toast.success(`Féminisation sauvegardée : "${professionFeminine}"`);
      console.log("✅ Féminisation sauvegardée avec succès");
    } catch (error) {
      console.error("❌ Erreur:", error);
      toast.error("Erreur lors de la sauvegarde de la féminisation");
    } finally {
      setIsSavingFeminisation(false);
    }
  };
  
  // Détecter les modifications pour activer/désactiver le bouton Enregistrer
  useEffect(() => {
    // Comparer les champs du form
    let hasFormChanges = false;
    for (const key in form) {
      const initialValue = initialValues[key as keyof typeof initialValues];
      const currentValue = form[key];
      
      const normalizedInitial = initialValue === null || initialValue === undefined ? "" : String(initialValue);
      const normalizedCurrent = currentValue === null || currentValue === undefined ? "" : String(currentValue);
      
      if (normalizedInitial !== normalizedCurrent) {
        hasFormChanges = true;
        break;
      }
    }
    
    // Comparer les champs CDDU
    const hasCDDUChanges = 
      (spectaclePick?.nom ?? "") !== (initialValues.spectacle ?? "") ||
      (spectaclePick?.numero_objet ?? "") !== (initialValues.numero_objet ?? "") ||
      (salarie?.nom ?? "") !== (initialValues.salarie_nom ?? "") ||
      (salarie?.matricule ?? "") !== (initialValues.salarie_matricule ?? "") ||
      categoriePro !== (initialValues.categorie_pro ?? "") ||
      (professionPick?.label ?? "") !== (initialValues.profession ?? "") ||
      typeSalaire !== (initialValues.type_salaire ?? "") ||
      String(montant) !== String(initialValues.salaire ?? "") ||
      panierRepas !== (initialValues.paniers_repas ?? "") ||
      reference !== (initialValues.reference ?? "") ||
      analytique !== (initialValues.analytique ?? "") ||
      dateSignature !== (initialValues.date_signature ?? "") ||
      String(nbRepresentations) !== String(initialValues.nb_representations ?? "") ||
      String(nbServicesRepetition) !== String(initialValues.nb_services_repetition ?? "") ||
      datesRepresentations !== (initialValues.dates_representations ?? "") ||
      datesRepetitions !== (initialValues.dates_repetitions ?? "") ||
      String(heuresTotal) !== String(initialValues.heures_total ?? "") ||
      minutesTotal !== (initialValues.minutes_total ?? "0") ||
      joursTravail !== (initialValues.jours_travail ?? "") ||
      String(nombreHeuresTotal) !== String(initialValues.nombre_heures_total ?? "") ||
      String(nombreHeuresParJour) !== String(initialValues.nombre_heures_par_jour ?? "") ||
      joursTravailReel !== (initialValues.jours_travail_reel ?? "") ||
      String(nbRepresentationsReel) !== String(initialValues.nb_representations_reel ?? "") ||
      String(nbServicesRepetitionsReel) !== String(initialValues.nb_services_repetitions_reel ?? "") ||
      String(nbHeuresRepetitionsReel) !== String(initialValues.nb_heures_repetitions_reel ?? "") ||
      String(nbHeuresAnnexesReel) !== String(initialValues.nb_heures_annexes_reel ?? "") ||
      String(nbCachetsAemReel) !== String(initialValues.nb_cachets_aem_reel ?? "") ||
      String(nbHeuresAemReel) !== String(initialValues.nb_heures_aem_reel ?? "");

    setHasUnsavedChanges(hasFormChanges || hasCDDUChanges);
  }, [
    form, spectaclePick, salarie, categoriePro, professionPick, typeSalaire, montant,
    panierRepas, reference, analytique, dateSignature, nbRepresentations, nbServicesRepetition,
    datesRepresentations, datesRepetitions, heuresTotal, minutesTotal, joursTravail,
    nombreHeuresTotal, nombreHeuresParJour, joursTravailReel, nbRepresentationsReel,
    nbServicesRepetitionsReel, nbHeuresRepetitionsReel, nbHeuresAnnexesReel,
    nbCachetsAemReel, nbHeuresAemReel, initialValues
  ]);

  const nextPayNumber = useMemo(
    () => (rows?.length ? Math.max(...rows.map((r) => Number(r.pay_number) || 0)) + 1 : 1),
    [rows]
  );

  const handleContractChange = (key: string, value: any) => {
    setForm((f: AnyObj) => ({ ...f, [key]: value }));
  };

  const saveContract = async () => {
    setIsSaving(true);
    try {
      const payload: AnyObj = {
        ...form,
        start_date: form.start_date || null,
        end_date: form.end_date || null,
        // CDDU fields - searchable/selectable
        production_id: spectaclePick?.id || null,
        production_name: spectaclePick?.nom || "",
        objet_spectacle: spectaclePick?.numero_objet || "",
        employee_name: salarie?.nom || "",
        employee_matricule: salarie?.matricule || "",
        categorie_pro: categoriePro,
        profession: professionPick?.label || professionQuery || "",
        // CDDU fields - manual inputs (nouvellement modifiables)
        type_salaire: typeSalaire || null,
        salaire: montant ? parseFloat(montant) : null,
        paniers_repas: panierRepas || null,
        reference: reference || null,
        analytique: analytique || null,
        date_signature: dateSignature || null,
        // Conditional fields based on category
        // Pour les metteurs en scène, garder nb_representations même en mode heures
        nb_representations: (useHeuresMode && professionPick?.code !== "MET040") ? null : nbRepresentations || null,
        nb_services_repetition: useHeuresMode ? null : nbServicesRepetition || null,
        dates_representations: useHeuresMode ? null : datesRepresentations || null,
        dates_repetitions: useHeuresMode ? null : datesRepetitions || null,
        heures_total: useHeuresMode ? heuresTotal || null : null,
        minutes_total: useHeuresMode ? minutesTotal : null,
        precisions_salaire: precisionsSalaire || null, // Nouveau champ pour précisions salaire
        autreprecision_duree: autrePrecisionDuree ? autrePrecisionDuree : null, // Autre précision durée
        autreprecision_salaire: autrePrecisionSalaire ? autrePrecisionSalaire : null, // Autre précision salaire
        // Map to database fields
        // Pour les metteurs en scène, garder nb_representations même en mode heures
        cachets_representations: (useHeuresMode && professionPick?.code !== "MET040") ? null : nbRepresentations || null,
        services_repetitions: useHeuresMode ? null : nbServicesRepetition || null,
        nombre_d_heures: useHeuresMode ? heuresTotal || null : nombreHeuresTotal || null,
        nombre_d_heures_par_jour: nombreHeuresParJour || null,
        jours_representations: useHeuresMode ? null : datesRepresentations || null,
        jours_repetitions: useHeuresMode ? null : datesRepetitions || null,
        // Envoyer jours_travail_non_artiste en mode heures (technicien ou metteur en scène)
        jours_travail_non_artiste: useHeuresMode ? ((typeof joursTravail === "string" && joursTravail.trim() === "") ? null : (joursTravail || null)) : null,
        // Envoyer jours_travail en mode artiste classique (représentations/répétitions)
        jours_travail: !useHeuresMode ? ((typeof joursTravail === "string" && joursTravail.trim() === "") ? null : (joursTravail || null)) : null,
        panier_repas: panierRepas || null,
        n_objet: spectaclePick?.numero_objet || null,
        brut: typeSalaire === "Brut" ? parseMonetaryAmount(montant) : null,
        // Le champ gross_pay correspond au champ "Brut" de l'interface utilisateur
        gross_pay: parseMonetaryAmount(form.gross_pay),
        // Temps de travail réel (informatif pour le client)
        jours_travail_reel: joursTravailReel || null,
        nb_representations_reel: nbRepresentationsReel || null,
        nb_services_repetitions_reel: nbServicesRepetitionsReel || null,
        nb_heures_repetitions_reel: nbHeuresRepetitionsReel || null,
        nb_heures_annexes_reel: nbHeuresAnnexesReel || null,
        nb_cachets_aem_reel: nbCachetsAemReel || null,
        nb_heures_aem_reel: nbHeuresAemReel || null,
      };
      
      console.log("💾 États actuels avant sauvegarde:", {
        nbRepresentations,
        nbServicesRepetition, 
        datesRepresentations,
        datesRepetitions,
        heuresTotal,
        minutesTotal,
        joursTravail,
        joursTravailDisplay,
        useHeuresMode,
        categoriePro,
        professionCode: professionPick?.code,
        autrePrecisionDuree,
        autrePrecisionSalaire,
        precisionsSalaire
      });
      
      console.log("💾 Sauvegarde contrat - payload:", payload);
      console.log("💾 Champs jours_travail dans le payload:", {
        jours_travail: payload.jours_travail,
        jours_travail_non_artiste: payload.jours_travail_non_artiste
      });
      const res = await fetch(`/api/staff/contracts/${contract.id}`, {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ contract: payload }),
      });
      const j = await res.json();
      if (!res.ok) {
        toast.error(j.error ?? "Erreur lors de la mise à jour du contrat");
        return;
      }
      
      setShowSaveSuccess(true);
      setHasUnsavedChanges(false); // Réinitialiser le tracking des modifications
      toast.success("Contrat mis à jour");
    } catch (error) {
      console.error("Erreur lors de la sauvegarde:", error);
      toast.error("Erreur lors de la sauvegarde du contrat");
    } finally {
      setIsSaving(false);
    }
  };

  const savePayslips = async () => {
    const sanitized = rows.map((r) => ({
      ...r,
      period_start: r.period_start?.slice?.(0, 10) ?? r.period_start,
      period_end: r.period_end?.slice?.(0, 10) ?? r.period_end,
      period_month: r.period_month?.slice?.(0, 10) ?? r.period_month,
      pay_date: r.pay_date ? r.pay_date.slice(0, 10) : null,
      processed: Boolean(r.processed),
      transfer_done: Boolean(r.transfer_done),
      contract_id: contract.id,
    }));
    const res = await fetch(`/api/staff/contracts/${contract.id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ payslips: sanitized }),
    });
    const j = await res.json();
    if (!res.ok) {
      toast.error(j.error ?? "Erreur lors de l’enregistrement des payslips");
      return;
    }
    setRows(j.payslips ?? []);
    toast.success("Payslips enregistrés");
  };

  const onCreatePayslip = async (payload: AnyObj) => {
    const res = await fetch(`/api/staff/contracts/${contract.id}`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ payslip: payload }),
    });
    const j = await res.json();
    if (!res.ok) {
      toast.error(j.error ?? "Erreur lors de l’ajout");
      return;
    }
    setRows((prev) => [...prev, j.payslip].sort((a, b) => (a.pay_number ?? 0) - (b.pay_number ?? 0)));
    toast.success("Payslip ajouté");
    setOpen(false);
  };

  const generatePdf = async () => {
    setIsGeneratingPdf(true);
    try {
      const response = await fetch(`/api/contrats/${contract.id}/generate-pdf`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.error || `Erreur ${response.status}`);
      }

      const result = await response.json();
      
      console.log("PDF généré:", result);
      
      // Mettre à jour les états locaux pour afficher le PDF sans rafraîchir la page
      if (result.contract_pdf_url) {
        setContractPdfUrl(result.contract_pdf_url);
      }
      if (result.contract_pdf_filename) {
        setContractPdfFilename(result.contract_pdf_filename);
      }
      
      setShowPdfSuccess(true);
      toast.success("PDF créé avec succès !");
    } catch (error) {
      console.error("Erreur lors de la génération du PDF:", error);
      toast.error(
        error instanceof Error 
          ? error.message 
          : "Erreur lors de la génération du PDF"
      );
    } finally {
      setIsGeneratingPdf(false);
    }
  };

  const launchElectronicSignature = async (sendNotification: boolean = true) => {
    console.log("🚀 [SIGNATURE] Fonction déclenchée");
    console.log("🚀 [SIGNATURE] contract.contract_pdf_filename:", contract.contract_pdf_filename);
    console.log("🚀 [SIGNATURE] salarie?.email:", salarie?.email);
    console.log("🚀 [SIGNATURE] sendNotification:", sendNotification);
    
    setIsLaunchingSignature(true);
    try {
      // Vérifier que le contrat a un PDF généré
      if (!contract.contract_pdf_filename) {
        toast.error("Veuillez d'abord générer le PDF du contrat");
        return;
      }

      // ========================================
      // 🔒 SÉCURITÉ MAXIMALE : Récupération et validation de l'email du salarié
      // ========================================
      let employeeEmail = salarie?.email;
      let verifiedEmployeeName = "";
      
      if (!employeeEmail) {
        console.log("🔍 [SIGNATURE] Email non trouvé dans salarie, recherche dans la base...");
        
        // 🛡️ VÉRIFICATION 1 : Le matricule doit être présent
        if (!contract.employee_matricule) {
          toast.error("❌ SÉCURITÉ : Le matricule du salarié est manquant dans le contrat. Signature annulée.");
          console.error("❌ [SIGNATURE] SÉCURITÉ : Matricule manquant");
          return;
        }
        
        // Normaliser le matricule (trim + conversion en string)
        const matricule = String(contract.employee_matricule).trim();
        console.log(`🔍 [SIGNATURE] Recherche EXACTE par matricule (code_salarie): "${matricule}" (type: ${typeof matricule}, longueur: ${matricule.length})`);
        
        // 🛡️ VÉRIFICATION 2 : Recherche EXACTE par code_salarie (même méthode que bulk-esign)
        const { data: salarieData, error: salarieError } = await supabase
          .from('salaries')
          .select('adresse_mail, nom, prenom, code_salarie, employer_id')
          .eq('code_salarie', matricule)
          .maybeSingle();
        
        if (salarieError) {
          console.error("❌ [SIGNATURE] Erreur Supabase lors de la recherche du salarié:", salarieError);
          toast.error("❌ Erreur lors de la recherche du salarié. Signature annulée.");
          return;
        }
        
        if (!salarieData) {
          console.error(`❌ [SIGNATURE] SÉCURITÉ : Aucun salarié trouvé pour le matricule: ${matricule}`);
          toast.error(`❌ SÉCURITÉ : Aucun salarié trouvé avec le matricule ${matricule}. Vérifiez les données du contrat.`);
          return;
        }
        
        // 🛡️ VÉRIFICATION 3 : L'email doit exister
        employeeEmail = salarieData.adresse_mail;
        if (!employeeEmail) {
          console.error(`❌ [SIGNATURE] SÉCURITÉ : Email manquant pour le salarié ${salarieData.prenom} ${salarieData.nom}`);
          toast.error(`❌ SÉCURITÉ : Le salarié ${salarieData.prenom} ${salarieData.nom} n'a pas d'email renseigné. Ajoutez un email avant de lancer la signature.`);
          return;
        }
        
        // 🛡️ VÉRIFICATION 4 : Le salarié doit appartenir à la même organisation que le contrat
        if (contract.org_id && salarieData.employer_id && salarieData.employer_id !== contract.org_id) {
          console.error(`❌ [SIGNATURE] SÉCURITÉ : Le salarié (org: ${salarieData.employer_id}) n'appartient pas à l'organisation du contrat (org: ${contract.org_id})`);
          toast.error(`❌ SÉCURITÉ : Le salarié ${salarieData.prenom} ${salarieData.nom} n'appartient pas à l'organisation de ce contrat. Signature annulée.`);
          return;
        }
        
        verifiedEmployeeName = `${salarieData.prenom || ''} ${salarieData.nom || ''}`.trim();
        console.log(`✅ [SIGNATURE] VALIDÉ : Email trouvé et vérifié`);
        console.log(`   - Salarié: ${verifiedEmployeeName}`);
        console.log(`   - Matricule: ${salarieData.code_salarie}`);
        console.log(`   - Email: ${employeeEmail}`);
        console.log(`   - Organisation: ${salarieData.employer_id}`);
      } else {
        // Email déjà présent dans l'état local, récupérer le nom pour la vérification
        verifiedEmployeeName = salarie?.nom || contract.employee_name || "";
        console.log(`✅ [SIGNATURE] Email déjà présent dans l'état local: ${employeeEmail}`);
      }

      // 🛡️ VÉRIFICATION 5 : L'email doit avoir un format valide
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(employeeEmail)) {
        console.error(`❌ [SIGNATURE] SÉCURITÉ : Format d'email invalide: ${employeeEmail}`);
        toast.error(`❌ SÉCURITÉ : Le format de l'email du salarié est invalide (${employeeEmail}). Signature annulée.`);
        return;
      }

      // 🛡️ VÉRIFICATION 6 : Récupération du prénom du salarié depuis la base de données
      let employeeFirstName = salarie?.prenom || "";
      
      if (!employeeFirstName && contract.employee_matricule) {
        console.log("🔍 [SIGNATURE] Récupération du prénom depuis la base de données...");
        const matricule = String(contract.employee_matricule).trim();
        
        const { data: prenomData, error: prenomError } = await supabase
          .from('salaries')
          .select('prenom')
          .eq('code_salarie', matricule)
          .maybeSingle();
        
        if (prenomData?.prenom) {
          employeeFirstName = prenomData.prenom;
          console.log(`✅ [SIGNATURE] Prénom trouvé: ${employeeFirstName}`);
        } else {
          console.error(`❌ [SIGNATURE] Prénom non trouvé pour le matricule ${matricule}`);
          toast.error(`Le prénom du salarié est manquant dans la base de données. Veuillez le renseigner avant de lancer la signature.`);
          return;
        }
      }
      
      if (!employeeFirstName) {
        console.error(`❌ [SIGNATURE] Prénom du salarié manquant`);
        toast.error(`Le prénom du salarié est manquant. Veuillez le renseigner avant de lancer la signature.`);
        return;
      }

      // 🛡️ VÉRIFICATION 7 : Confirmation finale avant envoi
      console.log("🔒 [SIGNATURE] VÉRIFICATIONS DE SÉCURITÉ RÉUSSIES");
      console.log(`   ✓ Matricule vérifié: ${contract.employee_matricule}`);
      console.log(`   ✓ Salarié identifié: ${verifiedEmployeeName}`);
      console.log(`   ✓ Prénom: ${employeeFirstName}`);
      console.log(`   ✓ Email validé: ${employeeEmail}`);
      console.log(`   ✓ Organisation vérifiée: ${contract.org_id}`);
      console.log(`   ✓ Contrat: ${contract.contract_number || contract.id}`);

      // Récupérer les informations de l'organisation active (ou du contrat pour les staff)
      console.log("🏢 [SIGNATURE] Récupération des infos organisation...");
      
      let employerEmail = "";
      let signerName = "";
      let organizationName = "";
      let employerCode = "";
      
      const orgResponse = await fetch('/api/me');
      const orgData = await orgResponse.json();
      
      console.log("🏢 [SIGNATURE] Réponse /api/me:", JSON.stringify(orgData, null, 2));
      
      if (orgData.is_staff) {
        // Pour les staff, récupérer les infos depuis l'organisation du contrat
        console.log("👨‍💼 [SIGNATURE] Utilisateur staff - récupération des infos du contrat...");
        console.log("👨‍💼 [SIGNATURE] contract.org_id:", contract.org_id);
        
        // Appel API pour récupérer les détails de l'organisation du contrat
        const contractOrgResponse = await fetch(`/api/organizations/${contract.org_id}/details`);
        
        if (contractOrgResponse.ok) {
          const contractOrgData = await contractOrgResponse.json();
          console.log("🏢 [SIGNATURE] Détails organisation contrat:", contractOrgData);
          
          employerEmail = contractOrgData.email_signature || contractOrgData.email_contact || "paie@odentas.fr";
          signerName = `${contractOrgData.prenom_signataire || ""} ${contractOrgData.nom_signataire || ""}`.trim() || "Responsable";
          organizationName = contractOrgData.structure || contract.production_name || "Organisation";
          employerCode = contractOrgData.code_employeur || "DEMO";
        } else {
          // Fallback avec les valeurs du contrat
          console.log("⚠️ [SIGNATURE] Impossible de récupérer les détails org, utilisation des valeurs par défaut");
          employerEmail = "paie@odentas.fr";
          signerName = "Responsable";
          organizationName = contract.production_name || "Organisation";
          employerCode = "DEMO";
        }
      } else {
        // Pour les clients normaux, récupérer les infos depuis leur organisation active
        console.log("👤 [SIGNATURE] Utilisateur client - récupération des infos de l'organisation active...");
        console.log("👤 [SIGNATURE] orgData.active_org_id:", orgData.active_org_id);
        
        // Appel API pour récupérer les détails de l'organisation active du client
        const clientOrgResponse = await fetch(`/api/organizations/${orgData.active_org_id}/details`);
        
        if (clientOrgResponse.ok) {
          const clientOrgData = await clientOrgResponse.json();
          console.log("🏢 [SIGNATURE] Détails organisation client:", clientOrgData);
          
          employerEmail = clientOrgData.email_signature || clientOrgData.email_contact || "paie@odentas.fr";
          signerName = `${clientOrgData.prenom_signataire || ""} ${clientOrgData.nom_signataire || ""}`.trim() || "Responsable";
          organizationName = clientOrgData.structure || orgData.active_org_name || "Organisation";
          employerCode = clientOrgData.code_employeur || "CLIENT";
        } else {
          // Fallback avec les valeurs par défaut
          console.log("⚠️ [SIGNATURE] Impossible de récupérer les détails org client, utilisation des valeurs par défaut");
          employerEmail = "paie@odentas.fr";
          signerName = "Responsable";
          organizationName = orgData.active_org_name || "Organisation";
          employerCode = "CLIENT";
        }
      }
      
      console.log("✅ [SIGNATURE] Informations finales:", {
        employerEmail,
        signerName,
        organizationName,
        employerCode
      });

      // Construire la clé S3 du PDF généré
      const pdfS3Key = `unsigned-contracts/${contract.contract_pdf_filename}`;

      const signatureData = {
        contractId: contract.id,
        pdfS3Key: pdfS3Key, // Utilisation du PDF généré et stocké dans Documents
        employerEmail: employerEmail,
        employeeEmail: employeeEmail,
        reference: reference || contract.reference || contract.contract_number,
        employeeName: salarie?.nom || contract.employee_name,
        startDate: form.start_date || contract.start_date,
        role: professionPick?.label || contract.profession || contract.role,
        analytique: analytique || contract.analytique || contract.production_name,
        structure: organizationName,
        signerFirstName: signerName,
        employerCode: employerCode,
        employeeFirstName: employeeFirstName,
        matricule: salarie?.code_salarie || salarie?.matricule || contract.employee_matricule,
        contractType: 'CDDU',
        orgId: contract.org_id, // Passer l'org_id pour récupérer la signature
        skipEmployerEmail: true, // Ne pas envoyer l'email individuel, seulement le récapitulatif si demandé
      };

      console.log("📤 [SIGNATURE] Données envoyées:", signatureData);

      console.log("🌐 [SIGNATURE] Appel API docuseal-signature...");
      const response = await fetch('/api/docuseal-signature', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(signatureData),
      });

      console.log("🌐 [SIGNATURE] Réponse HTTP:", response.status, response.statusText);

      if (!response.ok) {
        const errorData = await response.json();
        console.error("❌ [SIGNATURE] Erreur API DocuSeal:", {
          status: response.status,
          statusText: response.statusText,
          errorData: errorData
        });
        throw new Error(errorData.error || `Erreur ${response.status}`);
      }

      const result = await response.json();
      
      toast.success("Signature électronique lancée avec succès !");
      console.log("Signature électronique initiée:", result);
      
      // Envoyer l'email de notification au client si demandé
      if (sendNotification && contract.org_id) {
        console.log("📧 [SIGNATURE] Envoi de l'email de notification au client...");
        try {
          const notificationResponse = await fetch('/api/staff/contracts/send-esign-notification', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              organizationId: contract.org_id,
              contractCount: 1
            }),
          });

          if (notificationResponse.ok) {
            console.log("✅ [SIGNATURE] Email de notification envoyé avec succès");
          } else {
            const errorData = await notificationResponse.json();
            console.error("⚠️ [SIGNATURE] Erreur lors de l'envoi de la notification:", errorData);
            // Ne pas faire échouer toute l'opération si l'email de notif ne part pas
            toast.warning("Signature créée, mais l'email de notification n'a pas pu être envoyé");
          }
        } catch (notifError) {
          console.error("⚠️ [SIGNATURE] Exception lors de l'envoi de la notification:", notifError);
          // Ne pas faire échouer toute l'opération si l'email de notif ne part pas
        }
      }
      
      // Optionnel : rafraîchir les données du contrat
      setTimeout(() => {
        window.location.reload();
      }, 2000);
      
    } catch (error) {
      console.error("Erreur lors du lancement de la signature électronique:", error);
      toast.error(
        error instanceof Error 
          ? error.message 
          : "Erreur lors du lancement de la signature électronique"
      );
    } finally {
      setIsLaunchingSignature(false);
      setShowESignConfirmModal(false);
    }
  };
  
  // Handler for opening the e-sign confirmation modal
  const handleESignButtonClick = async () => {
    // Récupérer et vérifier l'email du salarié AVANT d'ouvrir le modal
    let employeeEmail = salarie?.email;
    
    if (!employeeEmail) {
      console.log("🔍 [MODAL] Recherche de l'email du salarié...");
      console.log("🔍 [MODAL] Contrat:", { 
        id: contract.id, 
        employee_matricule: contract.employee_matricule,
        employee_name: contract.employee_name,
        org_id: contract.org_id 
      });
      
      if (!contract.employee_matricule) {
        toast.error("❌ SÉCURITÉ : Le matricule du salarié est manquant dans le contrat.");
        return;
      }
      
      // Normaliser le matricule (trim + conversion en string)
      const matricule = String(contract.employee_matricule).trim();
      console.log(`🔍 [MODAL] Recherche EXACTE par matricule (code_salarie): "${matricule}" (type: ${typeof matricule}, longueur: ${matricule.length})`);
      
      const { data: salarieData, error: salarieError } = await supabase
        .from('salaries')
        .select('adresse_mail, code_salarie, employer_id, nom, prenom')
        .eq('code_salarie', matricule)
        .maybeSingle();
      
      if (salarieError) {
        console.error("❌ [MODAL] Erreur Supabase lors de la recherche du salarié:", salarieError);
        toast.error("❌ Impossible de trouver le salarié. Vérifiez les données du contrat.");
        return;
      }
      
      if (!salarieData) {
        console.error(`❌ [MODAL] Aucun salarié trouvé pour le matricule: ${matricule}`);
        toast.error("❌ Impossible de trouver le salarié. Vérifiez les données du contrat.");
        return;
      }
      
      console.log("✅ [MODAL] Salarié trouvé:", salarieData);
      
      employeeEmail = salarieData.adresse_mail;
      
      if (!employeeEmail) {
        toast.error("❌ Le salarié n'a pas d'email renseigné.");
        return;
      }
      
      // Vérifier l'organisation
      if (contract.org_id && salarieData.employer_id && salarieData.employer_id !== contract.org_id) {
        toast.error("❌ SÉCURITÉ : Le salarié n'appartient pas à l'organisation de ce contrat.");
        return;
      }
      
      // Valider le format
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(employeeEmail)) {
        toast.error(`❌ SÉCURITÉ : Le format de l'email est invalide (${employeeEmail}).`);
        return;
      }
      
      console.log(`✅ [MODAL] Email vérifié: ${employeeEmail}`);
    }
    
    // Récupérer l'email de l'employeur pour les signatures
    let employerEmail = "";
    
    if (!contract.org_id) {
      toast.error("❌ ID d'organisation manquant dans le contrat.");
      return;
    }
    
    try {
      console.log("🔍 [MODAL] Recherche de l'email de l'employeur...");
      const response = await fetch(`/api/organizations/${contract.org_id}/details`);
      
      if (!response.ok) {
        throw new Error(`Erreur ${response.status}`);
      }
      
      const orgData = await response.json();
      employerEmail = orgData.email_signature || orgData.email_contact || "paie@odentas.fr";
      
      console.log(`✅ [MODAL] Email employeur vérifié: ${employerEmail}`);
    } catch (error) {
      console.error("❌ [MODAL] Erreur lors de la récupération de l'email employeur:", error);
      toast.error("❌ Impossible de récupérer l'email de l'employeur.");
      return;
    }
    
    setVerifiedEmployeeEmail(employeeEmail);
    setVerifiedEmployerEmail(employerEmail);
    setShowESignConfirmModal(true);
  };
  
  // Handler for confirming the e-sign launch
  const handleConfirmESign = (sendNotification: boolean) => {
    setSendESignNotification(sendNotification);
    launchElectronicSignature(sendNotification);
  };
  
  // Payslip modal functions
  const handleOpenPayslipModal = (payslip?: any) => {
    setEditingPayslip(payslip || null);
    setIsPayslipModalOpen(true);
  };

  const handleClosePayslipModal = () => {
    setIsPayslipModalOpen(false);
    setEditingPayslip(null);
  };

  const handlePayslipModalSuccess = () => {
    // Refresh the payslips data
    window.location.reload(); // Pour l'instant, on recharge. Idéalement on ferait un refetch
  };

  // Fonction pour rafraîchir les payslips après un upload
  const handlePayslipUploadComplete = async () => {
    try {
      // Recharger les payslips depuis la base de données
      const response = await fetch(`/api/staff/payslips?contract_id=${contract.id}`);
      if (response.ok) {
        const data = await response.json();
        setRows(data.payslips ?? []);
        toast.success("Données mises à jour");
      }
    } catch (error) {
      console.error("Erreur lors du rafraîchissement des payslips:", error);
      // En cas d'erreur, on recharge la page
      window.location.reload();
    }
  };

  // Fonction pour marquer le contrat comme non signé
  const [isMarkingUnsigned, setIsMarkingUnsigned] = useState(false);
  
  const handleMarkAsUnsigned = async () => {
    if (isMarkingUnsigned) return;

    try {
      setIsMarkingUnsigned(true);
      
      const response = await fetch(`/api/staff/contrats/${contract.id}/mark-unsigned`, {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.error || `Erreur ${response.status}`);
      }

      const result = await response.json();
      
      toast.success(result.message || "Contrat marqué comme non signé avec succès !");
      
      // Mettre à jour l'état local du formulaire
      setForm(prev => ({
        ...prev,
        contrat_signe: "Non",
        contrat_signe_par_employeur: "Non"
      }));
      
      // Optionnel : rafraîchir après un délai
      setTimeout(() => {
        window.location.reload();
      }, 1500);
      
    } catch (error) {
      console.error("Erreur lors du marquage comme non signé:", error);
      toast.error(
        error instanceof Error 
          ? error.message 
          : "Erreur lors du marquage comme non signé"
      );
    } finally {
      setIsMarkingUnsigned(false);
    }
  };

  // Vérifier si le bouton doit être désactivé (les deux colonnes sont déjà "Non")
  const isBothUnsigned = (form.contrat_signe || contract.contrat_signe) === "Non" && 
                         (form.contrat_signe_par_employeur || contract.contrat_signe_par_employeur) === "Non";

  // États et fonctions pour la relance employeur
  const [isReminderModalOpen, setIsReminderModalOpen] = useState(false);
  const [isSendingReminder, setIsSendingReminder] = useState(false);
  const [organizationData, setOrganizationData] = useState<{
    email_signature?: string;
    organization_name?: string;
    organization_code?: string;
  } | null>(null);
  const [isLoadingOrgData, setIsLoadingOrgData] = useState(false);

  const fetchOrganizationData = async () => {
    if (!contract.org_id) {
      toast.error("ID d'organisation manquant dans le contrat");
      return false;
    }

    try {
      setIsLoadingOrgData(true);
      
      // Utiliser l'API existante ou créer une requête directe
      const response = await fetch(`/api/organizations/${contract.org_id}/details`, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        throw new Error(`Erreur ${response.status}`);
      }

      const result = await response.json();
      setOrganizationData(result);
      return true;
      
    } catch (error) {
      console.error("Erreur lors de la récupération des données d'organisation:", error);
      toast.error("Impossible de récupérer les données de l'organisation");
      return false;
    } finally {
      setIsLoadingOrgData(false);
    }
  };

  const handleOpenReminderModal = async () => {
    const success = await fetchOrganizationData();
    if (success) {
      setIsReminderModalOpen(true);
    }
  };

  const handleCloseReminderModal = () => {
    setIsReminderModalOpen(false);
  };

  const handleSendEmployerReminder = async () => {
    if (isSendingReminder) return;

    try {
      setIsSendingReminder(true);

      const response = await fetch(`/api/staff/contrats/${contract.id}/remind-employer`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
      });

      if (!response.ok) {
        const errorData = await response.json();
        throw new Error(errorData.error || `Erreur ${response.status}`);
      }

      const result = await response.json();
      
      toast.success("Relance employeur envoyée avec succès !");
      console.log("Relance employeur envoyée:", result);
      
      // Fermer la modal
      setIsReminderModalOpen(false);
      
    } catch (error) {
      console.error("Erreur lors de l'envoi de la relance employeur:", error);
      toast.error(
        error instanceof Error 
          ? error.message 
          : "Erreur lors de l'envoi de la relance employeur"
      );
    } finally {
      setIsSendingReminder(false);
    }
  };

  const defaultNewPayslip = {
    organization_id: contract.org_id,
    contract_id: contract.id,
    period_start: form.start_date || contract.start_date?.slice(0, 10) || "",
    period_end: form.end_date || contract.end_date?.slice(0, 10) || "",
    period_month:
      (form.start_date || contract.start_date?.slice(0, 10) || "").slice(0, 7) + "-01",
    pay_number: nextPayNumber,
    gross_amount: contract.gross_pay ?? "",
    net_amount: "",
    employer_cost: "",
    aem_status: "À traiter",
    processed: false,
    transfer_done: false,
    analytic_tag: contract.analytique ?? null,
    storage_path: `paies/${slugify(contract.structure || "")}/${contract.contract_number}.pdf`,
    source_reference: contract.contract_number,
  };

  return (
    <div className="min-h-[100svh] bg-gradient-to-br from-white via-zinc-50 to-zinc-100 px-6 py-10">
      <div className="mx-auto max-w-6xl space-y-6">
        <header className="space-y-4">
          <div className="flex items-center justify-between">
            <div>
              <h1 className="text-2xl md:text-3xl font-semibold tracking-tight">
                {contract.salaries?.salarie 
                  || (contract.salaries?.nom 
                      ? `${contract.salaries.nom.toUpperCase()}${contract.salaries.prenom ? ' ' + contract.salaries.prenom.charAt(0).toUpperCase() + contract.salaries.prenom.slice(1) : ''}`
                      : contract.employee_name || "")}
              </h1>
              <p className="text-sm text-muted-foreground">
                {contract.production_name} — {contract.contract_number}
              </p>
            </div>
          </div>
        </header>

        {/* Carte flottante avec boutons d'actions + Enregistrer */}
        <div className="fixed bottom-6 right-6 z-50 flex flex-col gap-3 w-full max-w-xs lg:w-[calc(33.333%-1.5rem)]">
          <Card className="rounded-3xl shadow-lg">
            <CardContent className="p-3 space-y-2">
              <Button
                onClick={() => setShowCancelModal(true)}
                disabled={isCancelling || form.etat_de_la_demande === "Annulée"}
                variant="outline"
                size="sm"
                className="w-full justify-start rounded-2xl px-4 text-red-600 border-red-300 hover:bg-red-50"
              >
                <Ban className="size-4 mr-2" />
                {form.etat_de_la_demande === "Annulée" ? "Annulé" : "Annuler"}
              </Button>
              
              <Button
                onClick={async () => {
                  setIsRefreshing(true);
                  try {
                    const res = await fetch(`/api/staff/contracts/${contract.id}`);
                    if (!res.ok) throw new Error('Erreur lors du rechargement');
                    toast.success('Données régénérées');
                    window.location.reload();
                  } catch (e) {
                    console.error('Erreur lors du rafraîchissement:', e);
                    toast.error('Impossible de régénérer les données');
                  } finally {
                    setIsRefreshing(false);
                  }
                }}
                disabled={isRefreshing}
                variant="ghost"
                size="sm"
                className="w-full justify-start rounded-2xl px-4"
              >
                <RefreshCw className="size-4 mr-2" />
                {isRefreshing ? 'Rafraîchissement...' : 'Rafraîchir'}
              </Button>
              
              <Button 
                onClick={generatePdf} 
                disabled={isGeneratingPdf}
                variant="outline"
                size="sm"
                className="w-full justify-start rounded-2xl px-4"
              >
                <FileDown className="size-4 mr-2" />
                {isGeneratingPdf ? "Génération..." : "Créer PDF"}
              </Button>

              <Button
                onClick={() => {
                  console.log("🖱️ [SIGNATURE] Bouton cliqué");
                  console.log("🖱️ [SIGNATURE] isLaunchingSignature:", isLaunchingSignature);
                  console.log("🖱️ [SIGNATURE] contract.contract_pdf_filename:", contract.contract_pdf_filename);
                  handleESignButtonClick();
                }}
                disabled={isLaunchingSignature || !contract.contract_pdf_filename}
                variant="secondary"
                size="sm"
                className="w-full justify-start rounded-2xl px-4"
              >
                <PenTool className="size-4 mr-2" />
                {isLaunchingSignature ? "Lancement..." : "E-signature"}
              </Button>
            </CardContent>
          </Card>
          
          <div>
            <style jsx>{`
              @keyframes gradient {
                0% { background-position: 0% 50%; }
                50% { background-position: 100% 50%; }
                100% { background-position: 0% 50%; }
              }
            `}</style>
            <Button 
              onClick={saveContract} 
              disabled={isSaving || !hasUnsavedChanges}
              className={`rounded-full transition-all duration-200 px-6 py-6 text-base font-semibold w-full ${
                hasUnsavedChanges 
                  ? 'bg-gradient-to-r from-green-400 via-yellow-300 to-green-400 bg-[length:200%_100%] animate-[gradient_2.5s_linear_infinite] hover:shadow-xl text-black shadow-lg' 
                  : 'bg-slate-300 text-slate-500 cursor-not-allowed hover:cursor-not-allowed shadow-lg'
              }`}
            >
              <Save className={`size-5 mr-2 ${hasUnsavedChanges ? 'text-black' : 'text-slate-500'}`} />
              {isSaving ? "Sauvegarde..." : "Enregistrer"}
            </Button>
          </div>
        </div>

        <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
          <div className="col-span-2 space-y-6">
            {/* Card 1: États et Statuts - Le plus important */}
            <Card className="rounded-3xl">
              <CardHeader className="bg-green-50 rounded-t-xl">
                <CardTitle className="flex items-center gap-2">
                  <CheckCircle2 className="size-5" /> États et statuts
                </CardTitle>
              </CardHeader>
              <CardContent>
                <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                  <div>
                    <label className="text-xs text-muted-foreground">État de la demande</label>
                    <select
                      value={form.etat_de_la_demande || ""}
                      onChange={(e) => handleContractChange("etat_de_la_demande", e.target.value)}
                      className="w-full p-2 border rounded"
                    >
                      <option value="">Sélectionner...</option>
                      <option value="Reçue">Reçue</option>
                      <option value="En cours">En cours</option>
                      <option value="Traitée">Traitée</option>
                      <option value="Refusée">Refusée</option>
                      <option value="Annulée">Annulée</option>
                    </select>
                  </div>
                  <div>
                    <label className="text-xs text-muted-foreground">État de la paie</label>
                    <select
                      value={form.etat_de_la_paie || ""}
                      onChange={(e) => handleContractChange("etat_de_la_paie", e.target.value)}
                      className="w-full p-2 border rounded"
                    >
                      <option value="">Sélectionner...</option>
                      <option value="À traiter">À traiter</option>
                      <option value="En cours">En cours</option>
                      <option value="Traitée">Traitée</option>
                      <option value="Non concernée">Non concernée</option>
                    </select>
                  </div>
                  <div>
                    <label className="text-xs text-muted-foreground">DPAE</label>
                    <select
                      value={form.dpae || ""}
                      onChange={(e) => handleContractChange("dpae", e.target.value)}
                      className="w-full p-2 border rounded"
                    >
                      <option value="">Sélectionner...</option>
                      <option value="À faire">À faire</option>
                      <option value="Faite">Faite</option>
                      <option value="Non concernée">Non concernée</option>
                    </select>
                  </div>
                  <div>
                    <label className="text-xs text-muted-foreground">Contrat signé par salarié</label>
                    <select
                      value={form.contrat_signe || ""}
                      onChange={(e) => handleContractChange("contrat_signe", e.target.value)}
                      className="w-full p-2 border rounded"
                    >
                      <option value="">Sélectionner...</option>
                      <option value="Oui">Oui</option>
                      <option value="Non">Non</option>
                    </select>
                  </div>
                  <div>
                    <label className="text-xs text-muted-foreground">Contrat signé par employeur</label>
                    <select
                      value={form.contrat_signe_par_employeur || ""}
                      onChange={(e) => handleContractChange("contrat_signe_par_employeur", e.target.value)}
                      className="w-full p-2 border rounded"
                    >
                      <option value="">Sélectionner...</option>
                      <option value="Oui">Oui</option>
                      <option value="Non">Non</option>
                    </select>
                  </div>
                </div>
              </CardContent>
            </Card>

            {/* Card 2: Informations principales du contrat */}
            <Card className="rounded-3xl">
              <CardHeader className="bg-blue-50 rounded-t-xl">
                <CardTitle className="flex items-center gap-2">
                  <FileText className="size-5" /> Informations du contrat
                </CardTitle>
              </CardHeader>
              <CardContent>
                <div className="space-y-6">
                  {/* Spectacle et Référence */}
                  <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                  <div className="relative md:col-span-2">
                    <label className="text-xs text-muted-foreground">Spectacle</label>
                    {spectaclePick ? (
                      <div className="flex items-center gap-2">
                        <div className="flex-1 p-2 border rounded bg-green-50 text-sm">
                          <div className="font-medium">{spectaclePick.nom}</div>
                          {spectaclePick.numero_objet && (
                            <div className="text-xs text-muted-foreground">{spectaclePick.numero_objet}</div>
                          )}
                        </div>
                        <button
                          type="button"
                          onClick={() => {
                            setSpectaclePick(null);
                            setSpectacleQuery("");
                          }}
                          className="px-2 py-1 text-xs border rounded hover:bg-gray-50"
                        >
                          Changer
                        </button>
                      </div>
                    ) : (
                      <>
                        <div className="relative">
                          <Input
                            value={spectacleQuery}
                            onChange={(e) => setSpectacleQuery(e.target.value)}
                            placeholder="Rechercher un spectacle..."
                          />
                          <Search className="absolute right-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" />
                        </div>
                        {spectacleQuery.length > 1 && spectacleSearch?.items && (
                          <div className="absolute z-10 w-full mt-1 bg-white border rounded-md shadow-lg max-h-48 overflow-y-auto">
                            {spectacleSearch.items.length === 0 ? (
                              <div className="p-2 text-sm text-gray-500">Aucun résultat</div>
                            ) : (
                              spectacleSearch.items.map((item, idx) => (
                                <button
                                  key={idx}
                                  type="button"
                                  className="w-full text-left p-2 hover:bg-gray-50 text-sm border-b last:border-b-0"
                                  onClick={() => {
                                    setSpectaclePick(item);
                                    setSpectacleQuery("");
                                  }}
                                >
                                  <div className="font-medium">{item.nom}</div>
                                  {(item.numero_objet || item.prod_type) && (
                                    <div className="text-xs text-gray-500">
                                      {item.numero_objet && <span>{item.numero_objet}</span>}
                                      {item.numero_objet && item.prod_type && <span> • </span>}
                                      {item.prod_type && <span>{item.prod_type}</span>}
                                    </div>
                                  )}
                                </button>
                              ))
                            )}
                          </div>
                        )}
                      </>
                    )}
                  </div>

                  {/* Analytique */}
                  <div>
                    <label className="text-xs text-muted-foreground">Analytique</label>
                    <Input
                      value={analytique}
                      onChange={(e) => setAnalytique(e.target.value)}
                      placeholder="Code analytique"
                    />
                  </div>
                  </div>

                  {/* Période du contrat */}
                  <div className="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4">
                  <div>
                    <label className="text-xs text-muted-foreground">Début</label>
                    <Input
                      type="date"
                      value={form.start_date || prefill.date_debut}
                      onChange={(e) => handleContractChange("start_date", e.target.value)}
                    />
                  </div>
                  <div>
                    <label className="text-xs text-muted-foreground">Fin</label>
                    <Input
                      type="date"
                      value={form.end_date || prefill.date_fin}
                      onChange={(e) => handleContractChange("end_date", e.target.value)}
                    />
                  </div>
                  <div>
                    <label className="text-xs text-muted-foreground">Date de signature</label>
                    <Input
                      type="date"
                      value={dateSignature}
                      onChange={(e) => setDateSignature(e.target.value)}
                    />
                  </div>
                  </div>
                </div>
              </CardContent>
            </Card>

            {/* Card 3: Salarié et Profession */}
            <Card className="rounded-3xl">
              <CardHeader className="bg-purple-50 rounded-t-xl">
                <CardTitle className="flex items-center gap-2">
                  <Users className="size-5" /> Salarié et profession
                </CardTitle>
              </CardHeader>
              <CardContent>
                <div className="space-y-6">
                  {/* Salarié avec recherche */}
                  <div className="relative md:col-span-2">
                    <label className="text-xs text-muted-foreground">Salarié</label>
                    {salarie ? (
                      <div className="flex items-center gap-2">
                        <div className="flex-1 p-2 border rounded bg-green-50 text-sm">
                          <div className="font-medium">{salarie.nom}</div>
                          <div className="text-xs text-muted-foreground">{salarie.matricule}</div>
                        </div>
                        <button
                          type="button"
                          onClick={() => {
                            setSalarie(null);
                            setSalarieQuery("");
                          }}
                          className="px-2 py-1 text-xs border rounded hover:bg-gray-50"
                        >
                          Changer
                        </button>
                      </div>
                    ) : (
                      <>
                        <div className="relative">
                          <Input
                            value={salarieQuery}
                            onChange={(e) => setSalarieQuery(e.target.value)}
                            placeholder="Rechercher un·e salarié·e..."
                          />
                          <Search className="absolute right-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" />
                        </div>
                        {salarieQuery.length > 1 && salarieSearch?.items && (
                          <div className="absolute z-10 w-full mt-1 bg-white border rounded-md shadow-lg max-h-48 overflow-y-auto">
                            {salarieSearch.items.length === 0 ? (
                              <div className="p-2 text-sm text-gray-500">Aucun résultat</div>
                            ) : (
                              salarieSearch.items.map((item, idx) => (
                                <button
                                  key={idx}
                                  type="button"
                                  className="w-full text-left p-2 hover:bg-gray-50 text-sm border-b last:border-b-0"
                                  onClick={() => {
                                    setSalarie(item);
                                    setSalarieQuery("");
                                  }}
                                >
                                  <div className="font-medium">{item.nom}</div>
                                  <div className="text-xs text-gray-500">
                                    <span>{item.matricule}</span>
                                    {item.email && <span> • {item.email}</span>}
                                  </div>
                                </button>
                              ))
                            )}
                          </div>
                        )}
                      </>
                    )}
                  </div>

                  {/* Profession, Profession féminin, Catégorie professionnelle - 3 colonnes */}
                  <div className="md:col-span-3">
                    <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                      {/* Profession avec recherche conditionnelle */}
                      <div className="relative">
                        <label className="text-xs text-muted-foreground">Profession</label>
                        {professionPick ? (
                          <div className="flex items-center gap-2">
                            <div className="flex-1 p-2 border rounded bg-green-50 text-sm">
                              <div className="font-medium">{professionPick.label}</div>
                              {professionPick.code && (
                                <div className="text-xs text-muted-foreground">{professionPick.code}</div>
                              )}
                            </div>
                            <button
                              type="button"
                              onClick={() => {
                                setProfessionPick(null);
                                setProfessionQuery("");
                                setProfessionFeminine("");
                              }}
                              className="px-2 py-1 text-xs border rounded hover:bg-gray-50"
                            >
                              Changer
                            </button>
                          </div>
                        ) : (
                          <>
                            <Input
                              value={professionQuery}
                              onChange={(e) => setProfessionQuery(e.target.value)}
                              onFocus={() => setProfessionInputFocused(true)}
                              onBlur={() => setTimeout(() => setProfessionInputFocused(false), 200)}
                              placeholder={`Rechercher une profession ${categoriePro.toLowerCase()}...`}
                            />
                            {(professionQuery || professionInputFocused) && (
                              <div className="absolute z-10 w-full mt-1 bg-white border rounded-md shadow-lg max-h-48 overflow-y-auto">
                                {categoriePro === "Artiste" ? (
                                  filteredProfessions.length === 0 ? (
                                    <div className="p-2 text-sm text-gray-500">Aucune profession trouvée</div>
                                  ) : (
                                    filteredProfessions.map((prof, idx) => (
                                      <button
                                        key={idx}
                                        type="button"
                                        className="w-full text-left p-2 hover:bg-gray-50 text-sm border-b last:border-b-0"
                                        onClick={() => {
                                          setProfessionPick(prof);
                                          setProfessionQuery("");
                                        }}
                                      >
                                        <div className="font-medium">{prof.label}</div>
                                        <div className="text-xs text-gray-500">{prof.code}</div>
                                      </button>
                                    ))
                                  )
                                ) : (
                                  filteredTechniciens.length === 0 ? (
                                    <div className="p-2 text-sm text-gray-500">
                                      {techniciens ? "Aucune profession trouvée" : "Chargement..."}
                                    </div>
                                  ) : (
                                    filteredTechniciens.map((prof, idx) => (
                                      <button
                                        key={idx}
                                        type="button"
                                        className="w-full text-left p-2 hover:bg-gray-50 text-sm border-b last:border-b-0"
                                        onClick={() => {
                                          setProfessionPick(prof);
                                          setProfessionQuery("");
                                        }}
                                      >
                                        <div className="font-medium">{prof.label}</div>
                                        <div className="text-xs text-gray-500">{prof.code}</div>
                                      </button>
                                    ))
                                  )
                                )}
                              </div>
                            )}
                          </>
                        )}
                      </div>

                      {/* Profession féminin */}
                      <div>
                        <label className="text-xs text-muted-foreground">Profession (féminin)</label>
                        <div className="relative">
                          <Input
                            value={professionFeminine}
                            onChange={(e) => handleFeminineChange(e.target.value)}
                            placeholder={professionPick ? "Saisir le féminin..." : "Sélectionnez d'abord une profession"}
                            disabled={!professionPick}
                            className={`${!professionPick ? "bg-gray-50 text-gray-400" : ""} pr-12`}
                            onKeyDown={(e) => {
                              console.log("🔍 KeyDown event:", e.key, {professionPick, professionFeminine});
                              if (e.key === 'Enter' && professionPick && professionFeminine.trim()) {
                                e.preventDefault();
                                console.log("🚀 Calling saveCurrentFeminisation from Enter key");
                                saveCurrentFeminisation();
                              }
                            }}
                          />
                          {professionPick && professionFeminine.trim() && (
                            <button
                              type="button"
                              onClick={() => {
                                console.log("🚀 Button clicked, calling saveCurrentFeminisation");
                                saveCurrentFeminisation();
                              }}
                              disabled={isSavingFeminisation}
                              className="absolute right-2 top-1/2 transform -translate-y-1/2 p-1.5 rounded-full hover:bg-green-100 text-green-600 disabled:opacity-50 disabled:cursor-not-allowed"
                              title="Sauvegarder la féminisation"
                            >
                              {isSavingFeminisation ? (
                                <RefreshCw className="w-4 h-4 animate-spin" />
                              ) : (
                                <Check className="w-4 h-4" />
                              )}
                            </button>
                          )}
                        </div>
                        {professionPick && !professionFeminine && (
                          <div className="text-xs text-amber-600 mt-1">
                            ℹ️ Saisissez la forme féminine pour les contrats de femmes
                          </div>
                        )}
                        {professionPick && professionFeminine.trim() && (
                          <div className="text-xs text-green-600 mt-1">
                            💾 Cliquez sur ✓ ou appuyez sur Entrée pour sauvegarder
                          </div>
                        )}
                      </div>

                      {/* Catégorie professionnelle */}
                      <div>
                        <label className="text-xs text-muted-foreground">Catégorie professionnelle</label>
                        <select
                          value={categoriePro}
                          onChange={(e) => {
                            const newCat = e.target.value as "Artiste" | "Technicien";
                            setCategoriePro(newCat);
                            // Reset profession when category changes
                            setProfessionPick(null);
                            setProfessionQuery("");
                          }}
                          className="w-full p-2 border rounded"
                        >
                          <option value="Artiste">Artiste</option>
                          <option value="Technicien">Technicien</option>
                        </select>
                      </div>
                    </div>
                  </div>
                </div>
              </CardContent>
            </Card>

            {/* Card 4: Rémunération */}
            <Card className="rounded-3xl">
              <CardHeader className="bg-orange-50 rounded-t-xl">
                <CardTitle className="flex items-center gap-2">
                  <Euro className="size-5" /> Rémunération
                </CardTitle>
              </CardHeader>
              <CardContent>
                <div className="space-y-6">
                  <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                  {/* Champs CDDU modifiables */}
                  <div>
                    <label className="text-xs text-muted-foreground">Type de salaire</label>
                    <select
                      value={typeSalaire}
                      onChange={(e) => setTypeSalaire(e.target.value)}
                      className="w-full p-2 border rounded"
                    >
                      <option value="">Sélectionner...</option>
                      <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>
                  </div>
                  <div>
                    <label className="text-xs text-muted-foreground">Montant</label>
                    <Input
                      type="number"
                      step="0.01"
                      value={montant}
                      onChange={(e) => setMontant(e.target.value)}
                      placeholder="Montant en euros"
                    />
                    
                    {/* Affichage du détail des salaires par date si disponible */}
                    {contract.salaires_par_date && (
                      <SalaireParDateEditor
                        salairesParDate={contract.salaires_par_date}
                        contractId={contract.id}
                        onUpdate={(newSalaires) => {
                          contract.salaires_par_date = newSalaires;
                          setMontant(String(newSalaires.total_calcule));
                        }}
                      />
                    )}
                  </div>
                  <div>
                    <label className="text-xs text-muted-foreground">Brut</label>
                    <Input
                      value={form.gross_pay || String(prefill.montant || "")}
                      onChange={(e) => handleContractChange("gross_pay", e.target.value)}
                    />
                  </div>
                  <div>
                    <label className="text-xs text-muted-foreground">Panier repas</label>
                    <select
                      value={panierRepas}
                      onChange={(e) => setPanierRepas(e.target.value)}
                      className="w-full p-2 border rounded"
                    >
                      <option value="">Sélectionner...</option>
                      <option value="Oui">Oui</option>
                      <option value="Non">Non</option>
                    </select>
                  </div>
                  </div>

                  <div>
                    <label className="text-xs text-muted-foreground">Précisions salaire</label>
                    <Textarea
                      rows={3}
                      value={precisionsSalaire}
                      onChange={(e) => setPrecisionsSalaire(e.target.value)}
                      placeholder="Précisions sur le calcul du salaire"
                    />
                  </div>
                </div>
              </CardContent>
            </Card>

            {/* Card 5: Temps de travail */}
            <Card className="rounded-3xl">
              <CardHeader className="bg-indigo-50 rounded-t-xl">
                <CardTitle className="flex items-center gap-2">
                  <CalendarRange className="size-5" /> Temps de travail
                </CardTitle>
              </CardHeader>
              <CardContent>
                <div className="space-y-6">
                {/* Champs conditionnels selon la catégorie professionnelle */}
                <div className="mt-4">
                  {!useHeuresMode ? (
                    <>
                      <div className="bg-indigo-50/50 border border-indigo-100 rounded-xl p-4 mb-4">
                        <h4 className="text-sm font-semibold text-indigo-900 mb-3">Répétitions et représentations</h4>
                      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div>
                          <label className="text-xs text-muted-foreground">Nombre de représentations</label>
                          <div className="flex items-center gap-2">
                            <Input
                              type="number"
                              min={0}
                              value={nbRepresentations}
                              onChange={(e) => setNbRepresentations(e.target.value === "" ? "" : Number(e.target.value))}
                              className="flex-1"
                            />
                            <button
                              type="button"
                              onClick={() => setDatesRepresentationsOpen(true)}
                              className="px-3 py-2 rounded-lg border bg-white text-sm hover:bg-slate-50 transition whitespace-nowrap"
                              title="Préciser les dates et quantités"
                            >
                              Préciser
                            </button>
                          </div>
                        </div>
                        <div>
                          <label className="text-xs text-muted-foreground">Nombre de services de répétition / Durée</label>
                          <div className="flex items-center gap-2">
                            <Input
                              type="number"
                              min={0}
                              value={nbServicesRepetition}
                              onChange={(e) => setNbServicesRepetition(e.target.value === "" ? "" : Number(e.target.value))}
                              placeholder="Nombre"
                              className="flex-1"
                            />
                            <span className="text-slate-400 font-medium">×</span>
                            {typeof nbServicesRepetition === "number" && nbServicesRepetition > 0 && (
                              <select
                                value={durationServices}
                                onChange={(e) => setDurationServices(e.target.value as "3" | "4")}
                                className="px-3 py-2 rounded-lg border bg-white text-sm"
                                title="Durée des services de répétition"
                              >
                                <option value="3">3h</option>
                                <option value="4">4h</option>
                              </select>
                            )}
                            <button
                              type="button"
                              onClick={() => setDatesRepetitionsOpen(true)}
                              className="px-3 py-2 rounded-lg border bg-white text-sm hover:bg-slate-50 transition whitespace-nowrap"
                              title="Préciser les dates et quantités"
                            >
                              Préciser
                            </button>
                          </div>
                        </div>
                        <div>
                          <label className="text-xs text-muted-foreground">Dates de représentations</label>
                          <div className="flex items-center gap-2">
                            <div className="flex-1 px-3 py-2 rounded-lg border bg-slate-50 text-sm text-slate-700 min-h-[42px] flex items-center">
                              {datesRepresentationsDisplay || (datesRepresentations ? datesRepresentations : "Cliquez pour sélectionner…")}
                            </div>
                            <button
                              type="button"
                              onClick={() => setDatesRepresentationsOpen(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 className="text-xs text-muted-foreground">Dates de répétitions</label>
                          <div className="flex items-center gap-2">
                            <div className="flex-1 px-3 py-2 rounded-lg border bg-slate-50 text-sm text-slate-700 min-h-[42px] flex items-center">
                              {datesRepetitionsDisplay || (datesRepetitions ? datesRepetitions : "Cliquez pour sélectionner…")}
                            </div>
                            <button
                              type="button"
                              onClick={() => setDatesRepetitionsOpen(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>
                      </div>

                      {/* Calendriers pour représentations et répétitions */}
                      <DatePickerCalendar
                        isOpen={datesRepresentationsOpen}
                        onClose={() => setDatesRepresentationsOpen(false)}
                        onApply={handleDatesRepresentationsApply}
                        initialDates={datesRepresentations ? datesRepresentations.split(", ") : []}
                        title="Sélectionner les dates de représentations"
                        minDate={contract.start_date?.slice(0, 10)}
                        maxDate={contract.end_date?.slice(0, 10)}
                      />
                      <DatePickerCalendar
                        isOpen={datesRepetitionsOpen}
                        onClose={() => setDatesRepetitionsOpen(false)}
                        onApply={handleDatesRepetitionsApply}
                        initialDates={datesRepetitions ? datesRepetitions.split(", ") : []}
                        title="Sélectionner les dates de répétitions"
                        minDate={contract.start_date?.slice(0, 10)}
                        maxDate={contract.end_date?.slice(0, 10)}
                      />
                      
                      {/* Nouveaux champs pour heures total et par jour */}
                      <div className="bg-purple-50/50 border border-purple-100 rounded-xl p-4">
                        <h4 className="text-sm font-semibold text-purple-900 mb-3">Heures de travail</h4>
                      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div>
                          <label className="text-xs text-muted-foreground">Nombre d'heures total</label>
                          <Input
                            type="number"
                            min={0}
                            step="0.5"
                            value={nombreHeuresTotal}
                            onChange={(e) => setNombreHeuresTotal(e.target.value === "" ? "" : Number(e.target.value))}
                            placeholder="ex : 24"
                          />
                        </div>
                        <div>
                          <label className="text-xs text-muted-foreground">Nombre d'heures par jour</label>
                          <Input
                            type="number"
                            min={0}
                            step="0.5"
                            value={nombreHeuresParJour}
                            onChange={(e) => setNombreHeuresParJour(e.target.value === "" ? "" : Number(e.target.value))}
                            placeholder="ex : 8"
                          />
                        </div>
                        <div className="md:col-span-2">
                          <label className="text-xs text-muted-foreground">Jours de travail</label>
                          <Textarea
                            rows={3}
                            value={joursTravail}
                            onChange={(e) => setJoursTravail(e.target.value)}
                            placeholder="ex : 12/10, 13/10, 24/10"
                          />
                        </div>
                      </div>
                      </div>
                    </>
                  ) : (
                    <>
                      <div className="bg-purple-50/50 border border-purple-100 rounded-xl p-4">
                        <h4 className="text-sm font-semibold text-purple-900 mb-3">Heures de travail</h4>
                      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                        <div>
                          <label className="text-xs text-muted-foreground">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"
                            />
                            <select
                              value={minutesTotal}
                              onChange={(e) => setMinutesTotal(e.target.value as "0" | "30")}
                              className="px-3 py-2 rounded-lg border bg-white text-sm"
                            >
                              <option value="0">+ 00 min</option>
                              <option value="30">+ 30 min</option>
                            </select>
                          </div>
                        </div>
                        <div>
                          <label className="text-xs text-muted-foreground">Jours de travail</label>
                          <Textarea
                            rows={3}
                            value={joursTravail}
                            onChange={(e) => setJoursTravail(e.target.value)}
                            placeholder="ex : 12/10, 13/10, 24/10"
                          />
                        </div>
                      </div>
                      
                      {/* Champ cachets pour metteur en scène */}
                      {professionPick?.code === "MET040" && (
                        <div className="mt-4">
                          <label className="text-xs text-muted-foreground">Nombre de représentations (cachets)</label>
                          <Input
                            type="number"
                            min={0}
                            value={nbRepresentations}
                            onChange={(e) => setNbRepresentations(e.target.value === "" ? "" : Number(e.target.value))}
                            placeholder="ex : 2"
                          />
                          <p className="text-[10px] text-muted-foreground mt-1">
                            Nombre de cachets de représentation pour le metteur en scène.
                          </p>
                        </div>
                      )}
                      </div>
                    </>
                  )}
                </div>

                {/* Séparateur */}
                <Separator className="my-6" />

                {/* Sous-section: Temps de travail réel (informatif pour le client) */}
                <div className="mt-6">
                  <div className="flex items-center gap-2 mb-4">
                    <div className="h-px flex-1 bg-gradient-to-r from-slate-200 to-transparent"></div>
                    <h4 className="text-sm font-semibold text-slate-700">Temps de travail réel (informatif client)</h4>
                    <div className="h-px flex-1 bg-gradient-to-l from-slate-200 to-transparent"></div>
                  </div>
                  <p className="text-xs text-muted-foreground mb-4">
                    Ces informations sont purement informatives pour le client et ne sont pas utilisées pour la génération du PDF du contrat.
                  </p>
                  
                  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <div>
                      <label className="text-xs text-muted-foreground">Jours travaillés</label>
                      <Input
                        value={joursTravailReel}
                        onChange={(e) => setJoursTravailReel(e.target.value)}
                        placeholder="ex: 15/01, 16/01, 17/01"
                      />
                    </div>
                    <div>
                      <label className="text-xs text-muted-foreground">Nbre de représentations</label>
                      <Input
                        type="number"
                        min={0}
                        value={nbRepresentationsReel}
                        onChange={(e) => setNbRepresentationsReel(e.target.value === "" ? "" : Number(e.target.value))}
                        placeholder="0"
                      />
                    </div>
                    <div>
                      <label className="text-xs text-muted-foreground">Nbre de services répétitions</label>
                      <Input
                        type="number"
                        min={0}
                        value={nbServicesRepetitionsReel}
                        onChange={(e) => setNbServicesRepetitionsReel(e.target.value === "" ? "" : Number(e.target.value))}
                        placeholder="0"
                      />
                    </div>
                    <div>
                      <label className="text-xs text-muted-foreground">Nbre d'heures répétitions</label>
                      <Input
                        type="number"
                        min={0}
                        step="0.5"
                        value={nbHeuresRepetitionsReel}
                        onChange={(e) => setNbHeuresRepetitionsReel(e.target.value === "" ? "" : Number(e.target.value))}
                        placeholder="0"
                      />
                    </div>
                    <div>
                      <label className="text-xs text-muted-foreground">Nbre d'heures Annexes 8</label>
                      <Input
                        type="number"
                        min={0}
                        step="0.5"
                        value={nbHeuresAnnexesReel}
                        onChange={(e) => setNbHeuresAnnexesReel(e.target.value === "" ? "" : Number(e.target.value))}
                        placeholder="0"
                      />
                    </div>
                    <div>
                      <label className="text-xs text-muted-foreground">Nombre de cachets AEM</label>
                      <Input
                        type="number"
                        min={0}
                        value={nbCachetsAemReel}
                        onChange={(e) => setNbCachetsAemReel(e.target.value === "" ? "" : Number(e.target.value))}
                        placeholder="0"
                      />
                    </div>
                    <div>
                      <label className="text-xs text-muted-foreground">Nombre d'heures AEM</label>
                      <Input
                        type="number"
                        min={0}
                        step="0.5"
                        value={nbHeuresAemReel}
                        onChange={(e) => setNbHeuresAemReel(e.target.value === "" ? "" : Number(e.target.value))}
                        placeholder="0"
                      />
                    </div>
                  </div>
                </div>
                </div>
              </CardContent>
            </Card>

            {/* Card 6: Informations complémentaires */}
            <Card className="rounded-3xl">
              <CardHeader className="bg-slate-50 rounded-t-xl">
                <CardTitle className="flex items-center gap-2">
                  <StickyNote className="size-5" /> Informations complémentaires
                </CardTitle>
              </CardHeader>
              <CardContent>
                <div className="space-y-4">
              <div>
                <label className="text-xs text-muted-foreground">S3 key (contrat PDF)</label>
                <Input
                  value={form.contract_pdf_s3_key}
                  onChange={(e) =>
                    handleContractChange("contract_pdf_s3_key", e.target.value)
                  }
                />
              </div>

              <div>
                <label className="text-xs text-muted-foreground">Note interne</label>
                <Textarea
                  rows={4}
                  value={form.notes ?? ""}
                  onChange={(e) => handleContractChange("notes", e.target.value)}
                />
              </div>

              <div>
                <label className="text-xs text-muted-foreground">Autre précision durée</label>
                <Textarea
                  rows={2}
                  value={autrePrecisionDuree}
                  onChange={(e) => setAutrePrecisionDuree(e.target.value)}
                  placeholder="Autre précision sur la durée du contrat"
                />
              </div>

              <div className="md:col-span-2">
                <label className="text-xs text-muted-foreground">Autre précision salaire</label>
                <Textarea
                  rows={2}
                  value={autrePrecisionSalaire}
                  onChange={(e) => setAutrePrecisionSalaire(e.target.value)}
                  placeholder="Autre précision sur le salaire"
                />
              </div>

              <div className="md:col-span-2">
                <label className="text-xs text-muted-foreground">Définition "Cachet de répétition"</label>
                <div className="relative">
                  <div 
                    className="p-3 bg-gray-50 border rounded-md text-sm cursor-pointer hover:bg-gray-100 transition-colors"
                    onClick={async () => {
                      const ccn = organizationDetails?.organization_details?.ccn || "Convention Collective Nationale des Entreprises Artistiques & Culturelles";
                      const text = `On entend par 'Cachet de répétition' une journée de répétitions, qu'elle soit constituée d'un ou deux services, conformément aux dispositions de la ${ccn}`;
                      try {
                        await navigator.clipboard.writeText(text);
                        toast.success("Texte copié dans le presse-papiers");
                      } catch (err) {
                        console.error("Erreur lors de la copie:", err);
                        toast.error("Erreur lors de la copie");
                      }
                    }}
                    title="Cliquer pour copier"
                  >
                    On entend par 'Cachet de répétition' une journée de répétitions, qu'elle soit constituée d'un ou deux services, conformément aux dispositions de la {organizationDetails?.organization_details?.ccn || "Convention Collective Nationale des Entreprises Artistiques & Culturelles"}
                  </div>
                  <div className="absolute top-2 right-2 text-xs text-gray-400 pointer-events-none">
                    📋 Cliquer pour copier
                  </div>
                </div>
              </div>
                </div>
              </CardContent>
            </Card>
          </div>

          <div className="space-y-6">
            {/* Calendrier pour dates travaillées - Modal global */}
            <DatePickerCalendar
              isOpen={joursTravailOpen}
              onClose={() => setJoursTravailOpen(false)}
              onApply={handleJoursTravailApply}
              initialDates={joursTravail ? joursTravail.split(", ") : []}
              title="Sélectionner les dates travaillées"
              minDate={contract.date_debut}
              maxDate={contract.date_fin}
            />

            {/* Card Infos salarié */}
            <Card className="rounded-3xl overflow-hidden">
              <CardHeader className="bg-slate-50 border-b border-slate-200">
                <CardTitle className="flex items-center gap-3">
                  <Users className="size-5 text-slate-600" />
                  <span>Infos salarié</span>
                </CardTitle>
              </CardHeader>
              <CardContent className="p-6">
                <div className="space-y-3">
                  <div className="flex flex-col space-y-1">
                    <span className="text-xs text-gray-500 font-medium">Nom et prénom</span>
                    <span className="font-medium text-gray-900">
                      {salarie?.nom || contract.employee_name || "Non défini"}
                    </span>
                  </div>
                  <div className="flex flex-col space-y-1">
                    <span className="text-xs text-gray-500 font-medium">Adresse e-mail</span>
                    <span className="text-sm text-gray-700">
                      {salarie?.email || contract.salaries?.adresse_mail || "Non renseigné"}
                    </span>
                  </div>
                  <div className="flex flex-col space-y-1">
                    <span className="text-xs text-gray-500 font-medium">Matricule</span>
                    <span className="text-sm font-mono text-gray-700">
                      {salarie?.matricule || salarie?.code_salarie || contract.salaries?.code_salarie || contract.employee_matricule || "Non renseigné"}
                    </span>
                  </div>
                </div>
              </CardContent>
            </Card>

            {/* Card Infos structure */}
            <Card className="rounded-3xl overflow-hidden">
              <CardHeader className="bg-indigo-50 border-b border-indigo-200">
                <CardTitle className="flex items-center gap-3">
                  <Users className="size-5 text-indigo-600" />
                  <span>Infos structure</span>
                </CardTitle>
              </CardHeader>
              <CardContent className="p-6">
                <div className="space-y-3">
                  <div className="flex flex-col space-y-1">
                    <span className="text-xs text-gray-500 font-medium">Nom de la structure</span>
                    <span className="font-medium text-gray-900">
                      {organizationDetails?.name || organizationDetails?.organization_name || "Non défini"}
                    </span>
                  </div>
                  <div className="flex flex-col space-y-1">
                    <span className="text-xs text-gray-500 font-medium">Code employeur</span>
                    <span className="text-sm font-mono text-gray-700">
                      {organizationDetails?.code_employeur || organizationDetails?.organization_code || organizationDetails?.organization_details?.code_employeur || "Non renseigné"}
                    </span>
                  </div>
                  <div className="flex flex-col space-y-1">
                    <span className="text-xs text-gray-500 font-medium">Convention collective</span>
                    <span className="text-sm text-gray-700">
                      {organizationDetails?.organization_details?.ccn || "Convention Collective Nationale des Entreprises Artistiques & Culturelles"}
                    </span>
                  </div>
                </div>
              </CardContent>
            </Card>

            {/* Card de suivi de signature électronique */}
            <Card className="rounded-3xl overflow-hidden">
              <CardHeader className={`${getSignatureStatus().bgColor} ${getSignatureStatus().borderColor} border-b`}>
                <CardTitle className="flex items-center justify-between">
                  <div className="flex items-center gap-3">
                    <PenTool className="size-5 text-indigo-600" />
                    <span>Signature électronique</span>
                  </div>
                  <div className={`flex items-center gap-2 px-3 py-1 rounded-full ${getSignatureStatus().bgColor} ${getSignatureStatus().color} border ${getSignatureStatus().borderColor}`}>
                    {(() => {
                      const IconComponent = getSignatureStatus().icon;
                      return <IconComponent className="size-4" />;
                    })()}
                    <span className="text-sm font-medium">{getSignatureStatus().label}</span>
                  </div>
                </CardTitle>
              </CardHeader>
              <CardContent className="p-6">
                <div className="space-y-4">
                  {/* Affichage détaillé du statut */}
                  <div className="grid grid-cols-1 md:grid-cols-3 gap-4 text-sm">
                    <div className="flex flex-col space-y-1">
                      <span className="text-gray-500 font-medium">État de la demande</span>
                      <span className={`font-semibold ${
                        (form.etat_de_la_demande || contract.etat_de_la_demande) === "Traitée" ? "text-green-600" : "text-gray-600"
                      }`}>
                        {form.etat_de_la_demande || contract.etat_de_la_demande || "Non défini"}
                      </span>
                    </div>
                    <div className="flex flex-col space-y-1">
                      <span className="text-gray-500 font-medium">Signature employeur</span>
                      <span className={`font-semibold ${
                        (form.contrat_signe_par_employeur || contract.contrat_signe_par_employeur) === "Oui" ? "text-green-600" : "text-gray-600"
                      }`}>
                        {form.contrat_signe_par_employeur || contract.contrat_signe_par_employeur || "Non"}
                      </span>
                    </div>
                    <div className="flex flex-col space-y-1">
                      <span className="text-gray-500 font-medium">Signature salarié</span>
                      <span className={`font-semibold ${
                        (form.contrat_signe || contract.contrat_signe) === "Oui" ? "text-green-600" : "text-gray-600"
                      }`}>
                        {form.contrat_signe || contract.contrat_signe || "Non"}
                      </span>
                    </div>
                  </div>

                  {/* Bouton de relance si en attente employeur */}
                  {getSignatureStatus().status === "waiting_employer" && (
                    <div className="pt-4 border-t">
                      <Button
                        variant="outline"
                        size="sm"
                        className="flex items-center gap-2 text-orange-600 border-orange-200 hover:bg-orange-50"
                        onClick={handleOpenReminderModal}
                        disabled={isLoadingOrgData}
                      >
                        {isLoadingOrgData ? (
                          <RefreshCw className="size-4 animate-spin" />
                        ) : (
                          <Send className="size-4" />
                        )}
                        {isLoadingOrgData ? "Chargement..." : "Relancer l'employeur"}
                      </Button>
                    </div>
                  )}

                  {/* Bouton "Marquer comme non signé" à la place de la progression */}
                  <div className="pt-4">
                    <Button
                      variant="outline"
                      size="sm"
                      className="flex items-center gap-2 text-red-600 border-red-200 hover:bg-red-50 disabled:opacity-50 disabled:cursor-not-allowed"
                      onClick={handleMarkAsUnsigned}
                      disabled={isBothUnsigned || isMarkingUnsigned}
                    >
                      {isMarkingUnsigned ? (
                        <RefreshCw className="size-4 animate-spin" />
                      ) : (
                        <XCircle className="size-4" />
                      )}
                      {isMarkingUnsigned 
                        ? "Marquage en cours..." 
                        : isBothUnsigned 
                          ? "Déjà marqué comme non signé"
                          : "Marquer comme non signé"
                      }
                    </Button>
                    {isBothUnsigned && (
                      <p className="text-xs text-gray-500 mt-2">
                        Les deux parties sont déjà marquées comme n'ayant pas signé le contrat.
                      </p>
                    )}
                  </div>
                </div>
              </CardContent>
            </Card>

            <Card className="rounded-3xl">
              <CardHeader className="bg-amber-50 rounded-t-xl">
                <CardTitle className="flex items-center gap-2">
                  <FileText className="size-5" /> Documents
                </CardTitle>
              </CardHeader>
              <CardContent className="space-y-3">
                {/* Contrat CDDU non signé */}
                {contractPdfUrl ? (
                  <div 
                    onClick={openPdf}
                    className="flex items-center gap-3 p-3 border rounded-lg cursor-pointer hover:bg-muted/50 transition-colors"
                  >
                    <FileText className="size-5 text-blue-600" />
                    <div className="flex-1">
                      <p className="font-medium">Contrat CDDU (version préliminaire)</p>
                      <p className="text-sm text-muted-foreground">
                        {contractPdfFilename || 'contrat.pdf'}
                      </p>
                    </div>
                  </div>
                ) : null}

                {/* Contrat CDDU signé */}
                {loadingSignedPdf ? (
                  <div className="flex items-center gap-3 p-3 border rounded-lg bg-gray-50">
                    <RefreshCw className="size-5 text-gray-400 animate-spin" />
                    <div className="flex-1">
                      <p className="font-medium text-gray-600">Vérification du contrat signé...</p>
                    </div>
                  </div>
                ) : signedPdfData?.hasSignedPdf && signedPdfData?.signedUrl ? (
                  <div className="flex items-center gap-3 p-3 border-2 border-green-200 bg-green-50 rounded-lg">
                    <CheckCircle2 className="size-5 text-green-600 flex-shrink-0" />
                    <div 
                      onClick={openSignedPdf}
                      className="flex-1 cursor-pointer hover:underline"
                    >
                      <p className="font-medium text-green-800">Contrat CDDU signé</p>
                      <p className="text-sm text-green-600">
                        Document électroniquement signé
                      </p>
                    </div>
                    <Button
                      variant="ghost"
                      size="sm"
                      onClick={() => setShowDeleteSignedPdfModal(true)}
                      className="text-red-600 hover:text-red-700 hover:bg-red-50"
                      title="Supprimer le contrat signé"
                    >
                      <Ban className="size-4" />
                    </Button>
                  </div>
                ) : null}

                {/* Message quand aucun document n'est disponible */}
                {!contract.contract_pdf_url && !loadingSignedPdf && !signedPdfData?.hasSignedPdf && (
                  <div className="text-center text-muted-foreground py-4">
                    <FileText className="size-8 mx-auto mb-2 opacity-50" />
                    <p>Aucun document généré</p>
                    <p className="text-sm">Utilisez le bouton "Créer le PDF" pour générer le contrat</p>
                  </div>
                )}

                {/* Bouton pour upload manuel du contrat signé */}
                <Separator className="my-4" />
                <div className="flex flex-col gap-2">
                  <p className="text-sm font-medium">Upload manuel</p>
                  <Button
                    variant="outline"
                    size="sm"
                    onClick={() => setIsUploadModalOpen(true)}
                    className="w-full"
                  >
                    <Upload className="size-4 mr-2" />
                    Ajouter le contrat signé manuellement
                  </Button>
                  <p className="text-xs text-muted-foreground">
                    Si vous avez reçu le contrat signé par email ou autre moyen
                  </p>
                </div>
              </CardContent>
            </Card>

            <Card className="rounded-3xl">
              <CardHeader className="bg-pink-50 rounded-t-xl">
                <CardTitle className="flex flex-col gap-3">
                  <div className="flex items-center justify-between">
                    <div className="flex items-center gap-2">
                      <CalendarRange className="size-5" /> Paies ({rows.length})
                    </div>
                    {contractType === "CDDU_MONO" && (
                      <Button
                        onClick={() => handleOpenPayslipModal()}
                        variant="outline"
                        size="sm"
                        className="rounded-2xl"
                      >
                        <FilePlus2 className="size-4 mr-2" />
                        Ajouter une paie
                      </Button>
                    )}
                  </div>
                  {(contractType === "RG" || contractType === "CDDU_MULTI") && (
                    <div className="flex items-center justify-between">
                      <span className="text-sm font-normal text-muted-foreground bg-slate-100 px-3 py-1.5 rounded-full">
                        {contractType === "RG" ? "Régime Général" : "CDDU Multi-mois"}
                      </span>
                      <Button
                        onClick={() => handleOpenPayslipModal()}
                        variant="outline"
                        size="sm"
                        className="rounded-2xl"
                      >
                        <FilePlus2 className="size-4 mr-2" />
                        Ajouter une paie
                      </Button>
                    </div>
                  )}
                </CardTitle>
              </CardHeader>
              <CardContent className="space-y-4">
                {rows.length === 0 ? (
                  <div className="text-center text-gray-500 py-8">
                    <CalendarRange className="size-12 mx-auto mb-4 text-gray-300" />
                    <p>Aucune paie enregistrée</p>
                    <p className="text-sm">Cliquez sur "Ajouter une paie" pour commencer</p>
                  </div>
                ) : (
                  <>
                    {contractType === "CDDU_MONO" ? (
                      // Affichage normal pour CDDU mono-mois
                      <div className="space-y-3">
                        {displayedPayslips.map((payslip, i) => (
                          <PayslipCard
                            key={payslip.id ?? i}
                            payslip={payslip}
                            index={i}
                            contractId={contract.id}
                            onClick={() => handleOpenPayslipModal(payslip)}
                            onUploadComplete={handlePayslipUploadComplete}
                          />
                        ))}
                      </div>
                    ) : (
                      // Affichage compact pour RG et CDDU multi-mois
                      <>
                        <div className="space-y-2">
                          {displayedPayslips.map((payslip, i) => (
                            <div
                              key={payslip.id ?? i}
                              onClick={() => handleOpenPayslipModal(payslip)}
                              className="p-3 border rounded-xl hover:bg-slate-50 cursor-pointer transition-colors"
                            >
                              <div className="flex items-start gap-6">
                                <div className="bg-blue-100 text-blue-800 px-2 py-1 rounded-full text-xs font-medium shrink-0">
                                  #{payslip.pay_number || (payslipPage * payslipsPerPage + i + 1)}
                                </div>
                                <div className="flex-1 min-w-0">
                                  <div className="font-normal text-sm text-gray-600 whitespace-nowrap mb-3">
                                    {payslip.period_start && payslip.period_end ? (
                                      `${new Date(payslip.period_start).toLocaleDateString('fr-FR', { month: 'short', year: 'numeric' })}`
                                    ) : (
                                      "Période non définie"
                                    )}
                                  </div>
                                  <div className="flex gap-1.5 flex-nowrap">
                                    {payslip.storage_path && (
                                      <span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-50 text-green-600 whitespace-nowrap">
                                        <CheckCircle2 className="size-3 mr-1" />
                                        PDF
                                      </span>
                                    )}
                                    {payslip.processed ? (
                                      <span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-50 text-green-600 whitespace-nowrap">
                                        Traitée
                                      </span>
                                    ) : (
                                      <span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-red-50 text-red-600 whitespace-nowrap">
                                        À traiter
                                      </span>
                                    )}
                                    {/* Statut AEM */}
                                    <span className={`inline-flex items-center px-2 py-1 rounded-full text-xs font-medium whitespace-nowrap ${
                                      payslip.aem_status === 'OK' 
                                        ? 'bg-green-50 text-green-600' 
                                        : payslip.aem_status === 'KO'
                                        ? 'bg-red-50 text-red-600'
                                        : 'bg-gray-50 text-gray-600'
                                    }`}>
                                      AEM: {payslip.aem_status || 'N/A'}
                                    </span>
                                  </div>
                                </div>
                                <div className="flex gap-10 text-right shrink-0 ml-10">
                                  <div className="leading-tight">
                                    <div className="font-semibold text-sm">
                                      {payslip.gross_amount ? `${parseFloat(payslip.gross_amount).toFixed(2)}€` : "—"}
                                    </div>
                                    <div className="text-xs text-gray-500">Brut</div>
                                  </div>
                                  <div className="leading-tight">
                                    <div className="font-semibold text-sm">
                                      {payslip.net_after_withholding ? `${parseFloat(payslip.net_after_withholding).toFixed(2)}€` : "—"}
                                    </div>
                                    <div className="text-xs text-gray-500">Net à payer</div>
                                  </div>
                                </div>
                              </div>
                            </div>
                          ))}
                        </div>
                        
                        {needsPagination && (
                          <div className="flex items-center justify-center gap-2 pt-2">
                            <Button
                              onClick={() => setPayslipPage(prev => Math.max(0, prev - 1))}
                              disabled={payslipPage === 0}
                              variant="outline"
                              size="sm"
                              className="rounded-lg"
                            >
                              Précédent
                            </Button>
                            <span className="text-sm text-muted-foreground px-3">
                              Page {payslipPage + 1} sur {totalPayslipPages}
                            </span>
                            <Button
                              onClick={() => setPayslipPage(prev => Math.min(totalPayslipPages - 1, prev + 1))}
                              disabled={payslipPage >= totalPayslipPages - 1}
                              variant="outline"
                              size="sm"
                              className="rounded-lg"
                            >
                              Suivant
                            </Button>
                          </div>
                        )}
                      </>
                    )}
                  </>
                )}
              </CardContent>
            </Card>

            {/* Section Notes */}
            <div className="rounded-3xl overflow-hidden">
              <NotesSection 
                contractId={contract.id} 
                contractRef={contract.contract_number || contract.reference}
                source="Renaud [Staff Odentas]"
              />
            </div>
          </div>
        </div>
      </div>
      
      {/* Loading Modals */}
      <LoadingModal
        isOpen={isSaving}
        title="Sauvegarde en cours..."
        description="Veuillez patienter pendant la sauvegarde du contrat."
        success={showSaveSuccess}
        successMessage="Contrat sauvegardé avec succès !"
        onClose={() => setShowSaveSuccess(false)}
      />
      
      <LoadingModal
        isOpen={isGeneratingPdf}
        title="Génération du PDF en cours..."
        description="Création du document de contrat, cela peut prendre quelques instants."
        success={showPdfSuccess}
        successMessage="PDF créé avec succès !"
        onClose={() => setShowPdfSuccess(false)}
      />
      
      {/* Payslip Modal */}
      <PayslipModal
        isOpen={isPayslipModalOpen}
        payslip={editingPayslip}
        contractId={contract.id}
        contractNumber={contract.contract_number}
        onClose={handleClosePayslipModal}
        onSuccess={handlePayslipModalSuccess}
      />

      {/* Employer Reminder Modal */}
      <EmployerReminderModal
        isOpen={isReminderModalOpen}
        onClose={handleCloseReminderModal}
        onConfirm={handleSendEmployerReminder}
        isLoading={isSendingReminder}
        contractData={{
          reference: contract.reference || contract.contract_number,
          employee_name: contract.employee_name,
          employer_email: organizationData?.email_signature,
          employer_name: organizationData?.organization_name
        }}
      />

      {/* E-Sign Confirmation Modal */}
      <ESignConfirmModal
        isOpen={showESignConfirmModal}
        onClose={() => setShowESignConfirmModal(false)}
        onConfirm={handleConfirmESign}
        contractReference={reference || contract.reference || contract.contract_number}
        employeeName={salarie?.nom || contract.employee_name}
        employeeEmail={verifiedEmployeeEmail}
        employerEmail={verifiedEmployerEmail}
        isLoading={isLaunchingSignature}
      />

      {/* Manual Signed Contract Upload Modal */}
      <ManualSignedContractUpload
        contractId={contract.id}
        contractNumber={contract.contract_number}
        open={isUploadModalOpen}
        onOpenChange={setIsUploadModalOpen}
        onSuccess={() => {
          // Invalider la query pour rafraîchir les données du contrat signé
          queryClient.invalidateQueries({ queryKey: ["signed-contract-pdf", contract.id] });
        }}
      />

      {/* Dates Quantity Modal for precise selection */}
      <DatesQuantityModal
        isOpen={quantityModalOpen}
        onClose={() => {
          setQuantityModalOpen(false);
          setPendingDates([]);
        }}
        selectedDates={pendingDates}
        dateType={quantityModalType || "jours_travail"}
        onApply={handleQuantityApply}
        allowSkipHoursByDay={quantityModalType === "jours_travail"}
      />

      {/* Cancel Contract Modal */}
      <CancelContractModal
        isOpen={showCancelModal}
        onClose={() => setShowCancelModal(false)}
        onConfirm={handleCancelContract}
        isCancelling={isCancelling}
        contractInfo={{
          contract_number: contract.contract_number || contract.reference,
          employee_name: contract.employee_name || contract.salaries?.salarie,
        }}
      />

      {/* Delete Signed PDF Confirmation Modal */}
      <Dialog open={showDeleteSignedPdfModal} onOpenChange={setShowDeleteSignedPdfModal}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Supprimer le contrat signé</DialogTitle>
            <DialogDescription>
              Êtes-vous sûr de vouloir supprimer le contrat signé ?
              Cette action est irréversible et supprimera le fichier du stockage.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter className="gap-2">
            <Button
              variant="outline"
              onClick={() => setShowDeleteSignedPdfModal(false)}
              disabled={isDeletingSignedPdf}
            >
              Annuler
            </Button>
            <Button
              variant="default"
              onClick={handleDeleteSignedPdf}
              disabled={isDeletingSignedPdf}
              className="bg-red-600 hover:bg-red-700 text-white"
            >
              {isDeletingSignedPdf ? (
                <>
                  <RefreshCw className="size-4 mr-2 animate-spin" />
                  Suppression...
                </>
              ) : (
                <>
                  <Ban className="size-4 mr-2" />
                  Supprimer
                </>
              )}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}