"use client";

// ---------- Currency helpers ----------
const fmtEUR = new Intl.NumberFormat("fr-FR", { style: "currency", currency: "EUR", minimumFractionDigits: 2, maximumFractionDigits: 2 });
function formatEUR(value?: string | number | null): string | undefined {
  if (value === null || value === undefined) return undefined;
  if (typeof value === "number" && Number.isFinite(value)) return fmtEUR.format(value);
  if (typeof value === "string") {
    // Nettoyage: garde chiffres/.,, et signe ; remplace virgule par point pour le parse
    const raw = value.trim();
    // Si la chaîne contient déjà un € et semble formatée, on tente d'en extraire un nombre
    const cleaned = raw.replace(/[^0-9,.-]/g, "").replace(/,(?=\d{1,2}$)/, ".");
    const num = parseFloat(cleaned.replace(/,/g, "."));
    if (!Number.isNaN(num)) return fmtEUR.format(num);
    // Sinon, on renvoie tel quel
    return raw;
  }
  return undefined;
}

import Link from "next/link";
import Script from "next/script";
import { usePageTitle } from "@/hooks/usePageTitle";
// ---------- Hook récupération fiches de paie Supabase ----------
// ...existing code...

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

// Hook usePayslips pour la page DEMO - retourne TOUJOURS les données de démo
function usePayslips(contractId: string) {
  console.log('🎭 [DEMO PAGE] usePayslips - Retour des données de démo');
  
  const DEMO_PAYSLIPS: Payslip[] = [
    {
      id: "demo-payslip-001",
      contract_id: "demo-cont-001",
      period_start: "2024-01-15",
      period_end: "2024-06-30",
      period_month: "2024-06",
      pay_number: 1,
      gross_amount: "850.00",
      net_amount: "623.45",
      net_after_withholding: "623.45",
      employer_cost: "1247.50",
      pay_date: "2024-07-15",
      processed: true,
      aem_status: "valide",
      transfer_done: true,
      analytic_tag: "SPECTACLE-2024",
      storage_path: "/demo/payslips/demo-payslip-001.pdf",
      source_reference: "DEMO-PAY-001",
      created_at: "2024-07-01T10:00:00Z"
    }
  ];
  
  return {
    data: DEMO_PAYSLIPS,
    isLoading: false,
    error: null,
    isError: false,
    isFetching: false
  };
  
  // Pas d'appel API : cette page est TOUJOURS en mode démo
}
import { useParams, useRouter } from "next/navigation";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { api } from "@/lib/fetcher";
import { Loader2, ArrowLeft, Check, Pencil, Download, Info, AlertTriangle, CheckCircle, Clock, Copy, PenTool, XCircle, Users, Send, FileText, CreditCard, Shield, Calendar, StickyNote, Euro } from "lucide-react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { LoadingModal } from "@/components/ui/loading-modal";
import { ConfirmationModal } from "@/components/ui/confirmation-modal";
import { useMemo, useState, useEffect } from "react";
import { toast } from "sonner";

// ---------- Types ----------
type StatutSimple = "oui" | "non" | "na" | "en_attente";
type EtatDemande = "Pré-demande" | "Reçue" | "Traitée" | "signe" | "modification" | "non_commence";

// Types pour la timeline
type TimelineStepStatus = "completed" | "current" | "upcoming";
type TimelineStep = {
  id: string;
  label: string;
  status: TimelineStepStatus;
};

