/* ──────────────────────────────────────────────────────────────────────────
      FicheDetail.jsx — fiche détaillée d'un programme (champs de coûts, lots,
      calculs foncier/travaux/marge). Extraite de FichesProgrammes.jsx (dette D1,
      2026-06-24). Portée globale (pas d'import/export). Affichée par App.jsx.
      ────────────────────────────────────────────────────────────────────────── */
/* ── FicheDetail ── */
function FicheDetail({proj,fiche,onUpdate,onBack,soldeFinOp,rows,values,crm,onGenerateFlows,onLotStatutChange,onArchitecteEmailSent,onUpdateLotReelFlows}) {
  const prixAchat=toN(fiche.prixAchat), devisTravaux=toN(fiche.devisTravaux);
  const euribor=toN(fiche.euribor), montantCredit=toN(fiche.montantCredit);
  const creditMensuel=montantCredit*(euribor/100+0.025)/12;
  const creditMensuelR=toN(fiche.creditMensuelR);
  const montantCommerce=toN(fiche.montantCommerceRdc);
  const prixDenormandie=prixAchat-montantCommerce;
  const moe=devisTravaux*0.08, creditTotal=creditMensuel*8;
  const achatFNI=prixDenormandie*1.025+toN(fiche.dossierBanque)+creditTotal;
  const montantTravaux=moe+toN(fiche.dp)+toN(fiche.pc)+toN(fiche.plaquette)+toN(fiche.deplacements)+toN(fiche.avocat)+toN(fiche.hommeArt)+toN(fiche.geometre)+toN(fiche.diagnostics)+toN(fiche.loyerMeuble)+toN(fiche.doTrc)+toN(fiche.gfa)+devisTravaux;
  // creditTotalR = somme réelle de la ligne "Crédit mensuel" du Plan Hebdo (voir autoReals.creditMensuel)
  // Fallback : creditMensuelR (override) × 8 si pas de ligne Plan Hebdo trouvée
  const COUTS_FIELDS_P=["gfa","doTrc","dossierBanque","dp","pc","plaquette","deplacements","avocat","hommeArt","geometre","diagnostics","loyerMeuble"];
  const COUTS_FIELDS_R=["gfaR","doTrcR","dossierBanqueR","dpR","pcR","plaqueтteR","deplacementsR","avocatR","hommeArtR","geometreR","diagnosticsR","loyerMeubleR"];
  const lots=fiche.lots||[];
  const prixTotalHorsMarge=achatFNI+montantTravaux;
  const totalMargePct=(toN(fiche.margeBluePct)+toN(fiche.margeCGPpct))/100;
  const caOperation=totalMargePct<1?prixTotalHorsMarge/(1-totalMargePct):prixTotalHorsMarge;
  const dontMargeBlue=caOperation*(toN(fiche.margeBluePct)/100);
  const dontMargeCGP=caOperation*(toN(fiche.margeCGPpct)/100);
  const lotsCalc=useMemo(()=>{
    const totalSP=lots.reduce((s,l)=>s+toN(l.surface)+Math.min(toN(l.ext)/2,8),0);
    const plafondPinelVal=toN(fiche.plafondPinel);
    // Passe 1 : prix brut et prix pondéré par lot
    const pass1=lots.map(l=>{
      const sp=toN(l.surface)+Math.min(toN(l.ext)/2,8);
      const prixBrutCalc=totalSP>0?caOperation*sp/totalSP:0;
      const ponderPct=toN(l.ponderationPct||"");
      const prixPondere=prixBrutCalc*(1+ponderPct/100);
      return {sp,prixBrutCalc,ponderPct,prixPondere};
    });
    const totalPrixPondere=pass1.reduce((s,lp)=>s+lp.prixPondere,0);
    // Passe 2 : prix final normalisé au CA total
    return lots.map((l,idx)=>{
      const {sp,prixBrutCalc,ponderPct,prixPondere}=pass1[idx];
      const prixFinalCalc=totalPrixPondere>0?prixPondere*caOperation/totalPrixPondere:prixBrutCalc;
      const prixFinal=l.prixFinalO!==""?toN(l.prixFinalO):prixFinalCalc;
      const pm=toN(l.surface)>0?prixFinal/toN(l.surface):0;
      const foncier=prixTotalHorsMarge>0?prixFinal*achatFNI/prixTotalHorsMarge:0;
      const travaux=prixFinal-foncier;
      const prixReelVal=toN(l.prixReel);
      const foncierReelCalc=prixReelVal>0&&prixTotalHorsMarge>0?prixReelVal*achatFNI/prixTotalHorsMarge:0;
      const foncierReelOverride=l.foncierReelO!==""&&l.foncierReelO!=null?toN(l.foncierReelO):null;
      const foncierReel=prixReelVal>0&&foncierReelOverride!==null?foncierReelOverride:foncierReelCalc;
      const travauxReel=prixReelVal>0?prixReelVal-foncierReel:0;
      const coefPinel=sp>0?Math.min(0.7+19/sp,1.2):0;
      const loyerPinelCalc=plafondPinelVal>0&&sp>0?Math.round(plafondPinelVal*sp*coefPinel):0;
      return {sp,prixBrutCalc,ponderPct,prixPondere,prixFinalCalc,prixFinal,pm,foncier,travaux,foncierReelCalc,foncierReel,travauxReel,loyerPinelCalc};
    });
  },[lots,caOperation,achatFNI,prixTotalHorsMarge,fiche.plafondPinel]);
  const lotsTotal=lotsCalc.reduce((s,lc)=>s+lc.prixFinal,0);
  const updateLot=(idx,field,val)=>onUpdate("lots",lots.map((l,i)=>i===idx?{...l,[field]:val}:l));
  // Pour les programmes existants, nomProgramme et ville peuvent être vides dans fiche ;
  // on utilise proj.nom / proj.ville comme fallback afin que les champs soient pré-remplis.
  const ficheAffichee={...fiche,nomProgramme:fiche.nomProgramme||proj.nom||"",ville:fiche.ville||proj.ville||""};
  const ff={fiche:ficheAffichee,onUpdate};
  // Pilotage du statut commercial déménagé vers l'onglet « Suivi des signatures »
  // (mécanique centralisée dans App.jsx). Ici la pastille est en lecture seule.
  const [confirmFlows,setConfirmFlows]=useState(false);
  const [confirmReelUpdate,setConfirmReelUpdate]=useState(null); // {lotIdx} — demande de confirmation pour MAJ flux après saisie prix réel / retro réelle
  const [editIntervenant,setEditIntervenant]=useState(null); // null ou {idx:-1 pour nouveau, role, entrepriseId, entrepriseNom, typeCout, contact}
  const [showColumnsMenu,setShowColumnsMenu]=useState(false);
  /* ── Appels de fonds EG : pct_cumule par lot_id (String(idx+1)) ── */
  const [appelsFonds,setAppelsFonds]=useState({});
  // Sprint F-d : extrait en useCallback pour pouvoir refetch après dispatch
  // de l'event 'appels-eg-updated' (envoi d'un appel client → pct_cumule change).
  const loadAppelsFonds=useCallback(()=>{
    if(!proj.id) return;
    fetch('/api/appels-eg?programme_id='+encodeURIComponent(proj.id))
      .then(r=>r.json())
      .then(rows=>{
        const map={};
        (rows||[]).forEach(row=>{
          const k=String(row.lot_id);
          if(map[k]===undefined) map[k]=Number(row.pct_cumule)||0;
        });
        setAppelsFonds(map);
      })
      .catch(()=>{});
  },[proj.id]);
  useEffect(()=>{ loadAppelsFonds(); },[loadAppelsFonds]);
  // Refresh quand un appel client est envoyé (event dispatché par Notifications.jsx)
  useEffect(()=>{
    const onUpdate=(ev)=>{
      if(!ev?.detail?.programme_id||ev.detail.programme_id===proj.id) loadAppelsFonds();
    };
    window.addEventListener('appels-eg-updated',onUpdate);
    return ()=>window.removeEventListener('appels-eg-updated',onUpdate);
  },[proj.id,loadAppelsFonds]);
  const [hiddenLotCols,setHiddenLotCols]=useState(()=>{
    try{const s=localStorage.getItem("tresoimmo_hiddenLotCols");return s?JSON.parse(s):{};}catch(e){return {};}
  });
  const toggleLotCol=(key)=>setHiddenLotCols(h=>{
    const nh={...h,[key]:!h[key]};
    try{localStorage.setItem("tresoimmo_hiddenLotCols",JSON.stringify(nh));}catch(e){}
    return nh;
  });
  const LOT_COL_TOGGLES=[
    {key:"loyerPinel",label:"Loyer Pinel"},
    {key:"prixBrut",label:"Prix brut"},
    {key:"ponderation",label:"Pondération"},
    {key:"prixPondere",label:"Prix pondéré"},
    {key:"foncier",label:"Foncier"},
    {key:"travaux",label:"Travaux"},
    {key:"foncierReel",label:"Foncier réel"},
    {key:"travauxReel",label:"Travaux réels"},
    {key:"retroPct",label:"% Rétro réel"},
    {key:"retroMontant",label:"Montant rétro réel"},
  ];

  /* Auto-génération des flux DÉSACTIVÉE — utiliser le bouton manuel */
  // const prevAcqRef=useRef(fiche.dateAcquisition);
  // const prevDtRef=useRef(fiche.dateDebutTravaux);
  // const isFirstDate=useRef(!fiche.dateAcquisition);

  /* Auto-réel depuis Plan Hebdo (toutes lignes R ET F, car les flux engagés
     sont pertinents quel que soit le statut de la ligne) */
  const autoReals = useMemo(()=>{
    if(!rows||!values) return {};
    const projRowsR=rows.filter(r=>r.projetId===proj.id);
    // fix R4 : on matche le mot-clé comme MOT ENTIER (pas en sous-chaîne), sinon des libellés
    // courts (« dp », « pc », « eau », « moe », « trc »…) s'accrochent à des lignes sans rapport
    // (« eau » dans « bureau », etc.) et faussent la colonne Réel. Comparaison sans accents.
    const fold=s=>String(s||'').normalize('NFD').replace(/[̀-ͯ]/g,'').toLowerCase();
    const esc=s=>s.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');
    const hit=(label,kw)=>new RegExp('\\b'+esc(fold(kw))+'\\b').test(fold(label));
    const sumOf=found=>Math.abs(values.filter(v=>found.some(r=>r.id===v.rowId)).reduce((s,v)=>s+v.montant,0));
    const match=(kws)=>{
      const found=projRowsR.filter(r=>kws.some(kw=>hit(r.label,kw)));
      return found.length?sumOf(found):undefined;
    };
    // Variante avec exclusion : ignore les lignes dont le label contient un des `excl`
    // (ex. « Travaux » ne doit PAS récupérer la ligne « Plus-value travaux »).
    const matchEx=(kws,excl)=>{
      const found=projRowsR.filter(r=>{
        if((excl||[]).some(e=>hit(r.label,e))) return false;
        return kws.some(kw=>hit(r.label,kw));
      });
      return found.length?sumOf(found):undefined;
    };
    return {
      gfa:         match(["gfa"]),
      doTrc:       match(["do/trc","trc","assurance do","do trc"]),
      dossierBanque: match(["dossier banque","dossier de banque"]),
      dp:          match(["dp","dépôt permis","dépôt de permis"]),
      pc:          match(["pc","permis construire","permis de construire"]),
      plaquette:   match(["plaquette"]),
      deplacements: match(["déplacement"]),
      avocat:      match(["avocat"]),
      hommeArt:    match(["homme de l'art","homme art"]),
      geometre:    match(["géomètre","geometre"]),
      diagnostics: match(["diagnostic"]),
      loyerMeuble: match(["loyer"]),
      travaux:     matchEx(["travaux"],["plus-value","plus value"]),
      plusvalueTravaux: match(["plus-value travaux","plus-value","plus value"]),
      creditMensuel: match(["crédit mensuel","credit mensuel"]),
      moe:         match(["moe"]),
      taxeFonciere: match(["taxe foncière","taxe fonciere"]),
      eauElectricite: match(["eau et électricité","eau électricité","eau"]),
      autres:      match(["autres"]),
    };
  },[rows,values,proj.id]);

  const effectiveR=(fieldR,ar)=>{
    const ov=fiche[fieldR];
    if(ov!==""&&ov!==undefined&&ov!==null) return toN(ov);
    return ar!==undefined?ar:0;
  };

  // Crédit total réel : somme de toute la ligne "Crédit mensuel" du Plan Hebdo.
  // Fallback sur l'override creditMensuelR × 8 si la ligne n'existe pas encore.
  const creditTotalR = (autoReals.creditMensuel!==undefined)
    ? autoReals.creditMensuel
    : creditMensuelR*8;

  const coutsTotalP=COUTS_FIELDS_P.reduce((s,f)=>s+toN(fiche[f]),0)+creditTotal+moe+devisTravaux+toN(fiche.plusvalueTravaux)+toN(fiche.taxeFonciere)+toN(fiche.eauElectricite)+toN(fiche.autres);
  const coutsTotalR=
    effectiveR("gfaR",autoReals.gfa)+
    effectiveR("doTrcR",autoReals.doTrc)+
    effectiveR("dossierBanqueR",autoReals.dossierBanque)+
    creditTotalR+
    effectiveR("moeR",autoReals.moe)+
    effectiveR("travauxR",autoReals.travaux)+
    effectiveR("plusvalueTravauxR",autoReals.plusvalueTravaux)+
    effectiveR("dpR",autoReals.dp)+
    effectiveR("pcR",autoReals.pc)+
    effectiveR("plaqueтteR",autoReals.plaquette)+
    effectiveR("deplacementsR",autoReals.deplacements)+
    effectiveR("avocatR",autoReals.avocat)+
    effectiveR("hommeArtR",autoReals.hommeArt)+
    effectiveR("geometreR",autoReals.geometre)+
    effectiveR("diagnosticsR",autoReals.diagnostics)+
    effectiveR("loyerMeubleR",autoReals.loyerMeuble)+
    effectiveR("taxeFonciereR",autoReals.taxeFonciere)+
    effectiveR("eauElectriciteR",autoReals.eauElectricite)+
    effectiveR("autresR",autoReals.autres);

  const sc=fiche.statut==="En cours"?"#15803d":fiche.statut==="à venir"?"#b45309":fiche.statut==="Livré"?"#1d4ed8":"#64748b";
  const sb=fiche.statut==="En cours"?"#dcfce7":fiche.statut==="à venir"?"#fef3c7":fiche.statut==="Livré"?"#dbeafe":"#f1f5f9";

  return (
    <div style={{padding:20,maxWidth:900,margin:"0 auto"}}>
      <div style={{display:"flex",alignItems:"center",gap:12,marginBottom:20}}>
        <button onClick={onBack} style={{background:"#334155",color:"#fff",border:"none",borderRadius:7,padding:"5px 12px",cursor:"pointer",fontSize:12,fontWeight:600}}>← Retour</button>
        <div>
          <div style={{fontWeight:800,fontSize:18}}>{proj.ville?proj.ville+" – ":""}{proj.nom}</div>
          <div style={{fontSize:12,color:C.muted}}>{[fiche.adresse,fiche.codePostal,fiche.ville].filter(Boolean).join(", ")||"Adresse non renseignée"}</div>
        </div>
        <span style={{marginLeft:"auto",fontSize:11,background:sb,color:sc,borderRadius:6,padding:"3px 10px",fontWeight:600}}>{fiche.statut}</span>
      </div>

      {/* Solde fin d'opération */}
      <div style={{background:C.card,borderRadius:10,border:"1px solid "+C.border,padding:14,textAlign:"center",marginBottom:14}}>
        <div style={{fontSize:11,color:C.muted,marginBottom:4}}>
          <span style={{background:"#dbeafe",color:"#1d4ed8",borderRadius:3,padding:"0 6px",fontSize:10,fontWeight:700,marginRight:6}}>R+F</span>
          Solde fin d'opération (total de tous les flux)
        </div>
        <div style={{fontSize:22,fontWeight:800,color:soldeFinOp>=0?"#2563eb":C.red}}>{fmtEur(soldeFinOp)}</div>
      </div>

      <FicheSection title="📍 Informations Opération" color="#38bdf8">
        <div style={{display:"grid",gridTemplateColumns:"1fr 1fr 1fr",gap:12}}>
          <FicheField label="Nom du programme" field="nomProgramme"{...ff}/><FicheField label="Ville" field="ville"{...ff}/>
          <FicheField label="Type d'opération" field="typeOp" opts={["Rénovation","Construction","VEFA","Marchand de biens","Autre"]}{...ff}/>
          <FicheField label="Adresse" field="adresse"{...ff}/><FicheField label="Code postal" field="codePostal"{...ff}/>
          <FicheField label="Statut" field="statut" opts={["En cours","à venir","Livré","Abandonné"]}{...ff}/>
          <FicheField label="Prix d'achat immeuble (€)" field="prixAchat"{...ff}/><FicheField label="Montant commerce RdC (€)" field="montantCommerceRdc"{...ff}/>
          <FicheField label="Prix Denormandie (€)" field="prixDenormandie" calc calcVal={fmtEur(prixDenormandie)}{...ff}/><FicheField label="Nombre de lots" field="nbLots"{...ff}/>
          <FicheField label="Devis travaux (€)" field="devisTravaux"{...ff}/><FicheField label="Surface habitable (m²)" field="surfaceTotale"{...ff}/>
          <FicheField label="Parties communes (m²)" field="partiesCommunes"{...ff}/><FicheField label="Extérieurs (m²)" field="exterieurs"{...ff}/>
          <FicheField label="Euribor 3 mois" field="euribor" suffix="%" {...ff}/><FicheField label="Nombre de lots occupés" field="nbLotsOccupes"{...ff}/>
          <FicheField label="Montant du crédit (€)" field="montantCredit"{...ff}/><FicheField label="Plafond Pinel (€/m²)" field="plafondPinel"{...ff}/>
          <FicheField label="DP ou PC ou Rien" field="dpOuPc" opts={["DP","PC","Rien"]}{...ff}/><FicheField label="Date d'acquisition" field="dateAcquisition" type="date"{...ff}/>
          <FicheField label="Date de démarrage des travaux" field="dateDebutTravaux" type="date"{...ff}/><FicheField label="Date de livraison prévue" field="dateLivraison" type="date"{...ff}/>
          <FicheField label="Banque" field="banque"{...ff}/>
          <FicheField label="IBAN du programme (appels de fonds)" field="ibanProgramme"{...ff}/>
          <div style={{gridColumn:"1/-1",display:"flex",alignItems:"center",gap:10,padding:"8px 10px",background:"#fffbeb",border:"1px solid #fde68a",borderRadius:7,marginTop:4}}>
            <input
              type="checkbox"
              id="prevalidationGFA"
              checked={!!fiche.prevalidationGFA}
              onChange={e=>onUpdate("prevalidationGFA",e.target.checked)}
              style={{width:16,height:16,cursor:"pointer",accentColor:"#f59e0b"}}
            />
            <label htmlFor="prevalidationGFA" style={{fontSize:13,fontWeight:600,color:"#92400e",cursor:"pointer",userSelect:"none"}}>
              Pré-validation GFA
            </label>
            <span style={{fontSize:11,color:"#b45309",marginLeft:4}}>(cocher si la GFA demande une prévalidation de chaque facture par email)</span>
          </div>
          {!!fiche.prevalidationGFA&&(()=>{
            const gfaIntervenants=(fiche.intervenants||[]).filter(iv=>iv.role==="Assurance GFA");
            if(gfaIntervenants.length===0) return (
              <div style={{gridColumn:"1/-1",padding:"8px 12px",background:"#fff7ed",border:"1px solid #fed7aa",borderRadius:7,marginTop:4,fontSize:13,color:"#c2410c",fontWeight:600}}>
                ⚠️ Aucun intervenant « Assurance GFA » trouvé dans ce programme. Ajoutez-le dans la section Intervenants.
              </div>
            );
            const emailOptions=[];
            gfaIntervenants.forEach(iv=>{
              const ent=(crm.entreprises||[]).find(e=>e.id===iv.entrepriseId);
              if(ent&&ent.emails){
                ent.emails.split(/[,;]/).map(s=>s.trim()).filter(Boolean).forEach(addr=>{
                  if(!emailOptions.includes(addr)) emailOptions.push(addr);
                });
              }
            });
            if(emailOptions.length===0) return (
              <div style={{gridColumn:"1/-1",padding:"8px 12px",background:"#fff7ed",border:"1px solid #fed7aa",borderRadius:7,marginTop:4,fontSize:13,color:"#c2410c",fontWeight:600}}>
                ⚠️ Aucun email trouvé pour l'intervenant « Assurance GFA ». Renseignez le champ Email(s) de l'entreprise dans le CRM.
              </div>
            );
            /* Pré-sélectionner la première adresse si le champ est vide */
            if(!fiche.gfaEmailContact && emailOptions.length>0) onUpdate("gfaEmailContact",emailOptions[0]);
            return (
              <div style={{gridColumn:"1/-1",display:"flex",alignItems:"center",gap:10,padding:"8px 10px",background:"#f0fdf4",border:"1px solid #86efac",borderRadius:7,marginTop:4}}>
                <span style={{fontSize:12,fontWeight:600,color:"#15803d",flexShrink:0}}>📧 Email GFA :</span>
                <select value={fiche.gfaEmailContact||""} onChange={e=>onUpdate("gfaEmailContact",e.target.value)}
                  style={{flex:1,padding:"5px 8px",border:"1px solid #86efac",borderRadius:6,fontSize:13,background:"#fff",color:"#15803d"}}>
                  {emailOptions.map(addr=><option key={addr} value={addr}>{addr}</option>)}
                </select>
              </div>
            );
          })()}
        </div>
      </FicheSection>

      {/* ── Section Intervenants ── */}
      <FicheSection title="👥 Intervenants" color="#8b5cf6">
        {(fiche.intervenants||[]).length===0&&!editIntervenant&&(
          <div style={{color:"#94a3b8",fontSize:13,marginBottom:8}}>Aucun intervenant renseigné.</div>
        )}
        {(fiche.intervenants||[]).map((iv,idx)=>(
          <div key={idx} style={{display:"flex",alignItems:"center",gap:8,padding:"7px 10px",background:"#faf5ff",borderRadius:7,marginBottom:6,border:"1px solid #e9d5ff"}}>
            <span style={{fontSize:11,fontWeight:700,color:"#7c3aed",background:"#ede9fe",borderRadius:4,padding:"2px 8px",flexShrink:0}}>{iv.role||"—"}</span>
            <span style={{fontSize:13,flex:1,fontWeight:500}}>{iv.entrepriseNom||iv.contact||"—"}</span>
            {iv.contact&&iv.entrepriseNom&&<span style={{fontSize:12,color:"#64748b"}}>{iv.contact}</span>}
            {iv.typeCout&&<span style={{fontSize:11,color:"#6d28d9",background:"#f3e8ff",borderRadius:4,padding:"1px 7px",flexShrink:0}}>{iv.typeCout}</span>}
            <button onClick={()=>setEditIntervenant({...iv,idx})}
              style={{background:"#334155",color:"#fff",border:"none",borderRadius:5,padding:"2px 9px",fontSize:11,cursor:"pointer",fontWeight:600}}>✎</button>
            <button onClick={()=>onUpdate("intervenants",(fiche.intervenants||[]).filter((_,i)=>i!==idx))}
              style={{background:"#dc2626",color:"#fff",border:"none",borderRadius:5,padding:"2px 9px",fontSize:11,cursor:"pointer",fontWeight:600}}>✕</button>
          </div>
        ))}
        {!editIntervenant&&(
          <button onClick={()=>setEditIntervenant({idx:-1,role:"MOE",entrepriseId:"",entrepriseNom:"",typeCout:"",contact:""})}
            style={{background:"#8b5cf6",color:"#fff",border:"none",borderRadius:7,padding:"6px 14px",fontSize:12,cursor:"pointer",fontWeight:600,marginTop:4}}>
            + Ajouter un intervenant
          </button>
        )}
        {editIntervenant&&(
          <div style={{background:"#faf5ff",border:"1px solid #c4b5fd",borderRadius:10,padding:14,marginTop:10}}>
            <div style={{fontWeight:700,fontSize:13,color:"#7c3aed",marginBottom:10}}>
              {editIntervenant.idx===-1?"Nouvel intervenant":"Modifier l'intervenant"}
            </div>
            <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:8,marginBottom:8}}>
              <div>
                <div style={{fontSize:11,color:"#64748b",marginBottom:3,fontWeight:600}}>Rôle</div>
                <select value={editIntervenant.role||""} onChange={e=>setEditIntervenant(v=>({...v,role:e.target.value}))}
                  style={{width:"100%",padding:"5px 7px",border:"1px solid #ddd6fe",borderRadius:5,fontSize:12,background:"#fff"}}>
                  {ROLES_INTERVENANTS.map(r=><option key={r}>{r}</option>)}
                </select>
              </div>
              <div>
                <div style={{fontSize:11,color:"#64748b",marginBottom:3,fontWeight:600}}>Poste coût associé</div>
                <select value={editIntervenant.typeCout||""} onChange={e=>setEditIntervenant(v=>({...v,typeCout:e.target.value}))}
                  style={{width:"100%",padding:"5px 7px",border:"1px solid #ddd6fe",borderRadius:5,fontSize:12,background:"#fff"}}>
                  <option value="">— Aucun —</option>
                  {COUT_ROWS_LABELS.map(l=><option key={l} value={l}>{l}</option>)}
                </select>
              </div>
            </div>
            <div style={{marginBottom:8}}>
              <div style={{fontSize:11,color:"#64748b",marginBottom:3,fontWeight:600}}>Société (depuis le CRM)</div>
              <select value={editIntervenant.entrepriseId||""} onChange={e=>{
                const ent=(crm.entreprises||[]).find(en=>en.id===e.target.value);
                setEditIntervenant(v=>({...v,entrepriseId:e.target.value,entrepriseNom:ent?ent.nom:""}));
              }} style={{width:"100%",padding:"5px 7px",border:"1px solid #ddd6fe",borderRadius:5,fontSize:12,background:"#fff"}}>
                <option value="">— Sélectionner dans le CRM —</option>
                {(crm.entreprises||[]).map(en=><option key={en.id} value={en.id}>{en.nom}</option>)}
              </select>
            </div>
            <div style={{marginBottom:12}}>
              <div style={{fontSize:11,color:"#64748b",marginBottom:3,fontWeight:600}}>Contact / Nom de la personne</div>
              <input type="text" value={editIntervenant.contact||""} onChange={e=>setEditIntervenant(v=>({...v,contact:e.target.value}))}
                placeholder="Ex : Jean Dupont"
                style={{width:"100%",padding:"5px 7px",border:"1px solid #ddd6fe",borderRadius:5,fontSize:12,background:"#fff"}}/>
            </div>
            <div style={{display:"flex",gap:8}}>
              <button onClick={()=>{
                const iv={role:editIntervenant.role,entrepriseId:editIntervenant.entrepriseId,entrepriseNom:editIntervenant.entrepriseNom,typeCout:editIntervenant.typeCout,contact:editIntervenant.contact};
                const list=fiche.intervenants||[];
                if(editIntervenant.idx===-1) onUpdate("intervenants",[...list,iv]);
                else onUpdate("intervenants",list.map((l,i)=>i===editIntervenant.idx?iv:l));
                setEditIntervenant(null);
              }} style={{background:"#8b5cf6",color:"#fff",border:"none",borderRadius:6,padding:"6px 14px",fontSize:12,cursor:"pointer",fontWeight:700}}>
                ✓ Enregistrer
              </button>
              <button onClick={()=>setEditIntervenant(null)}
                style={{background:"#f1f5f9",border:"1px solid #e2e8f0",borderRadius:6,padding:"6px 12px",fontSize:12,cursor:"pointer"}}>
                Annuler
              </button>
            </div>
          </div>
        )}
      </FicheSection>

      {/* Bannière génération flux */}
      {onGenerateFlows&&(
        <div style={{background:fiche.dateDebutTravaux?"#f0fdfa":"#f8fafc",border:"1px solid "+(fiche.dateDebutTravaux?"#99f6e4":"#e2e8f0"),borderRadius:10,padding:"12px 16px",marginBottom:14,display:"flex",alignItems:"center",gap:12,flexWrap:"wrap"}}>
          <span style={{fontSize:13,flex:1}}>
            {fiche.dateDebutTravaux
              ? <><b style={{color:"#0f766e"}}>⚡ Flux prévisionnels</b> — date de démarrage : <b>{new Date(fiche.dateDebutTravaux+"T12:00:00Z").toLocaleDateString("fr-FR")}</b>. Les flux prévisionnels (F) existants seront écrasés lors du recalcul. Les flux réels (R) sont préservés.</>
              : <span style={{color:C.muted}}>Renseignez la <b>date de démarrage des travaux</b> pour générer automatiquement les flux prévisionnels dans le Plan Hebdo.</span>
            }
          </span>
          <button onClick={()=>setConfirmFlows(true)} disabled={!fiche.dateDebutTravaux}
            style={{background:fiche.dateDebutTravaux?"#0d9488":"#cbd5e1",color:"#fff",border:"none",borderRadius:8,padding:"8px 18px",fontSize:13,fontWeight:700,cursor:fiche.dateDebutTravaux?"pointer":"default",flexShrink:0}}>
            ⚡ Recalculer les flux
          </button>
        </div>
      )}

      {/* Modale confirmation recalcul flux */}
      {confirmFlows&&(()=>{
        const STATUTS_AVANCES=['OPTION','LIA','COMPROMIS'];
        const lotsAvances=(lots||[]).filter(l=>STATUTS_AVANCES.includes(l.statutCommercial)||isAvancement(l.statutCommercial));
        return (
        <div style={{position:"fixed",inset:0,background:"rgba(0,0,0,0.45)",zIndex:2000,display:"flex",alignItems:"center",justifyContent:"center"}} onClick={()=>setConfirmFlows(false)}>
          <div style={{background:"#fff",borderRadius:16,padding:28,width:480,maxWidth:"95vw",boxShadow:"0 8px 40px #0003",border:"1px solid #e2e8f0"}} onClick={e=>e.stopPropagation()}>
            <div style={{fontSize:24,textAlign:"center",marginBottom:8}}>⚠️</div>
            <div style={{fontWeight:800,fontSize:16,textAlign:"center",marginBottom:8}}>Recalculer les flux prévisionnels ?</div>
            <div style={{fontSize:13,color:"#64748b",textAlign:"center",marginBottom:6}}>
              Cette action va <b style={{color:"#dc2626"}}>écraser tous les flux prévisionnels (F)</b> existants pour ce programme et les remplacer par les valeurs recalculées.
              {!fiche.dateDebutTravaux&&fiche.dateAcquisition&&<div style={{marginTop:4,fontSize:12,color:"#b45309"}}>⚠️ Date début travaux non saisie — hypothèse : date d'achat + 39 semaines</div>}
            </div>
            {lotsAvances.length>0&&(
              <div style={{fontSize:12,color:"#92400e",background:"#fef3c7",border:"1px solid #fbbf24",borderRadius:6,padding:"8px 12px",marginBottom:10}}>
                <b>⚠️ {lotsAvances.length} lot{lotsAvances.length>1?"s":""} déjà avancé{lotsAvances.length>1?"s":""} :</b>{" "}
                {lotsAvances.map((l,i)=>{
                  const idx=(lots||[]).indexOf(l);
                  return <span key={i}><b>Lot {idx+1}</b> ({l.statutCommercial}){i<lotsAvances.length-1?", ":""}</span>;
                })}<br/>
                Leurs flux prévisionnels (F) seront <b>replacés sur le calendrier générique</b> (dateDebutTravaux ±4 sem), effaçant les dates individuelles issues de leur statut. Utilisez le bouton <b>🔄</b> par lot pour recalculer uniquement un lot spécifique.
              </div>
            )}
            <div style={{fontSize:12,color:"#16a34a",textAlign:"center",background:"#dcfce7",borderRadius:6,padding:"6px 12px",marginBottom:20}}>
              ✓ Les flux réels (R) ne seront pas modifiés.
            </div>
            <div style={{display:"flex",gap:10,justifyContent:"center"}}>
              <button onClick={()=>{if(onGenerateFlows)onGenerateFlows(proj.id);setConfirmFlows(false);}}
                style={{background:"#0d9488",color:"#fff",border:"none",borderRadius:8,padding:"9px 22px",fontSize:13,fontWeight:700,cursor:"pointer"}}>
                ⚡ Confirmer le recalcul
              </button>
              <button onClick={()=>setConfirmFlows(false)}
                style={{background:"#f1f5f9",border:"1px solid #e2e8f0",borderRadius:8,padding:"9px 18px",fontSize:13,cursor:"pointer"}}>
                Annuler
              </button>
            </div>
          </div>
        </div>
        );
      })()}

      <FicheSection title="💰 Coûts engagés" color="#f59e0b">
        <div style={{fontSize:11,color:"#64748b",marginBottom:10,background:"#fffbeb",borderRadius:6,padding:"6px 10px",border:"1px solid #fde68a"}}>
          ℹ️ Les valeurs <b style={{color:"#15803d"}}>Réel</b> sont calculées automatiquement depuis le Plan Hebdo (lignes dont le nom contient le poste). Cliquez sur <b>✎</b> pour forcer manuellement, <b>↺</b> pour revenir au calcul.
        </div>
        <div style={{overflowX:"auto"}}>
          <table style={{borderCollapse:"collapse",width:"100%"}}>
            <thead>
              <tr style={{background:"#fffbeb",borderBottom:"2px solid #fde68a"}}>
                <th style={{padding:"7px 8px",textAlign:"left",fontSize:11,color:C.muted,fontWeight:600,minWidth:160}}>Poste</th>
                <th style={{padding:"7px 8px",textAlign:"right",fontSize:11,color:"#b45309",fontWeight:700,minWidth:130}}>📋 Prévisionnel</th>
                <th style={{padding:"7px 8px",textAlign:"right",fontSize:11,color:"#15803d",fontWeight:700,minWidth:145}}>✓ Réel</th>
                <th style={{padding:"7px 8px",textAlign:"right",fontSize:11,color:C.muted,fontWeight:600,minWidth:90}}>Écart</th>
              </tr>
            </thead>
            <tbody>
              <CoutRow label="GFA" fieldP="gfa" fieldR="gfaR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.gfa}/>
              <CoutRow label="DO / TRC" fieldP="doTrc" fieldR="doTrcR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.doTrc}/>
              <CoutRow label="Dossier banque" fieldP="dossierBanque" fieldR="dossierBanqueR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.dossierBanque}/>
              <CoutRow label="Crédit mensuel" fieldP="creditMensuel" fieldR="creditMensuelR" fiche={fiche} onUpdate={onUpdate} calcP={creditMensuel}/>
              <CoutRow label="Crédit total (×8)" fieldP="creditMensuel" fieldR="creditMensuelR" fiche={fiche} onUpdate={onUpdate} calcP={creditTotal} calcR={creditTotalR}/>
              <CoutRow label="MOE (8% travaux)" fieldP="_moe" fieldR="moeR" fiche={fiche} onUpdate={onUpdate} calcP={moe} autoReal={autoReals.moe}/>
              <CoutRow label="Travaux" fieldP="devisTravaux" fieldR="travauxR" fiche={fiche} onUpdate={onUpdate} calcP={devisTravaux} autoReal={autoReals.travaux}/>
              <CoutRow label="Plus-value travaux" fieldP="plusvalueTravaux" fieldR="plusvalueTravauxR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.plusvalueTravaux}/>
              <CoutRow label="DP" fieldP="dp" fieldR="dpR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.dp}/>
              <CoutRow label="PC" fieldP="pc" fieldR="pcR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.pc}/>
              <CoutRow label="Plaquette 3D" fieldP="plaquette" fieldR="plaqueтteR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.plaquette}/>
              <CoutRow label="Déplacements" fieldP="deplacements" fieldR="deplacementsR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.deplacements}/>
              <CoutRow label="Avocat" fieldP="avocat" fieldR="avocatR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.avocat}/>
              <CoutRow label="Homme de l'art" fieldP="hommeArt" fieldR="hommeArtR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.hommeArt}/>
              <CoutRow label="Géomètre" fieldP="geometre" fieldR="geometreR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.geometre}/>
              <CoutRow label="Diagnostics" fieldP="diagnostics" fieldR="diagnosticsR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.diagnostics}/>
              <CoutRow label="Loyer meublé" fieldP="loyerMeuble" fieldR="loyerMeubleR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.loyerMeuble}/>
              <CoutRow label="Taxe foncière" fieldP="taxeFonciere" fieldR="taxeFonciereR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.taxeFonciere}/>
              <CoutRow label="Eau et électricité" fieldP="eauElectricite" fieldR="eauElectriciteR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.eauElectricite}/>
              <CoutRow label="Autres" fieldP="autres" fieldR="autresR" fiche={fiche} onUpdate={onUpdate} autoReal={autoReals.autres}/>
              <tr style={{background:"#fffbeb",borderTop:"2px solid #fde68a",fontWeight:700}}>
                <td style={{padding:"7px 8px",fontSize:12,color:C.text}}>TOTAL</td>
                <td style={{padding:"7px 8px",textAlign:"right",fontSize:13,color:"#b45309"}}>{fmtEur(coutsTotalP)}</td>
                <td style={{padding:"7px 8px",textAlign:"right",fontSize:13,color:"#15803d"}}>{fmtEur(coutsTotalR)}</td>
                <td style={{padding:"7px 8px",textAlign:"right",fontSize:12,fontWeight:700,
                  color:(coutsTotalR-coutsTotalP)>0?"#dc2626":(coutsTotalR-coutsTotalP)<0?"#16a34a":"#94a3b8"}}>
                  {(coutsTotalP||coutsTotalR)?((coutsTotalR-coutsTotalP)>=0?"+":"")+fmtEur(coutsTotalR-coutsTotalP,true):"—"}
                </td>
              </tr>
            </tbody>
          </table>
        </div>
        {(() => {
          // Marge CGP réelle : on part du prévisionnel (dontMargeCGP) réparti équitablement entre les lots.
          // Pour chaque lot vendu dont la rétrocession réelle est renseignée (retroMontantR),
          // on remplace sa part prévisionnelle par la valeur réelle — alignement avec la logique
          // de mise à jour des flux (handleLotStatutChange / onUpdateLotReelFlows).
          const nbLotsCGP = Math.max(lots.length, 1);
          const cgpParLotPrev = dontMargeCGP / nbLotsCGP;
          const margeCGPreel = lots.reduce((s,l) => {
            const rm = toN(l.retroMontantR);
            return s + (rm > 0 ? rm : cgpParLotPrev);
          }, 0);
          // Marge Blue réelle = solde fin d'opération (ce qui reste à la fin du programme, tous flux confondus)
          const margeBlueReel = soldeFinOp;
          const subLabel={fontSize:11,color:C.muted,marginBottom:3};
          const calcBox={...FICHE_CALC,padding:"6px 10px"};
          return (
            <div style={{display:"flex",flexDirection:"column",gap:12,marginTop:12}}>
              {/* Marge CGP */}
              <div style={{display:"grid",gridTemplateColumns:"1fr 1fr 1fr",gap:10,alignItems:"end",background:"#fdf4ff",border:"1px solid #f5d0fe",borderRadius:8,padding:"10px 12px"}}>
                <FicheField label="Marge CGP (%)" field="margeCGPpct"{...ff}/>
                <div style={{marginBottom:10}}>
                  <div style={subLabel}>Marge CGP prévisionnelle (€) <span style={{color:C.accent,fontSize:10}}>calculé</span></div>
                  <div style={{...calcBox,borderColor:"#f5d0fe",color:"#a21caf"}}>{fmtEur(dontMargeCGP)}</div>
                </div>
                <div style={{marginBottom:10}}>
                  <div style={subLabel}>Marge CGP réelle (€) <span style={{color:"#15803d",fontSize:10}}>Lots vendus</span></div>
                  <div style={{...calcBox,background:"#f0fdf4",borderColor:"#bbf7d0",color:"#15803d"}}>{fmtEur(margeCGPreel)}</div>
                </div>
              </div>
              {/* Marge Blue */}
              <div style={{display:"grid",gridTemplateColumns:"1fr 1fr 1fr",gap:10,alignItems:"end",background:"#eff6ff",border:"1px solid #bfdbfe",borderRadius:8,padding:"10px 12px"}}>
                <FicheField label="Marge Blue (%)" field="margeBluePct"{...ff}/>
                <div style={{marginBottom:10}}>
                  <div style={subLabel}>Marge Blue prévisionnelle (€) <span style={{color:C.accent,fontSize:10}}>calculé</span></div>
                  <div style={{...calcBox,borderColor:"#bfdbfe",color:"#1d4ed8"}}>{fmtEur(dontMargeBlue)}</div>
                </div>
                <div style={{marginBottom:10}}>
                  <div style={subLabel}>Marge Blue réelle (€) <span style={{color:"#15803d",fontSize:10}}>Solde fin op.</span></div>
                  <div style={{...calcBox,background:"#f0fdf4",borderColor:"#bbf7d0",color:margeBlueReel>=0?"#15803d":"#dc2626"}}>{fmtEur(margeBlueReel)}</div>
                </div>
              </div>
            </div>
          );
        })()}
      </FicheSection>

      <FicheSection title="📊 Chiffre d'affaire de l'opération" color="#a855f7">
        <div style={{display:"grid",gridTemplateColumns:"1fr 1fr 1fr",gap:12}}>
          <FicheField label="Achat total FNI (€)" calc calcVal={fmtEur(achatFNI)}{...ff}/>
          <FicheField label="Montant des travaux (€)" calc calcVal={fmtEur(montantTravaux)}{...ff}/>
          <FicheField label="Prix total hors marge (€)" calc calcVal={fmtEur(prixTotalHorsMarge)}{...ff}/>
          <FicheField label="Dont marge Blue (€)" calc calcVal={fmtEur(dontMargeBlue)}{...ff}/>
          <FicheField label="Dont marge CGP (€)" calc calcVal={fmtEur(dontMargeCGP)}{...ff}/>
          <div style={{marginBottom:10}}>
            <div style={{fontSize:11,color:C.muted,marginBottom:3}}>CA Opération (€) <span style={{color:C.accent,fontSize:10}}>calculé</span></div>
            <div style={{...FICHE_CALC,color:C.green,fontSize:16,borderColor:"#a855f7"}}>{fmtEur(caOperation)}</div>
          </div>
        </div>
      </FicheSection>

      <FicheSection title="🏠 Lots" color="#22c55e">
        {lots.filter(l=>toN(l.surface)===0&&l.prixBrutO==="").length>0&&(
          <div style={{background:"#fef9c3",border:"1px solid #f59e0b",borderRadius:6,padding:"8px 12px",marginBottom:10,fontSize:12,color:"#92400e"}}>
            ⚠️ {lots.filter(l=>toN(l.surface)===0&&l.prixBrutO==="").length} lot(s) sans surface renseignée — ils ne reçoivent aucune part du CA.
          </div>
        )}
        <div style={{display:"flex",justifyContent:"flex-end",marginBottom:6,position:"relative"}}>
          <button onClick={()=>setShowColumnsMenu(v=>!v)} style={{background:C.card,border:"1px solid "+C.border,borderRadius:6,padding:"4px 10px",fontSize:11,cursor:"pointer",color:C.muted}}>
            👁 Colonnes {Object.values(hiddenLotCols).filter(Boolean).length>0?"("+Object.values(hiddenLotCols).filter(Boolean).length+" masquée·s)":""}
          </button>
          {showColumnsMenu&&(
            <div style={{position:"absolute",top:30,right:0,background:C.card,border:"1px solid "+C.border,borderRadius:8,boxShadow:"0 4px 12px rgba(0,0,0,0.1)",padding:"8px 10px",zIndex:30,minWidth:200}}>
              <div style={{fontSize:11,fontWeight:700,color:C.muted,marginBottom:6}}>Afficher / masquer</div>
              {LOT_COL_TOGGLES.map(c=>(
                <label key={c.key} style={{display:"flex",alignItems:"center",gap:6,padding:"3px 0",fontSize:12,cursor:"pointer"}}>
                  <input type="checkbox" checked={!hiddenLotCols[c.key]} onChange={()=>toggleLotCol(c.key)}/>
                  <span>{c.label}</span>
                </label>
              ))}
              <div style={{textAlign:"right",marginTop:6}}>
                <button onClick={()=>setShowColumnsMenu(false)} style={{background:"none",border:"none",color:C.accent,fontSize:11,cursor:"pointer"}}>Fermer</button>
              </div>
            </div>
          )}
        </div>
        <div style={{overflowX:"auto"}}>
          <table style={{borderCollapse:"collapse",width:"100%",fontSize:12}}>
            <thead><tr style={{background:"#f1f5f9"}}>
              {[
                {k:"_idx",label:""},
                {k:"_surface",label:"Surface"},
                {k:"_ext",label:"Ext"},
                {k:"_type",label:"Type"},
                {k:"_etage",label:"Étage"},
                {k:"loyerPinel",label:"Loyer Pinel"},
                {k:"prixBrut",label:"Prix brut"},
                {k:"ponderation",label:"Pondérat. (%)"},
                {k:"prixPondere",label:"Prix pondéré"},
                {k:"_prixFinal",label:"Prix final"},
                {k:"_pm",label:"Prix m²"},
                {k:"foncier",label:"Foncier"},
                {k:"travaux",label:"Travaux"},
                {k:"_prixReel",label:"Prix réel"},
                {k:"foncierReel",label:"Foncier réel"},
                {k:"travauxReel",label:"Travaux réels"},
                {k:"retroPct",label:"% Rétro réel"},
                {k:"retroMontant",label:"Montant rétro réel"},
                {k:"_client",label:"Client"},
                {k:"_cgp",label:"CGP"},
                {k:"_statut",label:"Statut"},
                {k:"_flux",label:""},
                {k:"_del",label:""},
              ].filter(c=>!hiddenLotCols[c.k]).map((c,i)=>(
                <th key={i} style={{padding:"6px 8px",textAlign:"right",color:C.muted,fontWeight:600,whiteSpace:"nowrap"}}>{c.label}</th>
              ))}
            </tr></thead>
            <tbody>
              {lots.map((lot,idx)=>{
                const lc=lotsCalc[idx]||{prixBrutCalc:0,ponderPct:0,prixPondere:0,prixFinalCalc:0,prixFinal:0,pm:0,foncier:0,travaux:0};
                const li={background:"#f8fafc",border:"1px solid "+C.border,borderRadius:6,color:C.text,padding:"4px 6px",fontSize:12,width:"100%",textAlign:"right"};
                const liWarn={...li,background:"#fef9c3",borderColor:"#f59e0b",color:"#92400e"};
                const liReadOnly={...li,background:"#e2e8f0",color:"#94a3b8",cursor:"not-allowed"};
                const surfaceManquante=toN(lot.surface)===0&&lot.prixBrutO==="";
                const canEditReel=true; // Toujours éditable — prix réel connu dès la négociation, utilisé pour la LIA au passage OPTION
                const retroPctVal=toN(lot.retroPctR);
                const prixReelVal=toN(lot.prixReel);
                const retroMontantVal=prixReelVal*retroPctVal/100;
                // Comparaison prix réel vs total ligne du lot dans le plan hebdo
                const lotPlanRow=(rows||[]).find(r=>r.projetId===proj.id&&r.label===`Lot ${idx+1}`);
                const planHebdoTotal=lotPlanRow?(values||[]).filter(v=>v.rowId===lotPlanRow.id).reduce((s,v)=>s+Number(v.montant),0):null;
                const prixReelVsPlan=prixReelVal>0&&planHebdoTotal!==null&&planHebdoTotal>0
                  ?(Math.abs(prixReelVal-planHebdoTotal)<=100?'ok':'diff'):null;
                // Mettre à jour automatiquement le montant de rétrocession calculé si prix/taux change
                const onChangePrixReel=(v)=>{
                  const nv={...lot,prixReel:v};
                  const pr=toN(v), pct=toN(lot.retroPctR);
                  if(pr>0&&pct>0) nv.retroMontantR=String(Math.round(pr*pct/100));
                  onUpdate("lots",lots.map((l,i)=>i===idx?nv:l));
                };
                const onChangeRetroPct=(v)=>{
                  const nv={...lot,retroPctR:v};
                  const pr=toN(lot.prixReel), pct=toN(v);
                  if(pr>0&&pct>0) nv.retroMontantR=String(Math.round(pr*pct/100));
                  onUpdate("lots",lots.map((l,i)=>i===idx?nv:l));
                };
                // Options pour dropdown clients et CGPs du CRM
                const crmClients=(crm?.clients||[]);
                const crmCgps=(crm?.cgps||[]);
                return (
                  <tr key={idx} style={{borderBottom:"1px solid "+C.border}}>
                    <td style={{padding:"4px 6px",fontSize:11,whiteSpace:"nowrap",color:C.muted}}>Lot {idx+1}</td>
                    {["surface","ext","type","etage"].map(f=>(
                      <td key={f} style={{padding:"3px 4px"}}>
                        <input value={lot[f]||""} onChange={e=>updateLot(idx,f,e.target.value)}
                          style={f==="surface"&&surfaceManquante?liWarn:li}/>
                      </td>
                    ))}
                    {!hiddenLotCols.loyerPinel&&(
                    <td style={{padding:"3px 4px"}}>
                      {toN(fiche.plafondPinel)>0&&!lot.loyerPinel?(
                        <div style={{...COUT_CALC,padding:"4px 6px",fontSize:12,minWidth:80,textAlign:"right",cursor:"pointer",display:"flex",alignItems:"center",gap:2}}
                          title={"Pinel calculé : "+fiche.plafondPinel+"€/m² × surface utile × coef. Cliquer pour saisir manuellement."}
                          onClick={()=>updateLot(idx,"loyerPinel",String(lc.loyerPinelCalc))}>
                          <span style={{flex:1}}>{lc.loyerPinelCalc>0?fmtEur(lc.loyerPinelCalc):"—"}</span>
                          <span style={{fontSize:10,color:"#94a3b8"}}>✎</span>
                        </div>
                      ):(
                        <input value={lot.loyerPinel||""} onChange={e=>updateLot(idx,"loyerPinel",e.target.value)}
                          style={toN(fiche.plafondPinel)>0&&lot.loyerPinel?{...liWarn}:li}
                          title={toN(fiche.plafondPinel)>0&&lot.loyerPinel?"Valeur manuelle (calculée automatiquement si effacée)":""}/>
                      )}
                    </td>
                    )}
                    {!hiddenLotCols.prixBrut&&(
                    <td style={{padding:"3px 4px"}}>
                      <OverrideCell calcVal={lc.prixBrutCalc} overrideVal={lot.prixBrutO} onSet={v=>updateLot(idx,"prixBrutO",v)} onClear={()=>updateLot(idx,"prixBrutO","")}/>
                    </td>
                    )}
                    {!hiddenLotCols.ponderation&&(
                    <td style={{padding:"3px 4px"}}>
                      <input value={lot.ponderationPct||""} onChange={e=>updateLot(idx,"ponderationPct",e.target.value)}
                        placeholder="0" style={{...li,width:62,textAlign:"right"}}/>
                    </td>
                    )}
                    {!hiddenLotCols.prixPondere&&(
                    <td style={{padding:"3px 8px",textAlign:"right"}}>
                      <div style={{...FICHE_CALC,padding:"4px 6px",fontSize:12,borderColor:"#c7d2fe",color:"#4338ca"}}>
                        {lc.prixPondere>0?fmtEur(lc.prixPondere):"—"}
                      </div>
                    </td>
                    )}
                    <td style={{padding:"3px 4px"}}>
                      <OverrideCell calcVal={lc.prixFinalCalc} overrideVal={lot.prixFinalO} onSet={v=>updateLot(idx,"prixFinalO",v)} onClear={()=>updateLot(idx,"prixFinalO","")}/>
                    </td>
                    <td style={{padding:"3px 8px",textAlign:"right"}}><div style={{...FICHE_CALC,padding:"4px 6px",fontSize:12}}>{lc.pm>0?fmtEur(lc.pm):"—"}</div></td>
                    {!hiddenLotCols.foncier&&(
                    <td style={{padding:"3px 8px",textAlign:"right"}}><div style={{...FICHE_CALC,padding:"4px 6px",fontSize:12,borderColor:"#bbf7d0",color:"#15803d"}}>{lc.foncier>0?fmtEur(lc.foncier):"—"}</div></td>
                    )}
                    {!hiddenLotCols.travaux&&(
                    <td style={{padding:"3px 8px",textAlign:"right"}}><div style={{...FICHE_CALC,padding:"4px 6px",fontSize:12,borderColor:"#fde68a",color:"#b45309"}}>{lc.travaux>0?fmtEur(lc.travaux):"—"}</div></td>
                    )}
                    <td style={{padding:"3px 4px"}}>
                      {(()=>{
                        const prTitle=!prixReelVal?(canEditReel?"Saisir le prix réel de vente":"Disponible dès qu'une option est posée"):!lotPlanRow?`Aucune ligne plan hebdo pour Lot ${idx+1}`:planHebdoTotal===0?`Ligne plan hebdo trouvée mais total = 0 €`:prixReelVsPlan==='ok'?`✓ Cohérent avec le plan hebdo : ${fmtEur(planHebdoTotal)}`:`⚠️ Plan hebdo : ${fmtEur(planHebdoTotal)} (écart : ${fmtEur(Math.abs(prixReelVal-planHebdoTotal))})`;
                        const prStyle=!canEditReel?{...liReadOnly,width:88}:prixReelVsPlan==='ok'?{...li,width:88,border:"1px solid #16a34a",background:"#f0fdf4",color:"#15803d"}:prixReelVsPlan==='diff'?{...li,width:88,border:"1px solid #dc2626",background:"#fef2f2",color:"#dc2626"}:{...li,width:88};
                        return <input
                          value={lot.prixReel||""}
                          onChange={e=>canEditReel&&onChangePrixReel(e.target.value)}
                          disabled={!canEditReel}
                          title={prTitle}
                          className={prixReelVsPlan==='ok'?'prix-reel-ok':prixReelVsPlan==='diff'?'prix-reel-diff':''}
                          style={prStyle}/>;
                      })()}
                    </td>
                    {!hiddenLotCols.foncierReel&&(
                    <td style={{padding:"3px 4px",textAlign:"right"}}>
                      {prixReelVal>0?(
                        <OverrideCell
                          calcVal={lc.foncierReelCalc}
                          overrideVal={lot.foncierReelO}
                          onSet={v=>updateLot(idx,"foncierReelO",v)}
                          onClear={()=>{
                            onUpdate("lots",lots.map((l,i)=>i===idx?{...l,foncierReelO:""}:l));
                          }}/>
                      ):(
                        <div style={{...FICHE_CALC,padding:"4px 6px",fontSize:12,borderColor:"#bbf7d0",color:"#15803d",opacity:0.4,textAlign:"right"}}>—</div>
                      )}
                    </td>
                    )}
                    {!hiddenLotCols.travauxReel&&(
                    <td style={{padding:"3px 8px",textAlign:"right"}}><div style={{...FICHE_CALC,padding:"4px 6px",fontSize:12,borderColor:"#fde68a",color:"#b45309",opacity:lc.travauxReel>0?1:0.4}}>{lc.travauxReel>0?fmtEur(lc.travauxReel):"—"}</div></td>
                    )}
                    {!hiddenLotCols.retroPct&&(
                    <td style={{padding:"3px 4px"}}>
                      <input
                        value={lot.retroPctR||""}
                        onChange={e=>canEditReel&&onChangeRetroPct(e.target.value)}
                        disabled={!canEditReel}
                        placeholder="%"
                        title={canEditReel?"Taux de rétrocession réel appliqué au prix réel":"Disponible dès qu'une option est posée"}
                        style={canEditReel?{...li,width:60}:{...liReadOnly,width:60}}/>
                    </td>
                    )}
                    {!hiddenLotCols.retroMontant&&(
                    <td style={{padding:"3px 8px",textAlign:"right"}}>
                      <div style={{...FICHE_CALC,padding:"4px 6px",fontSize:12,borderColor:"#fecaca",color:"#b91c1c"}}>
                        {retroMontantVal>0?fmtEur(retroMontantVal):"—"}
                      </div>
                    </td>
                    )}
                    <td style={{padding:"3px 4px"}}>
                      <select
                        value={lot.clientId||""}
                        onChange={e=>{
                          const cid=e.target.value;
                          const cli=crmClients.find(c=>c.id===cid);
                          const nv={...lot,clientId:cid,clientNom:cli?`${cli.prenom||""} ${cli.nom||""}`.trim():""};
                          // Si le client a un CGP lié et qu'aucun CGP n'est saisi, on le propose
                          if(cli&&cli.cgpId&&!lot.cgpId){
                            const cgp=crmCgps.find(g=>g.id===cli.cgpId);
                            if(cgp){
                              nv.cgpId=cgp.id;
                              nv.cgpNom=(cgp.societe?cgp.societe+" – ":"")+`${cgp.prenom||""} ${cgp.nom||""}`.trim();
                            }
                          }
                          onUpdate("lots",lots.map((l,i)=>i===idx?nv:l));
                        }}
                        style={{...li,width:130,textAlign:"left"}}
                        title="Client (depuis CRM — éditez la fiche client dans l'onglet CRM)">
                        <option value="">— Client —</option>
                        {crmClients.map(c=>(
                          <option key={c.id} value={c.id}>{`${c.prenom||""} ${c.nom||""}`.trim()||"(sans nom)"}</option>
                        ))}
                      </select>
                    </td>
                    <td style={{padding:"3px 4px"}}>
                      <select
                        value={lot.cgpId||""}
                        onChange={e=>{
                          const cid=e.target.value;
                          const cgp=crmCgps.find(g=>g.id===cid);
                          const nv={...lot,cgpId:cid,cgpNom:cgp?((cgp.societe?cgp.societe+" – ":"")+`${cgp.prenom||""} ${cgp.nom||""}`.trim()):""};
                          onUpdate("lots",lots.map((l,i)=>i===idx?nv:l));
                        }}
                        style={{...li,width:140,textAlign:"left"}}
                        title="Gestionnaire / CGP (depuis CRM)">
                        <option value="">— CGP —</option>
                        {crmCgps.map(g=>(
                          <option key={g.id} value={g.id}>{(g.societe?g.societe+" – ":"")+`${g.prenom||""} ${g.nom||""}`.trim()||"(sans nom)"}</option>
                        ))}
                      </select>
                    </td>
                    <td style={{padding:"3px 6px",textAlign:"center"}}>
                      <div style={{display:"flex",flexDirection:"column",alignItems:"center",gap:2}}>
                        <StatutLotBadge statut={lot.statutCommercial||"LIBRE"}/>
                        {(()=>{
                          const pct=appelsFonds[String(idx+1)];
                          if(!pct||pct<=0) return null;
                          const bg=pct>=95?"#dcfce7":pct>=50?"#fef9c3":"#ffedd5";
                          const col=pct>=95?"#15803d":pct>=50?"#b45309":"#c2410c";
                          return <span style={{background:bg,color:col,borderRadius:3,padding:"1px 5px",fontSize:9,fontWeight:700,whiteSpace:"nowrap"}}>AV {pct}%</span>;
                        })()}
                      </div>
                    </td>
                    <td style={{padding:"3px 4px",textAlign:"center"}}>
                      {canEditReel&&toN(lot.prixReel)>0&&(
                        <button onClick={()=>setConfirmReelUpdate({lotIdx:idx})} title="Mettre à jour les flux réels dans le Plan Hebdo" style={{background:"none",border:"none",color:"#0d9488",cursor:"pointer",fontSize:13,padding:"2px 4px"}}>🔄</button>
                      )}
                    </td>
                    <td style={{padding:"3px 6px",textAlign:"center"}}><button onClick={()=>onUpdate("lots",lots.filter((_,i)=>i!==idx))} style={{background:"none",border:"none",color:"#94a3b8",cursor:"pointer",fontSize:12}}>✕</button></td>
                  </tr>
                );
              })}
              {(()=>{
                const colSpan1 = 1 /*type*/ + (!hiddenLotCols.loyerPinel?1:0) + (!hiddenLotCols.prixBrut?1:0) + (!hiddenLotCols.ponderation?1:0) + (!hiddenLotCols.prixPondere?1:0);
                const colSpan2 = 1 /*pm*/ + (!hiddenLotCols.foncier?1:0) + (!hiddenLotCols.travaux?1:0) + (!hiddenLotCols.foncierReel?1:0) + (!hiddenLotCols.travauxReel?1:0) + 1 /*prixReel*/ + (!hiddenLotCols.retroPct?1:0) + (!hiddenLotCols.retroMontant?1:0) + 1 /*client*/ + 1 /*cgp*/ + 1 /*statut*/ + 1 /*flux*/ + 1 /*del*/;
                return (
                  <tr style={{background:"#f1f5f9",fontWeight:700}}>
                    <td style={{padding:"6px 8px",color:C.muted,fontSize:11}}>Total</td>
                    <td style={{padding:"6px 8px",textAlign:"right",color:C.text}}>{lots.reduce((s,l)=>s+toN(l.surface),0)||""}</td>
                    <td style={{padding:"6px 8px",textAlign:"right",color:C.text}}>{lots.reduce((s,l)=>s+toN(l.ext),0)||""}</td>
                    <td colSpan={colSpan1}></td>
                    <td style={{padding:"6px 8px",textAlign:"right",color:C.green,fontSize:14}}>{fmtEur(lotsTotal)}</td>
                    <td colSpan={colSpan2}></td>
                  </tr>
                );
              })()}
            </tbody>
          </table>
        </div>
        <button onClick={()=>onUpdate("lots",[...lots,EMPTY_LOT()])}
          style={{marginTop:10,background:"none",border:"1px dashed #334155",borderRadius:6,color:C.muted,fontSize:11,padding:"4px 14px",cursor:"pointer"}}>
          + Ajouter un lot
        </button>
        {confirmReelUpdate!==null&&(() => {
          const lIdx=confirmReelUpdate.lotIdx;
          const l=lots[lIdx]||{};
          const lcCur=lotsCalc[lIdx]||{};
          const pr=toN(l.prixReel);
          const rm=toN(l.retroMontantR);
          const pct=toN(l.retroPctR);
          const fonReel=lcCur.foncierReel||0;
          const travReel=lcCur.travauxReel||0;
          const fonForce=l.foncierReelO!==""&&l.foncierReelO!=null;
          const hasRetro=pct>0;
          return (
            <div style={{position:"fixed",inset:0,background:"#000c",display:"flex",alignItems:"center",justifyContent:"center",zIndex:60}}>
              <div style={{background:C.card,borderRadius:12,border:"1px solid "+C.border,padding:24,width:440}}>
                <div style={{fontWeight:700,fontSize:15,marginBottom:8,color:C.text}}>Mettre à jour les flux ?</div>
                <div style={{fontSize:12,color:C.muted,marginBottom:12}}>
                  Valeurs actuelles du <b>Lot {lIdx+1}</b> :<br/>
                  Prix réel : <b style={{color:C.text}}>{fmtEur(pr)}</b><br/>
                  Foncier réel : <b style={{color:C.text}}>{fmtEur(fonReel)}</b> {fonForce?<span style={{color:"#b45309",fontWeight:600}}>(forcé)</span>:<span style={{color:C.muted}}>(calculé)</span>}<br/>
                  Travaux réels : <b style={{color:C.text}}>{fmtEur(travReel)}</b>
                  {hasRetro&&<><br/>Taux rétro : <b style={{color:C.text}}>{pct.toFixed(2)} %</b> · Rétro réelle : <b style={{color:C.text}}>{fmtEur(rm)}</b></>}
                </div>
                <div style={{fontSize:12,color:C.muted,marginBottom:14}}>
                  Voulez-vous recalculer les flux <b>Lot {lIdx+1}</b> (foncier + travaux){hasRetro&&<> et la <b>Marge CGP</b> du programme</>} avec ces valeurs ?<br/>
                  <span style={{color:"#2563eb"}}>ℹ️ Les flux resteront en statut <b>F</b> (Forecast) tant que le lot n&apos;est pas en statut <b>Vendu</b>. Ils passent en <b>R</b> (Réel) au passage en Vendu.</span>
                </div>
                <div style={{display:"flex",gap:8,justifyContent:"flex-end"}}>
                  <button onClick={()=>setConfirmReelUpdate(null)} style={{background:"#e2e8f0",border:"none",borderRadius:6,color:C.text,padding:"6px 14px",fontSize:12,cursor:"pointer"}}>Annuler</button>
                  <button onClick={()=>{
                    if(onUpdateLotReelFlows) onUpdateLotReelFlows(lIdx);
                    setConfirmReelUpdate(null);
                  }} style={{background:C.accent,border:"none",borderRadius:6,color:"#fff",padding:"6px 14px",fontSize:12,cursor:"pointer",fontWeight:600}}>Confirmer</button>
                </div>
              </div>
            </div>
          );
        })()}
      </FicheSection>

      <FicheSection title="📝 Notes" color={C.muted}>
        <textarea value={fiche.notes||""} onChange={e=>onUpdate("notes",e.target.value)}
          style={{background:"#f8fafc",border:"1px solid "+C.border,borderRadius:8,color:C.text,padding:"8px 12px",fontSize:13,width:"100%",height:80,resize:"vertical"}}/>
      </FicheSection>
    </div>
  );
}
