"use client";

import Link from "next/link";
import Script from "next/script";
import { useParams } from "next/navigation";
import { useMemo, useState, useEffect } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { ArrowLeft, Download, Info, Loader2, Clock, CheckCircle, Euro, PenTool, XCircle, Users, Send, AlertTriangle, X, ExternalLink, AlertCircle } from "lucide-react";
import { NotesSection } from "@/components/NotesSection";
import { Button } from "@/components/ui/button";
import { ConfirmationModal } from "@/components/ui/confirmation-modal";
import { LoadingModal } from "@/components/ui/loading-modal";
import DocumentsCard from "@/components/contrats/DocumentsCard";
import { toast } from "sonner";
import { usePageTitle } from "@/hooks/usePageTitle";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";

/* =========================
   Types attendus du backend
   ========================= */
type StatutSimple = "oui" | "non" | "na" | "en_attente";
type EtatDemande =
  | "pre-demande"
  | "demande-recue"
  | "envoye"
  | "signe"
  | "modification"
  | "traitee"
  | "non_commence";

type ContratMultiDetail = {
  id: string;
  numero: string;                  // ex YW2KSC85
  regime: "CDDU_MULTI";
  is_multi_mois: true;             // drapeau utile
  salarie: { nom: string; email?: string };
  salarie_matricule?: string;     // Matricule API du/de la salarié·e pour lien fiche
  production: string;
  objet?: string;
  profession: string;
  categorie_prof?: string;
  type_salaire?: string;
  salaire_demande?: string;
  date_debut: string;              // ISO
  date_fin: string;                // ISO
  panier_repas?: StatutSimple;

  // État & signatures
  etat_demande: EtatDemande;
  contrat_signe_employeur: StatutSimple;
  contrat_signe_salarie: StatutSimple;
  etat_contrat?: "non_commence" | "en_cours" | "termine";

  // PDFs rattachés à la demande
  pdf_contrat?: { available: boolean; url?: string };
  pdf_avenant?: { available: boolean; url?: string };

  // Déclarations
  dpae?: "a_traiter" | "envoyee" | "refusee" | "retour_ok";

  // Temps de travail cumulé
  jours_travailles?: string | number;
  nb_representations?: number;
  nb_services_repetitions?: number;
  nb_heures_repetitions?: number;
  nb_heures_annexes?: number;
  nb_cachets_aem?: number;
  nb_heures_aem?: number;
};

type PaieMulti = {
  id: string;
  ordre: number;                   // 1,2,3… (Numéro de paie)
  mois: number;                    // 1..12
  annee: number;                   // 2024
  aem_statut?: "a_traiter" | "ok" | string | null;
  paie_pdf?: string | null;        // URL
  net_a_payer?: string | null;
  net_avant_pas?: string | null;
  brut?: string | null;
  cout_total?: string | null;
  transfer_done?: boolean | null;  // Champ pour le statut de paiement (même que payslips)
  traite?: "oui" | "non" | string | null;
  paie_traitee?: string | null;    // Période de paie (ex: "01/08/2025 – 31/08/2025")
};

/* ==============
   Data fetching
   ============== */
function useContrat(id: string) {
  return useQuery({
    queryKey: ["contrat-multi", id],
    queryFn: async () => {
      const res = await fetch(`/api/contrats/${id}`, {
        credentials: "include",
        headers: {
          Accept: "application/json",
          "Content-Type": "application/json",
        },
      });
      if (res.status === 403) {
        const msg = await res.text().catch(() => "");
        throw new Error(msg || "access_denied");
      }
      if (res.status === 404) {
        throw new Error("not_found");
      }
      if (!res.ok) {
        const t = await res.text().catch(() => "");
        throw new Error(t || `http_${res.status}`);
      }
      const data = (await res.json()) as ContratMultiDetail;
      return data;
    },
    staleTime: 15_000,
    enabled: Boolean(id),
    retry: (failureCount, error: any) => {
      const msg = String(error?.message || "");
      if (msg.includes("access_denied") || msg.includes("not_found")) return false;
      return failureCount < 3;
    },
  });
}

type Payslip = {
  id: string;
  contract_id: string;
  period_start: string;
  period_end: string;
  period_month: string;
  pay_number: number;
  gross_amount: string;
  net_amount: string;
  net_after_withholding: string;
  employer_cost: string;
  pay_date: string | null;
  processed: boolean;
  aem_status: string;
  transfer_done: boolean;
  analytic_tag: string;
  storage_path: string;
  source_reference: string;
  created_at: string;
};

// Type pour les URLs pré-signées retournées par l'API
type PayslipWithUrl = {
  id: string;
  pay_number: number;
  period_start: string;
  period_end: string;
  pay_date: string | null;
  gross_amount: string;
  net_amount: string;
  net_after_withholding: string;
  processed: boolean;
  aem_status: string;
  signedUrl: string | null;
  hasDocument: boolean;
};

function usePaies(id: string) {
  return useQuery({
    queryKey: ["contrat-multi-paies", id],
    queryFn: async () => {
      if (process.env.NODE_ENV !== 'production') {
        console.log("🔍 Fetching payslips from Supabase for contract:", id);
      }
      
      // Utiliser le même endpoint que les contrats normaux
      const url = `/api/payslips?contract_id=${encodeURIComponent(id)}`;
      const res = await fetch(url, {
        credentials: "include",
        headers: { Accept: "application/json" }
      });

      if (process.env.NODE_ENV !== 'production') {
        console.log("📥 Payslips response:", { status: res.status, statusText: res.statusText, contractId: id });
      }

      if (res.status === 403) {
        if (process.env.NODE_ENV !== 'production') {
          console.error("❌ Payslips access denied");
        }
        throw new Error("access_denied");
      }
      
      if (res.status === 404) {
        if (process.env.NODE_ENV !== 'production') {
          console.log("ℹ️ Payslips not found (404), returning empty list");
        }
        // Retourner une liste vide avec le format attendu
        return { items: [] as PaieMulti[] };
      }
      
      if (!res.ok) {
        const t = await res.text().catch(() => "");
        if (process.env.NODE_ENV !== 'production') {
          console.error("❌ Payslips error:", { status: res.status, error: t, contractId: id });
        }
        throw new Error(t || `HTTP ${res.status}`);
      }
      
      const payslips = (await res.json()) as Payslip[];
      
      if (process.env.NODE_ENV !== 'production') {
        console.log("✅ Payslips data received:", { contractId: id, count: payslips.length, payslips });
      }
      
      // Convertir les payslips en format PaieMulti
      const items: PaieMulti[] = payslips.map((slip) => ({
        id: slip.id,
        ordre: slip.pay_number,
        mois: parseInt(slip.period_month.split('-')[1] || '0'),
        annee: parseInt(slip.period_month.split('-')[0] || '0'),
        aem_statut: slip.aem_status || null,
        paie_pdf: slip.storage_path || null,
        net_a_payer: slip.net_after_withholding || null,
        net_avant_pas: slip.net_amount || null,
        brut: slip.gross_amount || null,
        cout_total: slip.employer_cost || null,
        transfer_done: slip.transfer_done,
        traite: slip.processed ? "oui" : "non",
        paie_traitee: `${slip.period_start} – ${slip.period_end}`,
      }));
      
      return { items };
    },
    staleTime: 15_000,
    enabled: Boolean(id),
    retry: (failureCount, error: any) => {
      const msg = String(error?.message || "");
      if (msg.includes("access_denied")) return false;
      return failureCount < 3;
    },
  });
}