// Fonction pour déterminer l'état de chaque étape de la timeline
function getTimelineSteps(etat_demande: EtatDemande, contrat_signe_salarie: StatutSimple, payslips?: any[]): TimelineStep[] {
  const steps: TimelineStep[] = [];

  // Étape 1: Réception/Pré-demande
  if (etat_demande === "Pré-demande") {
    steps.push({ id: "reception", label: "Pré-demande", status: "upcoming" });
  } else {
    steps.push({ id: "reception", label: "Reçu", status: "completed" });
  }

  // Étape 2: Préparation/Envoi du contrat
  if (etat_demande === "Pré-demande") {
    steps.push({ id: "envoi", label: "Envoi du contrat", status: "upcoming" });
  } else if (etat_demande === "Reçue") {
    steps.push({ id: "envoi", label: "Préparation du contrat", status: "current" });
  } else if (etat_demande === "Traitée") {
    steps.push({ id: "envoi", label: "Envoyé", status: "completed" });
  } else {
    // Pour les autres états (signe, modification, non_commence)
    steps.push({ id: "envoi", label: "Envoyé", status: "completed" });
  }

  // Étape 3: Signature du contrat
  const step3Completed = contrat_signe_salarie === "oui";
  if (etat_demande === "Pré-demande" || etat_demande === "Reçue") {
    steps.push({ id: "signature", label: "Signature du contrat", status: "upcoming" });
  } else if (etat_demande === "Traitée" && contrat_signe_salarie === "non") {
    steps.push({ id: "signature", label: "Signature en cours", status: "current" });
  } else if (step3Completed) {
    steps.push({ id: "signature", label: "Signé", status: "completed" });
  } else {
    // État de fallback
    steps.push({ id: "signature", label: "Signature du contrat", status: "upcoming" });
  }

  // Étape 4: Traitement de la paie
  // Récupérer la première paie (il ne peut y en avoir qu'une selon la spécification)
  const firstPayslip = payslips && payslips.length > 0 ? payslips[0] : null;
  const step4Completed = firstPayslip && firstPayslip.processed === true;
  
  if (!step3Completed) {
    // Si l'étape 3 n'est pas validée, mettre en gris
    steps.push({ id: "paie", label: "Traitement de la paie", status: "upcoming" });
  } else if (firstPayslip) {
    // Si on a une paie
    if (step4Completed) {
      steps.push({ id: "paie", label: "Paie traitée", status: "completed" });
    } else {
      steps.push({ id: "paie", label: "Paie en cours de traitement", status: "current" });
    }
  } else {
    // Pas de paie encore créée mais étape 3 validée
    steps.push({ id: "paie", label: "Traitement de la paie", status: "current" });
  }

  // Étape 5: Paiement du salaire
  if (!step4Completed) {
    // Si l'étape 4 n'est pas validée, mettre en gris
    steps.push({ id: "paiement", label: "Paiement du salaire", status: "upcoming" });
  } else if (firstPayslip) {
    // Si on a une paie traitée
    if (firstPayslip.transfer_done === true) {
      steps.push({ id: "paiement", label: "Salaire versé", status: "completed" });
    } else {
      steps.push({ id: "paiement", label: "Salaire à verser", status: "current" });
    }
  } else {
    // Cas de fallback (ne devrait pas arriver si step4Completed est true)
    steps.push({ id: "paiement", label: "Paiement du salaire", status: "upcoming" });
  }

  return steps;
}

type ContratDetail = {
  id: string;
  numero: string;                 // ex: "YW2KSC85"
  regime: "CDDU_MONO";            // cette page cible ce cas
  salarie: { nom: string; email?: string };
  salarie_matricule?: string;     // Matricule API du salarié pour lien fiche
  production: string;             // Spectacle / Prod
  objet?: string;                 // Numéro d'objet
  profession: string;             // code + libellé
  categorie_prof?: string;
  type_salaire?: string;          // Brut / Net etc.
  salaire_demande?: string;       // "622,40€"
  date_debut: string;             // ISO
  date_fin: string;               // ISO
  panier_repas?: StatutSimple;

  // Paie & pdf
  pdf_contrat?: { available: boolean; url?: string };
  pdf_avenant?: { available: boolean; url?: string }; // souvent n/a mono-mois
  pdf_paie?: { available: boolean; url?: string };    // Paie, AEM, Congés Spectacles (bundle ou séparés)
  etat_traitement?: "a_traiter" | "en_cours" | "termine";
  virement_effectue?: boolean | string; // Peut arriver en "Oui"/"Non" depuis l'API
  salaire_net_avant_pas?: string; // "Bientôt disponible" sinon
  net_a_payer_rib?: string;
  salaire_brut?: string;
  cout_employeur?: string;
  precisions_salaire?: string;

  // Signatures & contrat
  etat_demande: EtatDemande;      // "Reçue", etc.
  contrat_signe_employeur: StatutSimple;
  contrat_signe_salarie: StatutSimple;
  etat_contrat?: "non_commence" | "en_cours" | "termine";

  // Déclarations
  dpae?: "À traiter" | "OK";
  aem?: "À traiter" | "OK";

  // Temps de travail réel
  jours_travailles?: number;
  nb_representations?: number;
  nb_services_repetitions?: number;
  nb_heures_repetitions?: number;
  nb_heures_annexes?: number;
  nb_cachets_aem?: number;
  nb_heures_aem?: number;

  // Métadonnées
  created_at?: string;
  updated_at?: string;
};