// Nouveau hook pour récupérer les URLs pré-signées
function usePayslipUrls(id: string) {
  return useQuery({
    queryKey: ["payslip-urls", id],
    queryFn: async () => {
      const response = await fetch(`/api/contrats/${id}/payslip-urls`, {
        credentials: 'include',
        headers: { Accept: 'application/json' }
      });

      if (!response.ok) {
        console.error("Erreur lors de la récupération des URLs de fiches de paie");
        return { payslips: [] as PayslipWithUrl[] };
      }

      const data = await response.json();
      return { payslips: data.payslips || [] as PayslipWithUrl[] };
    },
    staleTime: 15_000,
    enabled: Boolean(id),
  });
}

/* =========
   Helpers
   ========= */
function Section({ title, children }: { title: React.ReactNode; children: React.ReactNode }) {
  return (
    <section className="rounded-2xl border bg-white">
      <div className="px-4 py-3 border-b font-medium text-slate-700 bg-slate-50/60">
        {title}
      </div>
      <div className="p-4">{children}</div>
    </section>
  );
}

function formatPeriodDisplay(periodStr?: string | null) {
  if (!periodStr) return null;
  // Expected formats: "YYYY-MM-DD – YYYY-MM-DD" or similar. Split on '–' or '-'
  const parts = periodStr.split(/\s*–\s*|\s*-\s*/);
  if (parts.length === 0) return periodStr;
  const left = parts[0]?.trim();
  const right = parts[1]?.trim();
  try {
    const parseISO = (s?: string | null) => {
      if (!s) return null;
      // If format is YYYY-MM-DD or YYYY-MM, ensure correct parsing
      const m = s.match(/^(\d{4})-(\d{2})-(\d{2})$/);
      if (m) return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
      const m2 = s.match(/^(\d{4})-(\d{2})$/);
      if (m2) return new Date(Number(m2[1]), Number(m2[2]) - 1, 1);
      const d = new Date(s);
      return isNaN(d.getTime()) ? null : d;
    };
    const L = parseISO(left);
    const R = parseISO(right);
    if (L && R) return `${formatDateFR(L)} – ${formatDateFR(R)}`;
    if (L) return formatDateFR(L);
    if (R) return formatDateFR(R);
    return periodStr;
  } catch (e) {
    return periodStr;
  }
}

function formatDateFR(iso?: string | Date) {
  if (!iso) return "—";
  const d = iso instanceof Date ? iso : new Date(String(iso));
  if (isNaN(d.getTime())) return String(iso);
  return d.toLocaleDateString("fr-FR", { day: "2-digit", month: "2-digit", year: "numeric" });
}

function Field({
  label,
  value,
  action,
}: {
  label: string;
  value?: React.ReactNode;
  action?: React.ReactNode;
}) {
  return (
    <div className="grid grid-cols-1 sm:grid-cols-[220px_1fr_auto] gap-2 items-center py-2">
      <div className="text-sm text-slate-500">{label}</div>
      <div className="text-sm">{value ?? <span className="text-slate-400">—</span>}</div>
      {action ? <div className="justify-self-end">{action}</div> : null}
    </div>
  );
}

function Badge({
  children,
  tone = "default" as "default" | "ok" | "warn" | "error" | "info",
}: {
  children: React.ReactNode;
  tone?: "default" | "ok" | "warn" | "error" | "info";
}) {
  const cls =
    tone === "ok"
      ? "bg-emerald-100 text-emerald-800"
      : tone === "warn"
      ? "bg-amber-100 text-amber-800"
      : tone === "error"
      ? "bg-rose-100 text-rose-800"
      : tone === "info"
      ? "bg-sky-100 text-sky-800"
      : "bg-slate-100 text-slate-700";
  return <span className={`text-xs px-2 py-1 rounded-full ${cls}`}>{children}</span>;
}

function boolBadge(v?: StatutSimple | boolean | null) {
  if (typeof v === "boolean") return v ? <Badge tone="ok">Oui</Badge> : <Badge tone="error">Non</Badge>;
  if (v === "oui") return <Badge tone="ok">Oui</Badge>;
  if (v === "non") return <Badge tone="error">Non</Badge>;
  if (v === "en_attente") return <Badge tone="info">En cours</Badge>;
  return <Badge>n/a</Badge>;
}

function stateBadgeDemande(s?: EtatDemande) {
  const input = String(s || "").trim();
  const normalized = input
    .toLowerCase()
    .normalize("NFD")
    .replace(/\p{Diacritic}/gu, "")
    .replace(/\s+/g, " ")
    .replace(/-/g, " ")
    .replace(/_/g, " ");

  // Mapping des 4 états principaux avec couleurs adaptées
  type Style = { bg: string; border: string; text: string; label: string };
  
  // Détection intelligente des états
  let style: Style;
  
  if (normalized.includes("pre") || normalized.includes("demande")) {
    // Pré-demande - Gris (neutre)
    style = { 
      bg: "bg-slate-50", 
      border: "border-slate-200", 
      text: "text-slate-700", 
      label: "Pré-demande" 
    };
  } else if (normalized.includes("recu") || normalized.includes("recue")) {
    // Reçue - Bleu (information)
    style = { 
      bg: "bg-blue-50", 
      border: "border-blue-200", 
      text: "text-blue-800", 
      label: "Reçue" 
    };
  } else if (normalized.includes("cours") || normalized.includes("traitement")) {
    // En cours de traitement - Orange (en attente)
    style = { 
      bg: "bg-orange-50", 
      border: "border-orange-200", 
      text: "text-orange-800", 
      label: "En cours de traitement" 
    };
  } else if (normalized.includes("traitee") || normalized.includes("traite")) {
    // Traitée - Vert (succès)
    style = { 
      bg: "bg-emerald-50", 
      border: "border-emerald-200", 
      text: "text-emerald-800", 
      label: "Traitée" 
    };
  } else {
    // Fallback - Affichage de la valeur brute avec style neutre
    style = { 
      bg: "bg-slate-50", 
      border: "border-slate-200", 
      text: "text-slate-700", 
      label: input || "—" 
    };
  }

  return (
    <div className={`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-lg border text-xs ${style.bg} ${style.border} ${style.text}`}>
      {style.label}
    </div>
  );
}


function formatEUR(v?: string | number | null) {
  if (v === null || v === undefined || v === "") return "—";
  // Autorise nombres sous forme de chaîne avec séparateurs
  const num = typeof v === "number" ? v : Number(String(v).replace(/[^0-9,.-]/g, "").replace(",", "."));
  if (!Number.isFinite(num)) return String(v);
  return num.toLocaleString("fr-FR", { style: "currency", currency: "EUR" });
}

function monthLabelSafe(m?: number) {
  if (typeof m !== "number" || !Number.isFinite(m) || m < 1 || m > 12) return null;
  return new Date(2025, m - 1, 1).toLocaleDateString("fr-FR", { month: "long" });
}

function payLabel(p: PaieMulti) {
  const ml = monthLabelSafe(p.mois);
  if (ml && p.annee) return `${ml} ${p.annee}`;
  if (ml) return ml;
  if (p.annee) return String(p.annee);
  return "";
}

/* =====
   Page
   ===== */