// ---------- Data hooks pour la page DEMO ----------
// Ces hooks retournent TOUJOURS les données de démo, sans appeler les API
function useContratDetail(id: string) {
  console.log('🎭 [DEMO PAGE] useContratDetail - Retour des données de démo');
  
  const DEMO_CONTRACT_DETAIL: ContratDetail = {
    id: "demo-cont-001",
    numero: "DEMO-2024-001",
    regime: "CDDU_MONO",
    salarie: { 
      nom: "MARTIN Alice", 
      email: "alice.martin@demo.fr" 
    },
    salarie_matricule: "demo-sal-001",
    production: "Les Misérables - Tournée 2024",
    objet: "PROD-2024-15",
    profession: "04201 - Comédien",
    categorie_prof: "Artiste interprète",
    type_salaire: "Forfait cachet",
    salaire_demande: "850,00€",
    date_debut: "2024-01-15",
    date_fin: "2024-06-30",
    panier_repas: "oui",
    
    // PDFs et documents
    pdf_contrat: { available: true, url: "/demo/contrat-demo.pdf" },
    pdf_avenant: { available: false },
    pdf_paie: { available: true, url: "/demo/paie-demo.pdf" },
    
    // États et statuts
    etat_traitement: "termine",
    virement_effectue: true,
    salaire_net_avant_pas: "623,45€",
    net_a_payer_rib: "623,45€",
    salaire_brut: "850,00€",
    cout_employeur: "1.247,50€",
    precisions_salaire: "Contrat démo - Tarif spectacle vivant",
    
    // Signatures et contrat
    etat_demande: "Traitée",
    contrat_signe_employeur: "oui",
    contrat_signe_salarie: "oui",
    etat_contrat: "termine",
    
    // Déclarations
    dpae: "OK",
    aem: "OK",
    
    // Temps de travail
    jours_travailles: 25,
    nb_representations: 18,
    nb_services_repetitions: 12,
    nb_heures_repetitions: 48,
    nb_heures_annexes: 8,
    nb_cachets_aem: 18,
    nb_heures_aem: 0,
    
    // Métadonnées
    created_at: "2024-01-10T09:00:00Z",
    updated_at: "2024-07-01T16:30:00Z"
  };
  
  return {
    data: DEMO_CONTRACT_DETAIL,
    isLoading: false,
    error: null,
    isError: false,
    isFetching: false
  };
  
  // Pas de mode normal : cette page est TOUJOURS en mode démo
}

// ---------- UI helpers ----------
function Section({ title, icon: Icon, children }: { title: string; icon?: React.ElementType; children: React.ReactNode }) {
  return (
    <Card className="rounded-3xl overflow-hidden">
      <CardHeader className="bg-slate-50/60 border-b">
        <CardTitle className="flex items-center gap-3">
          {Icon && <Icon className="size-5 text-slate-600" />}
          <span className="text-lg font-semibold">{title}</span>
        </CardTitle>
      </CardHeader>
      <CardContent className="p-6">
        {children}
      </CardContent>
    </Card>
  );
}