export default function ContratMultiPage() {
  const { id } = useParams<{ id: string }>();

  const { data, isLoading, isError, error } = useContrat(id);
  
  // Titre dynamique basé sur le numéro du contrat
  const contractTitle = data?.numero ? `Contrat ${data.numero}` : `Contrat multi-mois`;
  usePageTitle(contractTitle);
  
  const { data: paiesData, isLoading: paiesLoading, isError: paiesError, error: paiesErrorObj } = usePaies(id);
  const { data: payslipUrlsData } = usePayslipUrls(id);

  // State pour la modale de confirmation de paiement
  const [showPaymentModal, setShowPaymentModal] = useState<boolean>(false);
  const [selectedPaieId, setSelectedPaieId] = useState<string>("");
  const [selectedPaieStatus, setSelectedPaieStatus] = useState<boolean>(false);

  // State pour la modale de signature DocuSeal
  const [embedSrc, setEmbedSrc] = useState<string>("");
  const [modalTitle, setModalTitle] = useState<string>("");
  const [signatureB64ForDocuSeal, setSignatureB64ForDocuSeal] = useState<string | null>(null);
  
  // State pour la modale de chargement
  const [isLoadingSignature, setIsLoadingSignature] = useState<boolean>(false);

  // State pour la modale d'erreur DocuSeal
  const [showErrorModal, setShowErrorModal] = useState<boolean>(false);

  // State pour la modale de visualisation des fiches de paie
  const [isPayslipModalOpen, setIsPayslipModalOpen] = useState<boolean>(false);
  const [currentPayslipUrl, setCurrentPayslipUrl] = useState<string>("");
  const [currentPayslipTitle, setCurrentPayslipTitle] = useState<string>("");
  const [payslipPdfError, setPayslipPdfError] = useState<boolean>(false);

  // Query client pour la mise à jour du cache
  const queryClient = useQueryClient();

  // Effet pour bloquer le défilement quand le modal DocuSeal est ouvert
  useEffect(() => {
    // Vérifier si le dialog est ouvert en surveillant embedSrc
    const dlg = document.getElementById('dlg-signature') as HTMLDialogElement | null;
    if (dlg && embedSrc) {
      // Bloquer le défilement du body
      document.body.style.overflow = 'hidden';
      
      // Observer pour détecter la fermeture du dialog
      const observer = new MutationObserver(() => {
        if (!dlg.open) {
          document.body.style.overflow = '';
        }
      });
      
      observer.observe(dlg, { attributes: true, attributeFilter: ['open'] });
      
      return () => {
        observer.disconnect();
        document.body.style.overflow = '';
      };
    } else {
      // S'assurer que le défilement est rétabli si embedSrc est vide
      document.body.style.overflow = '';
    }
  }, [embedSrc]);

  // Effet pour bloquer le défilement quand le modal de fiche de paie est ouvert
  useEffect(() => {
    if (isPayslipModalOpen) {
      document.body.style.overflow = 'hidden';
      
      // Handler pour fermer avec Escape
      const handleEscape = (e: KeyboardEvent) => {
        if (e.key === 'Escape') {
          setIsPayslipModalOpen(false);
        }
      };
      
      document.addEventListener('keydown', handleEscape);
      
      return () => {
        document.body.style.overflow = '';
        document.removeEventListener('keydown', handleEscape);
      };
    } else {
      document.body.style.overflow = '';
    }
  }, [isPayslipModalOpen]);

  // Fonction pour ouvrir une fiche de paie dans le modal
  const openPayslipInModal = (url: string, title: string) => {
    setCurrentPayslipUrl(url);
    setCurrentPayslipTitle(title);
    setPayslipPdfError(false);
    setIsPayslipModalOpen(true);
  };

  // Mutation pour marquer une paie multi comme payée/non payée
  const markAsPaidMutation = useMutation({
    mutationFn: async ({ payslipId, transferDone }: { payslipId: string; transferDone: boolean }) => {
      const response = await fetch(`/api/payslips/${payslipId}`, {
        method: 'PATCH',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ transfer_done: transferDone }),
      });

      if (!response.ok) {
        const error = await response.json();
        throw new Error(error.error || 'Erreur lors de la mise à jour');
      }

      return response.json();
    },
    onSuccess: (_, variables) => {
      // Recharger les données des paies
      queryClient.invalidateQueries({ queryKey: ["contrat-multi-paies", id] });
      toast.success(variables.transferDone ? "Paiement marqué comme effectué !" : "Paiement marqué comme non effectué !");
      setShowPaymentModal(false);
      setSelectedPaieId("");
      setSelectedPaieStatus(false);
    },
    onError: (error: Error) => {
      toast.error("Erreur : " + error.message);
    },
  });

  // Fonction pour ouvrir le modal de confirmation
  const handleTogglePayment = (paieId: string, currentStatus: boolean) => {
    setSelectedPaieId(paieId);
    setSelectedPaieStatus(!currentStatus);
    setShowPaymentModal(true);
  };

  // Fonction pour confirmer le changement de statut
  const confirmTogglePayment = () => {
    if (selectedPaieId) {
      markAsPaidMutation.mutate({ 
        payslipId: selectedPaieId, 
        transferDone: selectedPaieStatus 
      });
    }
  };

  // Calcule l'état du contrat en fonction des dates et de l'état de la demande (même logique que contrats/[id])
  const etatContratCalcule = useMemo(() => {
    if (!data) return undefined;

    // Si l'état de la demande est Annulée → Annulé
    const etatDemandeNorm = String(data.etat_demande || "")
      .toLowerCase()
      .normalize("NFD")
      .replace(/\p{Diacritic}/gu, "");
    if (etatDemandeNorm.includes("annule")) {
      return "Annulé" as const;
    }

    // Si dates manquantes, on retombe sur l'ancien fallback
    if (!data.date_debut || !data.date_fin) return undefined;

    const toLocalDateOnly = (iso: string) => {
      const d = new Date(iso);
      // Normalise à minuit local pour une comparaison en J/J inclusif
      return new Date(d.getFullYear(), d.getMonth(), d.getDate());
    };

    const start = toLocalDateOnly(data.date_debut);
    const end = toLocalDateOnly(data.date_fin);
    const today = new Date();
    const current = new Date(today.getFullYear(), today.getMonth(), today.getDate());

    if (current < start) return "Non commencé" as const;
    if (current > end) return "Terminé" as const;
    return "En cours" as const; // inclusif entre début et fin
  }, [data]);

  const title = useMemo(() => (data ? `Contrat n° ${data.numero}` : "Contrat"), [data]);

  // Créer un map des URLs signées par ID de payslip (AVANT les retours conditionnels)
  const payslipUrlsMap = useMemo(() => {
    const map = new Map<string, string>();
    if (payslipUrlsData?.payslips) {
      for (const payslip of payslipUrlsData.payslips) {
        if (payslip.signedUrl) {
          map.set(payslip.id, payslip.signedUrl);
        }
      }
    }
    return map;
  }, [payslipUrlsData]);

  if (isLoading) {
    return (
      <div className="rounded-2xl border bg-white p-10 text-center text-slate-500">
        <Loader2 className="w-4 h-4 inline animate-spin mr-2" />
        Chargement du contrat…
      </div>
    );
  }

  if (isError || !data) {
    return (
      <div className="rounded-2xl border bg-white p-6">
        <div className="text-rose-600 font-medium mb-2">Impossible de charger ce contrat.</div>
        <div className="text-sm text-slate-500">{(error as any)?.message || "Erreur inconnue"}</div>
        <div className="mt-4">
          <Link className="inline-flex items-center gap-2 px-3 py-2 rounded-lg border" href="/contrats">
            <ArrowLeft className="w-4 h-4" /> Retour aux contrats
          </Link>
        </div>
      </div>
    );
  }

  // Fonction pour déterminer l'état de la signature électronique
  const getSignatureStatus = () => {
    const etatDemande = data.etat_demande;
    const contratSigneEmployeur = data.contrat_signe_employeur;
    const contratSigne = data.contrat_signe_salarie;
    
    // Détermine le statut
    if (contratSigneEmployeur === "oui" && contratSigne === "oui") {
      return {
        status: "completed" as const,
        label: "Complété",
        icon: CheckCircle,
        color: "text-green-600",
        bgColor: "bg-green-50",
        borderColor: "border-green-200"
      };
    } else if (contratSigneEmployeur === "oui" && contratSigne !== "oui") {
      return {
        status: "waiting_employee" as const,
        label: "En attente salarié",
        icon: Users,
        color: "text-blue-600",
        bgColor: "bg-blue-50",
        borderColor: "border-blue-200"
      };
    } else if (String(etatDemande || "").toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, '').includes("traitee") || String(etatDemande || "").toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, '').includes("traitée")) {
      return {
        status: "waiting_employer" as const,
        label: "En attente employeur",
        icon: Send,
        color: "text-orange-600", 
        bgColor: "bg-orange-50",
        borderColor: "border-orange-200"
      };
    } else {
      return {
        status: "not_sent" as const,
        label: "Non envoyé",
        icon: Clock,
        color: "text-gray-600",
        bgColor: "bg-gray-50", 
        borderColor: "border-gray-200"
      };
    }
  };

  // Fonction pour ouvrir la signature DocuSeal
  async function openSignature() {
    if (!data) return;
    
    // Afficher la modale de chargement
    setIsLoadingSignature(true);
    
    let embed: string | null = null;
    const title = `Signature (Employeur) · ${data.numero}`;
    setModalTitle(title);

    console.log('🔍 [SIGNATURE] Debug - data complète:', data);
    console.log('🔍 [SIGNATURE] Debug - data.id:', data.id);

    // Utiliser notre API pour récupérer les données de signature avec service role
    try {
      const response = await fetch(`/api/contrats/${data.id}/signature`, {
        credentials: 'include',
        headers: {
          'Accept': 'application/json'
        }
      });

      if (!response.ok) {
        if (response.status === 404) {
          setIsLoadingSignature(false);
          toast.error("Ce contrat n'a pas encore de signature électronique configurée. Veuillez d'abord créer la signature via l'interface d'édition du contrat.");
          return;
        }
        throw new Error(`Erreur API: ${response.status}`);
      }

      const result = await response.json();
      console.log('📋 [SIGNATURE] Données contrat depuis API:', result);
      console.log('🔍 [SIGNATURE] result.data:', result.data);
      console.log('🔍 [SIGNATURE] result.data.signature_b64:', result.data?.signature_b64);

      if (!result.success || !result.data) {
        setIsLoadingSignature(false);
        toast.error("Aucune donnée de signature trouvée pour ce contrat");
        return;
      }

      const contractData = result.data;
      console.log('📦 [SIGNATURE] contractData extrait:', contractData);

      // Stocker la signature si disponible
      const signatureB64 = contractData.signature_b64;
      console.log('🖊️ [SIGNATURE] signatureB64 extraite:', {
        exists: !!signatureB64,
        type: typeof signatureB64,
        length: signatureB64?.length,
        preview: signatureB64?.substring(0, 50)
      });
      
      if (signatureB64) {
        console.log('✅ [SIGNATURE] Signature B64 disponible, longueur:', signatureB64.length);
      } else {
        console.log('⚠️ [SIGNATURE] Aucune signature B64 disponible');
      }

      // Vérifier si la soumission DocuSeal n'a pas été créée
      if (!contractData.docuseal_submission_id && contractData.signature_status === "Non initiée") {
        setIsLoadingSignature(false);
        setShowErrorModal(true);
        return;
      }

      // 1) Si on a un signature_link direct, l'utiliser
      if (contractData.signature_link) {
        console.log('🔗 [SIGNATURE] Signature link trouvé:', contractData.signature_link);
        
        // Extraire le docuseal_id du lien de signature
        const signatureLinkMatch = contractData.signature_link.match(/docuseal_id=([^&]+)/);
        if (signatureLinkMatch) {
          const docusealId = signatureLinkMatch[1];
          
          // L'URL doit être propre sans paramètres
          embed = `https://docuseal.eu/s/${docusealId}`;
          console.log('🔗 [SIGNATURE] URL embed depuis signature_link:', embed);
        }
      }

      // 2) Sinon, récupérer via l'API DocuSeal à partir du template_id
      if (!embed && contractData.docuseal_template_id) {
        console.log('🔍 [SIGNATURE] Template ID trouvé:', contractData.docuseal_template_id);
        
        try {
          const tId = String(contractData.docuseal_template_id);
          
          const subRes = await fetch(`/api/docuseal/templates/${encodeURIComponent(tId)}/submissions`, { cache: 'no-store' });
          const subData = await subRes.json();
          
          console.log('📋 [SIGNATURE] Submissions DocuSeal:', subData);
          
          const first = Array.isArray(subData?.data) ? subData.data[0] : (Array.isArray(subData) ? subData[0] : subData);
          const subId = first?.id;
          
          if (subId) {
            const detRes = await fetch(`/api/docuseal/submissions/${encodeURIComponent(subId)}`, { cache: 'no-store' });
            const detData = await detRes.json();
            
            console.log('📋 [SIGNATURE] Détails submission DocuSeal:', detData);
            
            const roles = detData?.submitters || detData?.roles || [];
            const employer = roles.find((r: any) => (r.role || r.name) === 'Employeur') || {};
            
            if (employer?.slug) {
              // URL propre sans paramètres
              embed = `https://docuseal.eu/s/${employer.slug}`;
              console.log('🔗 [SIGNATURE] URL embed depuis DocuSeal API:', embed);
            } else {
              embed = employer?.embed_src || employer?.sign_src || detData?.embed_src || null;
              console.log('🔗 [SIGNATURE] URL embed alternative:', embed);
            }
          }
        } catch (e) {
          console.warn('❌ [SIGNATURE] DocuSeal fetch failed', e);
        }
      }

      if (embed) {
        console.log('✅ [SIGNATURE] URL embed trouvée:', embed);
        setEmbedSrc(embed);
        
        // Stocker la signature dans l'etat React pour l'ajouter au composant
        console.log('🔍 [SIGNATURE] Stockage de la signature dans l\'etat React...');
        console.log('🔍 [SIGNATURE] signatureB64 value:', signatureB64);
        
        if (signatureB64) {
          console.log('✅ [SIGNATURE] Signature B64 disponible pour pre-remplissage');
          setSignatureB64ForDocuSeal(signatureB64);
        } else {
          console.log('⚠️ [SIGNATURE] Aucune signature B64 disponible');
          setSignatureB64ForDocuSeal(null);
        }
        
        // Masquer la modale de chargement
        setIsLoadingSignature(false);
        
        // Ouvrir la modale
        const dlg = document.getElementById('dlg-signature') as HTMLDialogElement | null;
        if (dlg) {
          if (typeof dlg.showModal === 'function') {
            dlg.showModal();
          } else {
            dlg.setAttribute('open', '');
          }
        }
      } else {
        console.warn('❌ [SIGNATURE] Aucune URL d\'embed trouvée');
        setIsLoadingSignature(false);
        toast.error("Impossible de récupérer le lien de signature");
      }
    } catch (error) {
      console.error('❌ [SIGNATURE] Erreur:', error);
      setIsLoadingSignature(false);
      toast.error("Erreur lors du chargement de la signature");
    }
  }

  const paies = paiesData?.items ?? [];

  return (
    <div className="space-y-5">
      {/* Titre + breadcrumb */}
      <div className="flex flex-col md:flex-row md:items-center gap-3">
        <Link href="/contrats" className="inline-flex items-center gap-1 text-sm underline">
          <ArrowLeft className="w-4 h-4" /> Retour contrats terminés
        </Link>
      </div>

      <div className="rounded-2xl border bg-white p-4">
        <div className="flex flex-wrap items-center gap-2">
          <div className="text-lg font-semibold">{title}</div>
          <div className="h-4 w-px bg-slate-200 mx-1" />
          <div className="text-sm text-slate-500">CDDU · Multi-mois</div>
        </div>
      </div>

      {/* Disposition 2 colonnes (colonnes indépendantes en hauteur) */}
      <div className="grid grid-cols-1 md:grid-cols-2 gap-5">
        {/* Colonne gauche : Documents, Demande puis Temps de travail réel */}
        <div className="flex flex-col gap-5">
          {/* Card Documents */}
          <DocumentsCard 
            contractId={id}
            contractNumber={data.numero}
            contractData={{
              pdf_contrat: data.pdf_contrat,
              contrat_signe_employeur: data.contrat_signe_employeur,
              contrat_signe_salarie: data.contrat_signe_salarie
            }}
            showPayslips={false}
          />

          <Section title="Demande">
            <Field
              label="Salarié"
              value={
                data.salarie_matricule ? (
                  <Link href={`/salaries/${encodeURIComponent(data.salarie_matricule)}`} className="underline">
                    {data.salarie?.nom || data.salarie_matricule}
                  </Link>
                ) : (
                  data.salarie?.nom
                )
              }
            />
            <Field label="État de la demande" value={stateBadgeDemande(data.etat_demande)} />
            <Field label="Contrat signé par employeur" value={boolBadge(data.contrat_signe_employeur)} />
            <Field label="Contrat signé par salarié·e" value={boolBadge(data.contrat_signe_salarie)} />
            <Field
              label="État du contrat"
              value={
                etatContratCalcule === "Annulé" ? (
                  <Badge tone="error">Annulé</Badge>
                ) : etatContratCalcule === "En cours" ? (
                  <Badge tone="info">En cours</Badge>
                ) : etatContratCalcule === "Terminé" ? (
                  <Badge tone="ok">Terminé</Badge>
                ) : etatContratCalcule === "Non commencé" ? (
                  <Badge>Non commencé</Badge>
                ) : (
                  // Fallback sur l'ancien champ si le calcul n'est pas possible
                  data.etat_contrat === "en_cours" ? <Badge tone="info">En cours</Badge>
                  : data.etat_contrat === "termine" ? <Badge tone="ok">Terminé</Badge>
                  : <Badge>Non commencé</Badge>
                )
              }
            />
            <Field label="Spectacle" value={data.production} />
            <Field label="Numéro d’objet" value={data.objet} />
            <Field label="Profession" value={data.profession} />
            <Field label="Catégorie professionnelle" value={data.categorie_prof} />
            <Field label="Type de salaire demandé" value={data.type_salaire} />
            
            {/* Affichage conditionnel : soit salaire global, soit détail par date */}
            {(data as any).salaires_par_date ? (
              <>
                <Field label="Salaire demandé" value={(data as any).salaires_par_date.total_calcule} />
                <div className="col-span-full">
                  <div className="mt-2 p-3 bg-slate-50 rounded-lg border border-slate-200">
                    <div className="text-xs font-semibold text-slate-700 mb-2">Détail des salaires par date</div>
                    
                    {/* Représentations */}
                    {(data as any).salaires_par_date.representations && (data as any).salaires_par_date.representations.length > 0 && (
                      <div className="mb-3">
                        <div className="text-xs font-semibold text-indigo-700 uppercase tracking-wide mb-1">Représentations</div>
                        <div className="overflow-hidden rounded-md border border-slate-200">
                          <table className="w-full text-xs">
                            <thead className="bg-slate-100">
                              <tr>
                                <th className="text-left px-3 py-2 font-semibold text-slate-700 border-b border-slate-200">Date</th>
                                <th className="text-left px-3 py-2 font-semibold text-slate-700 border-b border-slate-200">Type</th>
                                <th className="text-right px-3 py-2 font-semibold text-slate-700 border-b border-slate-200">Montant</th>
                              </tr>
                            </thead>
                            <tbody className="bg-white divide-y divide-slate-100">
                              {(data as any).salaires_par_date.representations.map((rep: any, repIdx: number) => (
                                rep.items && rep.items.map((item: any, itemIdx: number) => (
                                  <tr key={`${repIdx}-${itemIdx}`} className="hover:bg-slate-50">
                                    <td className="px-3 py-2 font-medium text-slate-700">{rep.date}</td>
                                    <td className="px-3 py-2 text-slate-600">R{item.numero}</td>
                                    <td className="px-3 py-2 text-right font-semibold text-slate-900">{item.montant.toFixed(2)} €</td>
                                  </tr>
                                ))
                              ))}
                            </tbody>
                          </table>
                        </div>
                      </div>
                    )}
                    
                    {/* Répétitions */}
                    {(data as any).salaires_par_date.repetitions && (data as any).salaires_par_date.repetitions.length > 0 && (
                      <div className="mb-3">
                        <div className="text-xs font-semibold text-purple-700 uppercase tracking-wide mb-1">Répétitions</div>
                        <div className="overflow-hidden rounded-md border border-slate-200">
                          <table className="w-full text-xs">
                            <thead className="bg-slate-100">
                              <tr>
                                <th className="text-left px-3 py-2 font-semibold text-slate-700 border-b border-slate-200">Date</th>
                                <th className="text-left px-3 py-2 font-semibold text-slate-700 border-b border-slate-200">Type</th>
                                <th className="text-right px-3 py-2 font-semibold text-slate-700 border-b border-slate-200">Montant</th>
                              </tr>
                            </thead>
                            <tbody className="bg-white divide-y divide-slate-100">
                              {(data as any).salaires_par_date.repetitions.map((rep: any, repIdx: number) => (
                                rep.items && rep.items.map((item: any, itemIdx: number) => (
                                  <tr key={`${repIdx}-${itemIdx}`} className="hover:bg-slate-50">
                                    <td className="px-3 py-2 font-medium text-slate-700">{rep.date}</td>
                                    <td className="px-3 py-2 text-slate-600">S{item.numero}</td>
                                    <td className="px-3 py-2 text-right font-semibold text-slate-900">{item.montant.toFixed(2)} €</td>
                                  </tr>
                                ))
                              ))}
                            </tbody>
                          </table>
                        </div>
                      </div>
                    )}
                    
                    {/* Jours travaillés */}
                    {(data as any).salaires_par_date.jours_travail && (data as any).salaires_par_date.jours_travail.length > 0 && (
                      <div className="mb-3">
                        <div className="text-xs font-semibold text-green-700 uppercase tracking-wide mb-1">Jours travaillés</div>
                        <div className="overflow-hidden rounded-md border border-slate-200">
                          <table className="w-full text-xs">
                            <thead className="bg-slate-100">
                              <tr>
                                <th className="text-left px-3 py-2 font-semibold text-slate-700 border-b border-slate-200">Date</th>
                                <th className="text-left px-3 py-2 font-semibold text-slate-700 border-b border-slate-200">Type</th>
                                <th className="text-right px-3 py-2 font-semibold text-slate-700 border-b border-slate-200">Montant</th>
                              </tr>
                            </thead>
                            <tbody className="bg-white divide-y divide-slate-100">
                              {(data as any).salaires_par_date.jours_travail.map((jour: any, jourIdx: number) => (
                                <tr key={jourIdx} className="hover:bg-slate-50">
                                  <td className="px-3 py-2 font-medium text-slate-700">{jour.date}</td>
                                  <td className="px-3 py-2 text-slate-600">Jour</td>
                                  <td className="px-3 py-2 text-right font-semibold text-slate-900">{jour.montant.toFixed(2)} €</td>
                                </tr>
                              ))}
                            </tbody>
                          </table>
                        </div>
                      </div>
                    )}
                    
                    {/* Total */}
                    <div className="pt-2 border-t border-slate-200">
                      <div className="flex justify-between items-center">
                        <span className="text-xs font-semibold text-slate-700">Total</span>
                        <span className="text-sm font-bold text-indigo-900">{(data as any).salaires_par_date.total_calcule.toFixed(2)} €</span>
                      </div>
                    </div>
                  </div>
                </div>
              </>
            ) : (
              <Field label="Salaire demandé" value={data.salaire_demande} />
            )}
            
            <Field label="Début contrat" value={formatDateFR(data.date_debut)} />
            <Field label="Fin contrat" value={formatDateFR(data.date_fin)} />
            <Field label="Panier repas" value={boolBadge(data.panier_repas)} />
          </Section>

          <Section title="Temps de travail réel">
            <Field label="Jours travaillés" value={data.jours_travailles ?? "—"} />
            <Field label="Nbre de représentations" value={data.nb_representations ?? 0} />
            <Field label="Nbre de services répétitions" value={data.nb_services_repetitions ?? 0} />
            <Field label="Nbre d'heures répétitions" value={data.nb_heures_repetitions ?? 0} />
            <Field label="Nbre d'heures Annexes 8" value={data.nb_heures_annexes ?? 0} />
            <Field label="Nombre de cachets AEM" value={data.nb_cachets_aem ?? 0} />
            <Field label="Nombre d'heures AEM" value={data.nb_heures_aem ?? 0} />
          </Section>
        </div>

        {/* Colonne droite : Signature électronique, Déclarations, puis Paies */}
        <div className="flex flex-col gap-5">
          {/* Card 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 l'envoi</span>
                    <span className={`font-semibold ${
                      (() => {
                        const etatNormalise = String(data.etat_demande || "").toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, '');
                        return etatNormalise.includes("traitee") || etatNormalise.includes("traitée") ? "text-green-600" : "text-gray-600";
                      })()
                    }`}>
                      {(() => {
                        const etatNormalise = String(data.etat_demande || "").toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, '');
                        return etatNormalise.includes("traitee") || etatNormalise.includes("traitée") ? "Envoyé" : "En cours";
                      })()}
                    </span>
                  </div>
                  <div className="flex flex-col space-y-1">
                    <span className="text-gray-500 font-medium">Signature employeur</span>
                    <span className={`font-semibold ${
                      data.contrat_signe_employeur === "oui" ? "text-green-600" : "text-gray-600"
                    }`}>
                      {data.contrat_signe_employeur === "oui" ? "Oui" : "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 ${
                      data.contrat_signe_salarie === "oui" ? "text-green-600" : "text-gray-600"
                    }`}>
                      {data.contrat_signe_salarie === "oui" ? "Oui" : "Non"}
                    </span>
                  </div>
                </div>

                {/* Bouton Signer maintenant */}
                {(() => {
                  const etatNormalise = String(data.etat_demande || "").toLowerCase().normalize('NFD').replace(/\p{Diacritic}/gu, '');
                  const isTraitee = etatNormalise.includes("traitee") || etatNormalise.includes("traitée");
                  const signatureEmployeurNon = data.contrat_signe_employeur !== "oui";
                  
                  return (isTraitee && signatureEmployeurNon) ? (
                    <div className="pt-4 border-t">
                      <Button
                        onClick={openSignature}
                        className="w-full bg-gradient-to-r from-indigo-200 via-purple-200 to-pink-200 text-black hover:from-indigo-300 hover:via-purple-300 hover:to-pink-300"
                      >
                        <PenTool className="size-4 mr-2 text-black" />
                        Signer maintenant
                      </Button>
                    </div>
                  ) : null;
                })()}
              </div>
            </CardContent>
          </Card>

<Section title="Déclarations">
  {(() => {
    const raw = String(data.dpae || "");
    const norm = raw.normalize("NFD").replace(/\p{Diacritic}/gu, "").trim().toLowerCase();
    
    // États "OK" / "Effectuée"
    if (norm === "ok" || norm === "faite" || norm === "envoyee" || norm === "retourok" || norm === "retour_ok") {
      return (
        <Field
          label="DPAE"
          value={(
            <span className="inline-flex items-center gap-1 text-[11px] px-2 py-0.5 rounded-full bg-emerald-100 text-emerald-800">
              <CheckCircle className="w-3 h-3" /> Effectuée
            </span>
          )}
        />
      );
    }
    
    // États "À traiter" / "En cours"
    if (norm === "a traiter" || norm === "a_traiter" || norm === "a faire" || norm === "a_faire") {
      return (
        <Field
          label="DPAE"
          value={(
            <span className="inline-flex items-center gap-1 text-[11px] px-2 py-0.5 rounded-full bg-amber-100 text-amber-800">
              <Clock className="w-3 h-3" /> En cours
            </span>
          )}
        />
      );
    }
    
    // État "Refusée"
    if (norm === "refusee" || norm === "refuse") {
      return (
        <Field
          label="DPAE"
          value={(
            <span className="inline-flex items-center gap-1 text-[11px] px-2 py-0.5 rounded-full bg-rose-100 text-rose-800">
              <Clock className="w-3 h-3" /> Refusée
            </span>
          )}
        />
      );
    }
    
    // Si une valeur existe mais n'est pas reconnue, l'afficher telle quelle
    if (raw) {
      return <Field label="DPAE" value={<span className="text-xs text-slate-600">{raw}</span>} />;
    }
    
    // Aucune valeur
    return <Field label="DPAE" value={<span className="text-xs text-slate-400">—</span>} />;
  })()}
</Section>

          <Section title={<><span>Paies</span><span className="ml-2 text-xs italic text-slate-500">- Cliquez sur la carte d'une paie pour afficher ses documents de paie et sur le symbole € pour la marquer comme payée ou non payée.</span></>}>
            {paiesLoading ? (
              <div className="px-3 py-8 text-center text-slate-500">
                <Loader2 className="w-4 h-4 inline animate-spin mr-2" /> Chargement des paies…
              </div>
            ) : paiesError ? (
              <div className="px-3 py-8 text-center text-rose-600">
                Erreur lors du chargement des paies.
                {process.env.NODE_ENV !== 'production' && (
                  <div className="mt-2 text-xs text-slate-400">{(paiesErrorObj as any)?.message || 'Erreur inconnue'}</div>
                )}
              </div>
            ) : paies.length === 0 ? (
              <div className="px-3 py-8 text-center text-slate-500">
                Aucune paie trouvée.
                {process.env.NODE_ENV === 'development' && (
                  <div className="mt-2 text-xs text-slate-400 space-y-1">
                    <div>Debug: Contract ID = {id}</div>
                    <div>Debug: Contract Reference = {data?.numero || 'non définie'}</div>
                    <div className="text-yellow-600">
                      Vérifiez que le champ "Référence API" dans la table "Paies CDDU Multi-Mois" contient la valeur "{data?.numero || '???'}".
                    </div>
                  </div>
                )}
              </div>
            ) : (
              <div className="space-y-4">
                {paies
                  .slice()
                  .sort((a,b) => (b.ordre ?? 0) - (a.ordre ?? 0))
                  .map((p) => {
                    const label = payLabel(p) || (p.ordre ? `Paie ${p.ordre}` : 'Paie');
                    // Normalize aem_statut for robust checks (API can return 'OK', 'ok', 'Traité', etc.)
                    const aemNorm = String((p as any).aem_statut || '').normalize('NFD').replace(/\p{Diacritic}/gu, '').trim().toLowerCase();
                    // Vérifier d'abord "À traiter" pour éviter les faux positifs
                    const aemPending = aemNorm.includes('a_traiter') || aemNorm.includes('a traiter');
                    const aemOk = !aemPending && (aemNorm === 'ok' || aemNorm === 'oui' || aemNorm.includes('ok') || aemNorm === 'valide');

                    const CardInner = (
                      <div className="h-full rounded-2xl border bg-white p-4 hover:shadow-md transition-shadow relative">
                        {/* Bouton de paiement en position absolue */}
                        {p.traite === 'oui' && (
                          <Button
                            onClick={(e) => {
                              e.preventDefault();
                              e.stopPropagation();
                              handleTogglePayment(p.id, p.transfer_done || false);
                            }}
                            className="absolute bottom-2 right-2 bg-gradient-to-r from-indigo-200 via-purple-200 to-pink-200 text-black hover:from-indigo-300 hover:via-purple-300 hover:to-pink-300 text-xs px-2 py-1 h-auto z-10"
                            disabled={markAsPaidMutation.isPending}
                            title={p.transfer_done ? "Valider" : "Valider"}
                          >
                            <Euro className="w-3 h-3" />
                          </Button>
                        )}
                        
                        <div className="flex flex-col gap-2 sm:flex-row sm:items-start sm:gap-3">
                          <div className="flex items-center gap-2">
                            {/* Numéro de paie */}
                            <span className="text-[11px] px-2 py-0.5 rounded-full bg-indigo-100 text-indigo-800 border border-indigo-200/60">
                              # {p.ordre ?? '—'}
                            </span>
                            {/* Période (format texte) */}
                            {label && (
                              <span className="text-[11px] px-2 py-1 rounded-lg bg-gradient-to-br from-sky-50 to-blue-100 text-blue-800 border border-blue-200/70 shadow-[0_1px_0_rgba(255,255,255,0.6)]">
                                {label}
                              </span>
                            )}
                          </div>
                          <div className="sm:ml-auto flex items-center gap-2">
                            {/* 1. Traitée */}
                            {p.traite === 'non' ? (
                              <span className="inline-flex items-center gap-1 text-[11px] px-2 py-0.5 rounded-full bg-amber-100 text-amber-800">
                                <Clock className="w-3 h-3" /> À traiter
                              </span>
                            ) : p.traite === 'oui' ? (
                              <span className="inline-flex items-center gap-1 text-[11px] px-2 py-0.5 rounded-full bg-emerald-100 text-emerald-800">
                                <CheckCircle className="w-3 h-3" /> Traitée
                              </span>
                            ) : null}
                            
                            {/* 2. AEM */}
                            {aemPending ? (
                              <span className="inline-flex items-center gap-1 text-[11px] px-2 py-0.5 rounded-full bg-amber-100 text-amber-800">
                                <Clock className="w-3 h-3" /> AEM
                              </span>
                            ) : aemOk ? (
                              <span className="inline-flex items-center gap-1 text-[11px] px-2 py-0.5 rounded-full bg-emerald-100 text-emerald-800">
                                <CheckCircle className="w-3 h-3" /> AEM OK
                              </span>
                            ) : (
                              <span className="text-xs text-slate-400">AEM —</span>
                            )}
                            
                            {/* 3. Payée avec même style que les autres */}
                            {p.transfer_done ? (
                              <span className="inline-flex items-center gap-1 text-[11px] px-2 py-0.5 rounded-full bg-emerald-100 text-emerald-800">
                                <CheckCircle className="w-3 h-3" /> Payée
                              </span>
                            ) : (
                              <span className="inline-flex items-center gap-1 text-[11px] px-2 py-0.5 rounded-full bg-slate-100 text-slate-600">
                                <Clock className="w-3 h-3" /> Non payée
                              </span>
                            )}
                          </div>
                        </div>
                        <div className="mt-3 grid grid-cols-4 gap-3 text-sm">
                          <div>
                            <div className="text-slate-500">Net avant PAS</div>
                            <div className="font-medium">{formatEUR((p as any).net_avant_pas ?? p.net_avant_pas)}</div>
                          </div>
                          <div>
                            <div className="text-slate-500">Net à payer</div>
                            <div className="font-medium">{formatEUR(p.net_a_payer)}</div>
                          </div>
                          <div>
                            <div className="text-slate-500">Brut</div>
                            <div>{formatEUR(p.brut)}</div>
                          </div>
                          <div>
                            <div className="text-slate-500">Coût total</div>
                            <div>{formatEUR(p.cout_total)}</div>
                          </div>
                        </div>
                      </div>
                    );

                    // Récupérer l'URL signée depuis le map
                    const signedUrl = payslipUrlsMap.get(p.id);
                    const payslipTitle = payLabel(p) || (p.ordre ? `Paie ${p.ordre}` : 'Fiche de paie');
                    
                    return signedUrl ? (
                      <div 
                        key={p.id} 
                        onClick={() => openPayslipInModal(signedUrl, payslipTitle)}
                        className="group block cursor-pointer"
                      >
                        {CardInner}
                      </div>
                    ) : (
                      <div key={p.id} className="opacity-70 cursor-not-allowed group block" title="PDF de paie indisponible">
                        {CardInner}
                      </div>
                    );
                  })}
              </div>
            )}
          </Section>
        </div>
      </div>

      {/* Notes */}
      <NotesSection contractId={id} contractRef={data?.numero} />

      {/* Script DocuSeal */}
      <Script src="https://cdn.docuseal.com/js/form.js" strategy="lazyOnload" />

      {/* Modale d'erreur DocuSeal */}
      {showErrorModal && (
        <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
          <div className="bg-white rounded-2xl max-w-md mx-4 p-6 shadow-xl">
            <div className="flex items-center gap-3 mb-4">
              <div className="w-10 h-10 bg-red-100 rounded-full flex items-center justify-center">
                <AlertTriangle className="w-5 h-5 text-red-600" />
              </div>
              <h2 className="text-lg font-semibold text-slate-900">Signature non disponible</h2>
            </div>
            <div className="text-slate-600 mb-6">
              <p className="mb-3">Nous nous excusons pour la gêne occasionnée.</p>
              <p>La signature électronique n'est pas encore prête pour ce contrat. Nos équipes travaillent activement sur la préparation des documents.</p>
            </div>
            <div className="flex gap-3">
              <Button 
                variant="outline" 
                onClick={() => setShowErrorModal(false)}
                className="flex-1"
              >
                Fermer
              </Button>
              <Button 
                onClick={() => {
                  window.location.href = '/support';
                }}
                className="flex-1 bg-gradient-to-r from-indigo-200 via-purple-200 to-pink-200 text-black hover:from-indigo-300 hover:via-purple-300 hover:to-pink-300"
              >
                Nous contacter
              </Button>
            </div>
          </div>
        </div>
      )}

      {/* Modale de signature DocuSeal */}
      <dialog id="dlg-signature" className="rounded-lg border max-w-5xl w-[96vw] p-0">
        <div className="sticky top-0 z-10 flex items-center justify-between px-4 py-3 border-b bg-white">
          <strong>{modalTitle || 'Signature électronique'}</strong>
          <button
            onClick={() => {
              const dlg = document.getElementById('dlg-signature') as HTMLDialogElement | null;
              if (dlg) dlg.close();
            }}
            className="p-1.5 rounded hover:bg-slate-50"
            aria-label="Fermer"
            title="Fermer"
          >
            <XCircle className="w-4 h-4" aria-hidden="true" />
          </button>
        </div>
        <div className="p-0" style={{ height: '80vh', minHeight: 520, overflowY: 'auto' }}>
          {embedSrc ? (
            <div dangerouslySetInnerHTML={{
              __html: (() => {
                console.log('🎨 [SIGNATURE RENDER] Génération du HTML docuseal-form');
                console.log('🎨 [SIGNATURE RENDER] embedSrc:', embedSrc);
                
                // Utiliser la signature depuis l'etat React au lieu de sessionStorage
                const signatureB64 = signatureB64ForDocuSeal;
                
                console.log('🎨 [SIGNATURE RENDER] Signature depuis l\'etat React:', {
                  exists: !!signatureB64,
                  length: signatureB64?.length,
                  preview: signatureB64?.substring(0, 50)
                });
                
                const signatureAttr = signatureB64 ? `data-signature="${signatureB64.replace(/"/g, '&quot;')}"` : '';
                
                console.log('🎨 [SIGNATURE RENDER] signatureAttr généré:', {
                  hasAttr: !!signatureAttr,
                  attrLength: signatureAttr.length,
                  attrPreview: signatureAttr.substring(0, 100)
                });
                
                const html = `<docuseal-form
                data-src="${embedSrc}"
                data-language="fr"
                data-with-title="false"
                data-background-color="#fff"
                data-allow-typed-signature="false"
                ${signatureAttr}>
              </docuseal-form>`;
              
                console.log('🎨 [SIGNATURE RENDER] HTML final généré');
                console.log('🎨 [SIGNATURE RENDER] HTML length:', html.length);
                console.log('🎨 [SIGNATURE RENDER] HTML contient data-signature:', html.includes('data-signature='));
                
                return html;
              })()
            }} />
          ) : (
            <div className="p-4 text-slate-500">Préparation du formulaire…</div>
          )}
        </div>
      </dialog>

      {/* Modale de chargement */}
      <LoadingModal
        isOpen={isLoadingSignature}
        title="Préparation de la signature"
        description="Chargement de l'interface de signature électronique..."
        onClose={() => setIsLoadingSignature(false)}
      />

      {/* Modale de confirmation de paiement */}
      <ConfirmationModal
        isOpen={showPaymentModal}
        title={selectedPaieStatus ? "Confirmer le paiement" : "Confirmer l'annulation"}
        description={
          selectedPaieStatus 
            ? "Êtes-vous sûr de vouloir marquer cette paie comme payée ? Cette action mettra à jour le statut de paiement dans le système."
            : "Êtes-vous sûr de vouloir marquer cette paie comme non payée ? Cette action annulera le statut de paiement dans le système."
        }
        confirmText={selectedPaieStatus ? "Valider" : "Valider"}
        cancelText="Annuler"
        onConfirm={confirmTogglePayment}
        onCancel={() => {
          setShowPaymentModal(false);
          setSelectedPaieId("");
          setSelectedPaieStatus(false);
        }}
        confirmButtonVariant="gradient"
        isLoading={markAsPaidMutation.isPending}
      />

      {/* Modale de visualisation des fiches de paie */}
      {isPayslipModalOpen && (
        <div 
          className="fixed inset-0 z-[9999] flex items-center justify-center p-4 bg-black/50"
          onClick={() => setIsPayslipModalOpen(false)}
        >
          <div 
            className="relative w-full max-w-6xl h-[90vh] bg-white rounded-2xl shadow-2xl flex flex-col"
            onClick={(e) => e.stopPropagation()}
          >
            {/* Header sticky */}
            <div className="sticky top-0 z-10 flex items-center justify-between px-6 py-4 bg-white border-b rounded-t-2xl">
              <h2 className="text-lg font-semibold text-slate-800 flex items-center gap-2">
                {currentPayslipTitle}
                {data?.numero && (
                  <>
                    <span className="text-slate-400">•</span>
                    <span className="text-sm font-normal text-slate-500">
                      Contrat {data.numero}
                    </span>
                  </>
                )}
              </h2>
              <div className="flex items-center gap-2">
                <Button
                  onClick={() => window.open(currentPayslipUrl, '_blank')}
                  variant="outline"
                  size="sm"
                  className="gap-2"
                >
                  <ExternalLink className="w-4 h-4" />
                  Ouvrir dans un nouvel onglet
                </Button>
                <Button
                  onClick={() => {
                    const link = document.createElement('a');
                    link.href = currentPayslipUrl;
                    link.download = `${currentPayslipTitle.replace(/\s+/g, '_')}.pdf`;
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                  }}
                  variant="outline"
                  size="sm"
                  className="gap-2"
                >
                  <Download className="w-4 h-4" />
                  Télécharger
                </Button>
                <Button
                  onClick={() => setIsPayslipModalOpen(false)}
                  variant="ghost"
                  size="sm"
                  className="gap-2"
                >
                  <X className="w-4 h-4" />
                </Button>
              </div>
            </div>

            {/* Content area */}
            <div className="flex-1 overflow-hidden">
              {payslipPdfError ? (
                <div className="flex flex-col items-center justify-center h-full text-slate-500 gap-4">
                  <AlertCircle className="w-16 h-16 text-slate-400" />
                  <p>Impossible de charger le PDF</p>
                  <Button
                    onClick={() => window.open(currentPayslipUrl, '_blank')}
                    variant="outline"
                    size="sm"
                    className="gap-2"
                  >
                    <ExternalLink className="w-4 h-4" />
                    Ouvrir dans un nouvel onglet
                  </Button>
                </div>
              ) : (
                <iframe
                  src={currentPayslipUrl}
                  className="w-full h-full border-0"
                  title={currentPayslipTitle}
                  onError={() => setPayslipPdfError(true)}
                />
              )}
            </div>
          </div>
        </div>
      )}

    </div>
  );
}