function Field({ label, value, hint, action }: { label: string; value?: React.ReactNode; hint?: string; 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> : hint ? <div className="text-xs text-slate-400">{hint}</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) {
  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 | string) {
  const input = String(s || "").trim();
  const normalized = input
    .toLowerCase()
    .normalize("NFD")
    .replace(/\p{Diacritic}/gu, "")
    .replace(/\s+/g, " ");

  // Mapping des 5 états officiels -> style mini-card harmonisé
  // Couleurs:
  // - Reçue: bleu
  // - Pré-demande: gris
  // - En cours de traitement: ambre
  // - Traitée: vert
  // - En cours d'envoi: indigo
  type Style = { bg: string; border: string; text: string; label: string };
  const styles: Record<string, Style> = {
    "Reçue": { bg: "bg-sky-50", border: "border-sky-200", text: "text-sky-800", label: "Reçue" },
    "Pré-demande": { bg: "bg-slate-50", border: "border-slate-200", text: "text-slate-700", label: "Pré-demande" },
    "En cours de traitement": { bg: "bg-amber-50", border: "border-amber-200", text: "text-amber-800", label: "En cours de traitement" },
    "Traitée": { bg: "bg-emerald-50", border: "border-emerald-200", text: "text-emerald-800", label: "Traitée" },
    "En cours d'envoi": { bg: "bg-indigo-50", border: "border-indigo-200", text: "text-indigo-800", label: "En cours d'envoi" },
  };

  // Normalisations alternatives depuis l'API
  const alt = normalized
    .replace(/-/g, " ")
    .replace(/_/g, " ");

  const style =
    styles[normalized] ||
    styles[alt] ||
    // fallback générique
    { 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 formatDateFR(iso?: string) {
  if (!iso) return "—";
  const d = new Date(iso);
  return d.toLocaleDateString("fr-FR", { day: "2-digit", month: "2-digit", year: "numeric" });
}

// ---------- Composant d'erreur d'accès ----------
function AccessDeniedError({ contractId }: { contractId: string }) {
  return (
    <div className="rounded-2xl border bg-white p-8">
      <div className="flex flex-col items-center text-center max-w-md mx-auto space-y-4">
        <div className="w-16 h-16 rounded-full bg-rose-100 flex items-center justify-center">
          <AlertTriangle className="w-8 h-8 text-rose-600" />
        </div>
        
        <div>
          <h2 className="text-lg font-semibold text-slate-900 mb-2">
            Accès non autorisé
          </h2>
          <p className="text-sm text-slate-600 leading-relaxed">
            Vous n'avez pas l'autorisation de consulter ce contrat. Il est possible qu'il appartienne à une autre organisation ou qu'il n'existe pas.
          </p>
        </div>

        <div className="text-xs text-slate-500 bg-slate-50 px-3 py-2 rounded-lg font-mono">
          ID: {contractId}
        </div>

        <Link 
          href="/contrats" 
          className="inline-flex items-center gap-2 px-4 py-2 bg-slate-900 text-white rounded-lg text-sm font-medium hover:bg-slate-800 transition-colors"
        >
          <ArrowLeft className="w-4 h-4" /> 
          Retour aux contrats
        </Link>
      </div>
    </div>
  );
}

// ---------- Page ----------
export default function ContratDemoPage() {
  // 🎭 TOUJOURS utiliser l'ID de démo
  const id = 'demo-cont-001';
  const router = useRouter();

  const { data, isLoading, isError, error } = useContratDetail(id);
  
  // Définir le titre basé sur les données du contrat
  const contractTitle = data?.numero 
    ? `Contrat ${data.numero}` 
    : `Contrat CDDU`;
  usePageTitle(contractTitle);
  
  const payslipsQuery = usePayslips(id);
  const [signedPayslipUrls, setSignedPayslipUrls] = useState<Record<string, string>>({});

  // State pour la modale de signature DocuSeal
  const [embedSrc, setEmbedSrc] = useState<string>("");
  const [modalTitle, setModalTitle] = useState<string>("");
  const [signatureB64ForDocuSeal, setSignatureB64ForDocuSeal] = useState<string | null>(null); // Signature pour pré-remplissage
  
  // 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 confirmation de paiement
  const [showPaymentModal, setShowPaymentModal] = useState<boolean>(false);
  const [selectedPayslipId, setSelectedPayslipId] = useState<string>("");
  const [selectedPayslipStatus, setSelectedPayslipStatus] = 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]);

  // Mutation pour marquer une paie 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 payslips
      queryClient.invalidateQueries({ queryKey: ["payslips", id] });
      toast.success(variables.transferDone ? "Paiement marqué comme effectué !" : "Paiement marqué comme non effectué !");
      setShowPaymentModal(false);
      setSelectedPayslipId("");
      setSelectedPayslipStatus(false);
    },
    onError: (error: Error) => {
      toast.error("Erreur : " + error.message);
    },
  });

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

  // Fonction pour confirmer le changement de statut
  const confirmTogglePayment = () => {
    // 🎭 En mode démo, afficher un message au lieu d'appeler l'API
    toast.info("Fonctionnalité désactivée en mode démonstration", {
      description: "Les modifications de paiement ne sont pas possibles sur les données de démo"
    });
    setShowPaymentModal(false);
    setSelectedPayslipId("");
    setSelectedPayslipStatus(false);
    return;
    
    // Le code suivant n'est jamais exécuté en mode démo
    if (selectedPayslipId) {
      markAsPaidMutation.mutate({ 
        payslipId: selectedPayslipId, 
        transferDone: selectedPayslipStatus 
      });
    }
  };

  // Fonction pour ouvrir la signature DocuSeal
  async function openSignature() {
    // 🎭 En mode démo, afficher un message au lieu d'appeler l'API
    toast.info("Fonctionnalité de signature désactivée en mode démonstration", {
      description: "Cette fonctionnalité n'est disponible qu'avec de vrais contrats"
    });
    return;
    
    // Le code suivant n'est jamais exécuté en mode démo
    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 as string);
        
        // 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 as HTMLDialogElement).showModal === 'function') {
            (dlg as HTMLDialogElement).showModal();
          } else {
            (dlg as HTMLDialogElement).setAttribute('open', '');
          }
        }
      } else {
        console.warn('❌ [SIGNATURE] Aucune URL d\'embed trouvée');
        setIsLoadingSignature(false);
        toast.error("Signature électronique non disponible pour ce contrat");
      }
    } catch (error) {
      console.error('❌ [SIGNATURE] Erreur:', error);
      setIsLoadingSignature(false);
      toast.error("Erreur lors de l'ouverture de la signature électronique");
    }
  }

  // 🎭 DÉSACTIVÉ en mode démo : pas de fetchSignedUrls car les fichiers n'existent pas dans S3
  // useEffect(() => {
  //   async function fetchSignedUrls() {
  //     if (payslipsQuery.data) {
  //       const urls: Record<string, string> = {};
  //       for (const slip of payslipsQuery.data) {
  //         if (slip.storage_path) {
  //           try {
  //             const res = await fetch("/api/payslips/presign", {
  //               method: "POST",
  //               headers: { "Content-Type": "application/json" },
  //               body: JSON.stringify({ storage_path: slip.storage_path, expiresInSeconds: 3600 })
  //             });
  //             const json = await res.json();
  //             urls[slip.id] = json.url || "";
  //             console.log("Presigned URL API pour", slip.id, ":", json.url);
  //           } catch (err) {
  //             urls[slip.id] = "";
  //             console.warn("Erreur API presign pour", slip.id, err);
  //           }
  //         } else {
  //           console.warn("Pas de storage_path pour la paie", slip.id);
  //         }
  //       }
  //       setSignedPayslipUrls(urls);
  //     }
  //   }
  //   fetchSignedUrls();
  // }, [payslipsQuery.data]);

  // Redirection de sécurité côté client
  useEffect(() => {
    // Si l'utilisateur essaie d'accéder à un ID suspect, on peut ajouter des vérifications
    if (id && !/^[a-zA-Z0-9\-_]{1,50}$/.test(id)) {
      console.warn("Suspicious contract ID format:", id);
      router.push("/contrats");
    }
  }, [id, router]);

  const title = useMemo(() => (data ? `Contrat n° ${data.numero}` : "Contrat"), [data]);
  
  // virementOn: déduire un booléen de la valeur potentiellement "Oui"/"Non"/boolean
  const virementOn = useMemo(() => {
    const v = data?.virement_effectue;
    if (typeof v === "boolean") return v;
    const s = String(v || "").trim().toLowerCase();
    return s === "oui" || s === "true" || s === "1";
  }, [data?.virement_effectue]);
  
  // Calcule l'état du contrat en fonction des dates et de l'état de la demande
  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;
    }

    // Calcul basé sur les dates
    if (!data.date_debut || !data.date_fin) return undefined;

    function toLocalDateOnly(isoString: string) {
      const date = new Date(isoString);
      const year = date.getFullYear();
      const month = String(date.getMonth() + 1).padStart(2, '0');
      const day = String(date.getDate()).padStart(2, '0');
      return `${year}-${month}-${day}`;
    }

    const today = toLocalDateOnly(new Date().toISOString());
    const start = toLocalDateOnly(data.date_debut);
    const end = toLocalDateOnly(data.date_fin);

    if (today < start) return "Non commencé" as const;
    if (today > end) return "Terminé" as const;
    return "En cours" as const;
  }, [data]);

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

  // Gestion spécifique des erreurs d'accès
  if (isError) {
    const errorMessage = (error as any)?.message || "";
    
    if (errorMessage === "access_denied") {
      return <AccessDeniedError contractId={id} />;
    }
    
    if (errorMessage === "not_found") {
      return (
        <div className="rounded-2xl border bg-white p-6">
          <div className="text-amber-600 font-medium mb-2">Contrat introuvable</div>
          <div className="text-sm text-slate-500">Le contrat demandé n'existe pas ou a été supprimé.</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>
      );
    }

    // Erreur générique
    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">{errorMessage || "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>
    );
  }

  if (!data) {
    return <AccessDeniedError contractId={id} />;
  }

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

return (
  <div className="space-y-5">
    {/* Barre titre + actions */}
    <div className="flex flex-col md:flex-row md:items-center gap-3">
      <div className="flex 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 en cours
        </Link>
      </div>
      <div className="md:ml-auto flex items-center gap-2">

<button
  type="button"
  onClick={() => {
    // Construire le payload de duplication avec vérifications améliorées
    const professionCode = (() => {
      const candidates = [
        (data as any).profession_code,
        (data as any).codeprofession,
        (data as any).code_profession,
        (data as any).codeemploi,
      ];
      for (const raw of candidates) {
        if (typeof raw === "string" && raw.trim()) return raw.trim();
      }
      const match = /([A-Z]{3}\d{3})/.exec((data.profession || "").toString());
      return match ? match[1] : "";
    })();

    const payload: any = {
      // Production : utiliser production (nom de la production)
      spectacle: data.production || "",
      numero_objet: data.objet || null,
      
      // Salarié : améliorer la récupération des informations
      salarie: data.salarie_matricule || data.salarie ? {
        matricule: data.salarie_matricule || "",
        nom: data.salarie?.nom || data.salarie_matricule || "",
        email: data.salarie?.email || null,
      } : null,
      
      // Catégorie professionnelle : améliorer la logique de détection
      categorie: (() => {
        // Récupérer la catégorie depuis différentes sources possibles
        const catSource = (
          data.categorie_prof || 
          ""
        ).toString().toLowerCase();
        
        // Logique de détection améliorée
        if (catSource.includes("tech") || catSource.includes("technicien")) {
          return "Technicien";
        } else if (catSource.includes("artiste") || catSource.includes("artist")) {
          return "Artiste";
        } else {
          // Fallback : essayer de déduire depuis la profession
          const professionStr = (data.profession || "").toString().toLowerCase();
          if (professionStr.includes("tech") || professionStr.includes("ingé") || professionStr.includes("régiss")) {
            return "Technicien";
          }
          // Par défaut : Artiste (plus fréquent)
          return "Artiste";
        }
      })(),
      
      // Profession : améliorer l'extraction
      profession: {
        label: data.profession || "",
        code: professionCode,
      },
      
      // Dates
      date_debut: data.date_debut || "",
      date_fin: data.date_fin || "",
      
      // Représentations et services
      nb_representations: typeof data.nb_representations === 'number' ? data.nb_representations : "",
      nb_services_repetition: typeof data.nb_services_repetitions === 'number' ? data.nb_services_repetitions : "",
      
      // Heures : logique améliorée
      heures_total: (() => {
        // Essayer plusieurs sources d'heures
        const sources = [
          data.nb_heures_aem,
          (Number(data.nb_heures_repetitions || 0) + Number(data.nb_heures_annexes || 0))
        ];
        
        for (const source of sources) {
          const num = Number(source);
          if (Number.isFinite(num) && num > 0) return num;
        }
        
        return "";
      })(),
      minutes_total: "0", // Par défaut 0 minutes
      
      // Jours de travail
      jours_travail: (() => {
        if (typeof data.jours_travailles === "number" && data.jours_travailles > 0) {
          return String(data.jours_travailles);
        }
        return "";
      })(),
      
      // Type de salaire : normaliser les valeurs
      type_salaire: (() => {
        const typeStr = (data.type_salaire || "").toString().toLowerCase();
        const validTypes = ["Brut", "Net avant PAS", "Coût total employeur", "Minimum conventionnel"];
        
        // Recherche par correspondance partielle
        for (const validType of validTypes) {
          if (typeStr.includes(validType.toLowerCase()) || 
              validType.toLowerCase().includes(typeStr)) {
            return validType;
          }
        }
        
        // Fallbacks spécifiques
        if (typeStr.includes("brut")) return "Brut";
        if (typeStr.includes("net") && typeStr.includes("pas")) return "Net avant PAS";
        if (typeStr.includes("coût") || typeStr.includes("cout") || typeStr.includes("total")) return "Coût total employeur";
        if (typeStr.includes("minimum") || typeStr.includes("conventionnel")) return "Minimum conventionnel";
        
        return "Brut"; // Par défaut
      })(),
      
      // Montant : améliorer l'extraction numérique
      montant: (() => {
        const sources = [data.salaire_demande];
        
        for (const source of sources) {
          if (!source) continue;
          
          const raw = source.toString();
          // Nettoyer : garder seulement chiffres, points, virgules et signes moins
          const cleaned = raw.replace(/[^0-9,.-]/g, '');
          // Remplacer la dernière virgule par un point (format décimal français)
          const normalized = cleaned.replace(/,(?=\d{1,2}$)/, '.');
          // Puis remplacer les autres virgules par rien (séparateurs de milliers)
          const finalClean = normalized.replace(/,/g, '.');
          
          const num = parseFloat(finalClean);
          if (Number.isFinite(num) && num > 0) return num;
        }
        
        return "";
      })(),
      
      // Panier repas : normaliser
      panier_repas: (() => {
        const val = (data.panier_repas || "").toString().toLowerCase();
        if (val === 'oui' || val === 'true' || val === '1') return 'Oui';
        if (val === 'non' || val === 'false' || val === '0') return 'Non';
        return 'Non'; // Par défaut
      })(),
      
      notes: "", // Vide pour une nouvelle demande
      multi_mois: false, // Par défaut mono-mois
    };

    // Encoder en base64 et rediriger
    const json = JSON.stringify(payload);
    let b64 = "";
    try {
      b64 = btoa(json);
    } catch {
      // Fallback Node.js
      b64 = Buffer.from(json, 'utf8').toString('base64');
    }
    
    router.push(`/contrats/nouveau?dupe=${encodeURIComponent(b64)}`);
  }}
  className="inline-flex items-center gap-2 px-3 py-2 rounded-lg border opacity-60 cursor-not-allowed"
  title="Fonctionnalité désactivée en mode démo"
  disabled
>
  <Copy className="w-4 h-4" />
  Dupliquer
</button>

        <button 
          disabled
          className="inline-flex items-center gap-2 px-3 py-2 rounded-lg border opacity-60 cursor-not-allowed"
          title="Fonctionnalité désactivée en mode démo"
        >
          <Pencil className="w-4 h-4" /> Modifier
        </button>
        <button className="inline-flex items-center gap-2 px-3 py-2 rounded-lg border opacity-60 cursor-not-allowed" title="À définir">
          <Check className="w-4 h-4" /> Valider
        </button>
      </div>
    </div>

    <div className="rounded-2xl border bg-white p-6">
      <div className="grid grid-cols-1 lg:grid-cols-4 gap-6 items-center">
        {/* Titre du contrat - 1 colonne */}
        <div className="lg:col-span-1">
          <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</div>
          </div>
        </div>

        {/* Timeline - 3 colonnes */}
        <div className="lg:col-span-3">
          <div className="flex items-center justify-between relative">
            {/* Ligne de progression */}
            <div className="absolute top-1/2 left-0 right-0 h-0.5 bg-slate-200 -translate-y-1/2 z-0"></div>
            {(() => {
              const steps = getTimelineSteps(data.etat_demande, data.contrat_signe_salarie, payslipsQuery.data);
              const completedSteps = steps.filter(s => s.status === "completed").length;
              const progressPercentage = Math.max(0, Math.min(100, (completedSteps / steps.length) * 100));
              
              return (
                <div 
                  className="absolute top-1/2 left-0 h-0.5 bg-blue-500 -translate-y-1/2 z-0" 
                  style={{ width: `${progressPercentage}%` }}
                ></div>
              );
            })()}
            
            {/* Étapes */}
            <div className="flex items-center justify-between w-full relative z-10">
              {getTimelineSteps(data.etat_demande, data.contrat_signe_salarie, payslipsQuery.data).map((step, index) => (
                <div key={step.id} className="flex flex-col items-center bg-white px-2">
                  <div className={`w-8 h-8 rounded-full flex items-center justify-center mb-2 ${
                    step.status === "completed" 
                      ? "bg-green-500" 
                      : step.status === "current" 
                        ? "bg-blue-500" 
                        : "bg-slate-300"
                  }`}>
                    {step.status === "completed" ? (
                      <Check className="w-4 h-4 text-white" />
                    ) : step.status === "current" ? (
                      <Clock className="w-4 h-4 text-white" />
                    ) : (
                      <Clock className="w-4 h-4 text-slate-500" />
                    )}
                  </div>
                  <div className={`text-xs font-medium text-center ${
                    step.status === "upcoming" 
                      ? "text-slate-500" 
                      : "text-slate-700"
                  }`}>
                    {step.label}
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </div>

    {/* Grille 2 colonnes */}
    <div className="flex flex-col md:grid md:grid-cols-2 gap-5 md:items-start">
      {/* Left column: Documents, Demande - ordre 1 sur mobile */}
      <div className="space-y-5 order-1">
        {/* Card Documents - Version démo simplifiée */}
        <Card className="rounded-3xl overflow-hidden">
          <CardHeader className="bg-slate-50/60 border-b">
            <CardTitle className="flex items-center gap-3">
              <FileText className="size-5 text-slate-600" />
              <span className="text-lg font-semibold">Documents</span>
            </CardTitle>
          </CardHeader>
          <CardContent className="p-6">
            <div className="space-y-3">
              {/* Contrat CDDU */}
              <div className="flex items-center justify-between p-3 rounded-lg border bg-slate-50">
                <div className="flex items-center gap-3">
                  <FileText className="w-5 h-5 text-slate-600" />
                  <div>
                    <div className="font-medium text-sm">Contrat CDDU fictif</div>
                    <div className="text-xs text-slate-500">Document de démonstration</div>
                  </div>
                </div>
                <button
                  disabled
                  className="px-3 py-1.5 rounded-lg text-sm bg-slate-200 text-slate-400 cursor-not-allowed"
                  title="Fonctionnalité désactivée en mode démo"
                >
                  Visualiser
                </button>
              </div>
              
              {/* Message informatif */}
              <div className="p-3 rounded-lg bg-blue-50 border border-blue-200">
                <div className="flex items-start gap-2">
                  <Info className="w-4 h-4 text-blue-600 mt-0.5 flex-shrink-0" />
                  <div className="text-xs text-blue-800">
                    <strong>Mode démonstration :</strong> Les documents ne sont pas disponibles au téléchargement. 
                    Cette fonctionnalité est active uniquement avec de vrais contrats.
                  </div>
                </div>
              </div>
            </div>
          </CardContent>
        </Card>

        <Section title="Demande" icon={FileText}>
          <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="Avenant contrat PDF"
            value={
              data.pdf_avenant?.available ? (
                <a className="inline-flex items-center gap-2 underline" href={data.pdf_avenant.url} target="_blank" rel="noreferrer">
                  <Download className="w-4 h-4" /> Télécharger
                </a>
              ) : (
                <span className="text-slate-400">n/a</span>
              )
            }
          />
          <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} />
          <Field label="Salaire demandé" value={formatEUR(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 Notes en mode démo */}
        <Section title="Notes" icon={StickyNote}>
          <div className="space-y-4">
            {/* Note de démonstration */}
            <div className="p-4 rounded-lg border bg-slate-50">
              <div className="text-sm text-slate-700 mb-2">
                🎭 <strong>Mode démonstration</strong>
              </div>
              <div className="text-sm text-slate-600">
                Cette section affiche normalement les notes internes liées au contrat. 
                En mode démo, les fonctionnalités d'ajout et de modification sont désactivées.
              </div>
              <div className="text-xs text-slate-400 mt-2">
                Exemple de note • Créée le {formatDateFR(new Date().toISOString())}
              </div>
            </div>
            
            {/* Bouton désactivé */}
            <button
              disabled
              className="w-full px-4 py-2 rounded-lg border bg-slate-100 text-slate-400 cursor-not-allowed flex items-center justify-center gap-2"
              title="Fonctionnalité désactivée en mode démo"
            >
              <StickyNote className="w-4 h-4" />
              Ajouter une note (désactivé en mode démo)
            </button>
          </div>
        </Section>
      </div>
      
      {/* Right column: Signature électronique, Déclarations, Paie, Temps de travail réel - ordre 2 sur mobile */}
      <div className="space-y-5 order-2">
        {/* 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" icon={Shield}>
          <Field
            label="DPAE"
            value={(() => {
              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 (
                  <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 (
                  <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 (
                  <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 <span className="text-xs text-slate-600">{raw}</span>;
              }
              
              // Aucune valeur
              return <span className="text-xs text-slate-400">—</span>;
            })()}
          />
        </Section>

        <Section title="Paie" icon={CreditCard}>
          {/* Nouvelle logique : affichage des fiches de paie Supabase */}
          {payslipsQuery.isLoading ? (
            <div className="text-slate-400">Chargement des fiches de paie…</div>
          ) : payslipsQuery.data && payslipsQuery.data.length > 0 ? (
            payslipsQuery.data.map((slip) => (
              <div key={slip.id} className="mb-4 p-4 rounded-lg border bg-slate-50 relative">
                {/* Bouton de paiement en position absolue dans le coin bas droit */}
                {slip.processed && (
                  <Button
                    onClick={() => handleTogglePayment(slip.id, slip.transfer_done)}
                    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={slip.transfer_done ? "Marquer comme non payée" : "Noter comme payée"}
                  >
                    <Euro className="w-3 h-3" />
                  </Button>
                )}
                
                <div className="mb-3">
                  <div className="font-medium text-slate-700">
                    Période : {formatDateFR(slip.period_start)} – {formatDateFR(slip.period_end)}
                  </div>
                </div>
                <Field label="État de traitement" value={slip.processed ? <Badge tone="ok">Terminé</Badge> : <Badge tone="warn">À traiter</Badge>} />
                <Field label="Virement effectué" value={slip.transfer_done ? <Badge tone="ok">Oui</Badge> : <Badge tone="error">Non</Badge>} />
                <Field label="Net avant PAS" value={formatEUR(slip.net_amount)} />
                <Field label="Net après PAS" value={formatEUR(slip.net_after_withholding)} />
                <Field label="Brut" value={formatEUR(slip.gross_amount)} />
                <Field label="Coût total employeur" value={formatEUR(slip.employer_cost)} />
                <Field label="AEM" value={(() => {
                  const aemNorm = String(slip.aem_status || '').normalize('NFD').replace(/\p{Diacritic}/gu, '').trim().toLowerCase();
                  // Vérifier d'abord si c'est "À traiter" pour éviter les faux positifs
                  if (aemNorm.includes('a traiter') || aemNorm.includes('a_traiter')) {
                    return <Badge tone="warn">À traiter</Badge>;
                  }
                  // Ensuite vérifier les cas OK
                  const aemOk = aemNorm === 'ok' || aemNorm === 'oui' || aemNorm.includes('ok') || aemNorm === 'valide';
                  return aemOk ? <Badge tone="ok">AEM OK</Badge> : <Badge tone="warn">À traiter</Badge>;
                })()} />
              </div>
            ))
          ) : (
            <span className="text-slate-400">Aucune fiche de paie disponible.</span>
          )}
        </Section>

        <Section title="Temps de travail réel" icon={Calendar}>
          <Field label="Jours travaillés" value={data.jours_travailles ?? 0} />
          <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>
    </div>

    {/* 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={selectedPayslipStatus ? "Confirmer le paiement" : "Confirmer l'annulation"}
      description={
        selectedPayslipStatus 
          ? "Êtes-vous sûr de vouloir marquer cette paie comme payée ? Cette action mettra à jour le statut de virement dans le système."
          : "Êtes-vous sûr de vouloir marquer cette paie comme non payée ? Cette action annulera le statut de virement dans le système."
      }
      confirmText={selectedPayslipStatus ? "Valider" : "Valider"}
      cancelText="Annuler"
      onConfirm={confirmTogglePayment}
      onCancel={() => {
        setShowPaymentModal(false);
        setSelectedPayslipId("");
        setSelectedPayslipStatus(false);
      }}
      confirmButtonVariant="gradient"
      isLoading={markAsPaidMutation.isPending}
    />
  </div>
);
}