/* ── NotificationsView : onglet Notifications & Actions ── */
function NotificationsView({notifications,setNotifications,notifLoading,setNotifLoading,notifError,setNotifError,notifFilterBal,setNotifFilterBal,notifFilterCat,setNotifFilterCat,notifShowAll,setNotifShowAll,notifPdfModal,setNotifPdfModal,analyzingIds,setAnalyzingIds,editingFacture,setEditingFacture,reglerModal,setReglerModal,agentRunning,setAgentRunning,loadNotifs,fiches,projects,rows,values,handleCellSave,logMouvementAuto,crm}) {
  const inp={background:"#f8fafc",border:"1px solid #cbd5e1",borderRadius:8,color:"#1e293b",padding:"8px 12px",fontSize:13,width:"100%"};
  const btnS=(bg,sm)=>({background:bg||"#2563eb",color:"#fff",border:"none",borderRadius:7,padding:sm?"4px 10px":"8px 16px",cursor:"pointer",fontSize:sm?11:13,fontWeight:600});

  const CAT_COLORS={
    facture:               {bg:"#dbeafe",color:"#1d4ed8"},
    notaire:               {bg:"#f3e8ff",color:"#7c3aed"},
    architecte:            {bg:"#d1fae5",color:"#065f46"},
    lia_retour:            {bg:"#e0f2fe",color:"#0369a1"},
    eg_appel_fonds:        {bg:"#fef3c7",color:"#b45309"},
    architecte_attestation:{bg:"#ecfdf5",color:"#047857"},
    diagnostic:            {bg:"#fae8ff",color:"#a21caf"},
    autre:                 {bg:"#f1f5f9",color:"#64748b"},
  };
  const FACTURE_STATUS_CONFIG={
    "reçue":    {bg:"#dbeafe",color:"#1d4ed8",label:"Reçue"},
    "confirmée":{bg:"#dcfce7",color:"#15803d",label:"Confirmée"},
    "réglée":   {bg:"#f1f5f9",color:"#64748b",label:"Réglée ✓"},
    "refusée":  {bg:"#fee2e2",color:"#dc2626",label:"Refusée"},
  };
  const relTime=(iso)=>{
    const d=Date.now()-new Date(iso).getTime();
    if(d<60000) return "à l'instant";
    if(d<3600000) return `il y a ${Math.round(d/60000)} min`;
    if(d<86400000) return `il y a ${Math.round(d/3600000)} h`;
    return `il y a ${Math.round(d/86400000)} j`;
  };

  // Séparation factures / autres
  // F : les appels de fonds EG et les attestations archi se pilotent désormais
  // dans l'onglet « Appels de fonds » (zone « à vérifier ») → ils n'apparaissent
  // plus dans Notifications. La facture à régler l'EG (category="facture") y reste.
  const EG_PILOTE_AILLEURS=["eg_appel_fonds","architecte_attestation"];
  const filteredByBal=notifications.filter(n=>notifFilterBal==="all"||n.mailbox===notifFilterBal);
  const factures=filteredByBal.filter(n=>n.category==="facture");
  const autres=filteredByBal.filter(n=>n.category!=="facture"&&!EG_PILOTE_AILLEURS.includes(n.category)&&(notifFilterCat==="all"||n.category===notifFilterCat));

  // Factures visibles selon l'état du filtre
  const facturesVisible=notifShowAll
    ? factures
    : factures.filter(n=>!["réglée","refusée"].includes(n.facture_status)&&n.status!=="dismissed");

  // Autres notifs visibles
  const autresVisible=notifShowAll
    ? autres
    : autres.filter(n=>n.status==="new");

  const analyzeFacture=async(notifId)=>{
    setAnalyzingIds(s=>({...s,[notifId]:true}));
    try{
      const r=await window.apiFetch("/api/agent/notifications/"+notifId+"/read-invoice",{method:"POST"});
      const d=await r.json();
      if(d.error) alert("Erreur analyse : "+d.error);
      else loadNotifs(notifShowAll);
    }catch(e){ alert("Erreur réseau : "+e.message); }
    finally{ setAnalyzingIds(s=>({...s,[notifId]:false})); }
  };

  const patchFactureStatus=async(notifId,status)=>{
    await window.apiFetch("/api/agent/notifications/"+notifId+"/facture",{
      method:"PATCH",headers:{"Content-Type":"application/json"},
      body:JSON.stringify({facture_status:status})
    }).catch(()=>{});
    loadNotifs(notifShowAll);
  };

  const saveFactureData=async(notifId,data)=>{
    await window.apiFetch("/api/agent/notifications/"+notifId+"/facture",{
      method:"PATCH",headers:{"Content-Type":"application/json"},
      body:JSON.stringify({facture_data:data,facture_status:"confirmée"})
    }).catch(()=>{});
    /* ── Envoi email GFA si prévalidation activée ── */
    try {
      const notif=notifications.find(n=>n.id===notifId);
      const programmeId=notif?.proposed_action?.programmeId||notif?.proposed_action?.params?.programmeId;
      const ficheProg=programmeId?fiches[programmeId]:null;
      if(ficheProg?.prevalidationGFA && ficheProg?.gfaEmailContact) {
        const gfaEmail=ficheProg.gfaEmailContact;
        /* Récupérer le PDF en base64 */
        let attachmentPayload=null;
        try {
          const pdfResp=await window.apiFetch("/api/agent/notifications/"+notifId+"/attachment");
          if(pdfResp.ok){
            const blob=await pdfResp.blob();
            const base64=await new Promise(resolve=>{
              const reader=new FileReader();
              reader.onloadend=()=>resolve(reader.result.split(",")[1]);
              reader.readAsDataURL(blob);
            });
            let filename="facture.pdf";
            try{const ref=JSON.parse(notif.attachment_ref||"{}");filename=ref.filename||filename;}catch(_){}
            attachmentPayload={filename,contentType:"application/pdf",content:base64};
          }
        } catch(_) {}
        const fournisseur=data.fournisseur||"(fournisseur inconnu)";
        const montant=data.montant_ttc!=null?Number(data.montant_ttc).toLocaleString("fr-FR",{minimumFractionDigits:2,maximumFractionDigits:2}):"?";
        const numFact=data.numero_facture||"";
        const subject="Prévalidation facture — "+fournisseur+" — "+montant+" €";
        const body="Bonjour,\n\nVeuillez trouver ci-joint la facture de "+fournisseur+" d'un montant de "+montant+" € TTC"+(numFact?" (réf. "+numFact+")":"")+` pour prévalidation.\n\nCordialement,\nPierre Rouzaud — TrésoImmo`;
        const emailPayload={to:gfaEmail,subject,body};
        if(attachmentPayload) emailPayload.attachment=attachmentPayload;
        const emailResp=await window.apiFetch("/api/email/send",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(emailPayload)});
        if(emailResp.ok){
          setTimeout(()=>alert("📧 Email GFA envoyé à "+gfaEmail),100);
        } else {
          const errTxt=await emailResp.text().catch(()=>"");
          setTimeout(()=>alert("⚠️ Impossible d'envoyer l'email GFA à "+gfaEmail+".\n"+errTxt),100);
        }
      }
    } catch(e) {
      console.warn("Envoi email GFA échoué (non-bloquant) :", e);
    }
    setEditingFacture(null);
    loadNotifs(notifShowAll);
  };

  const resetFacture=async(notifId)=>{
    if(!confirm("Réinitialiser cette facture à l'état « Non analysée » ?")) return;
    await window.apiFetch("/api/agent/notifications/"+notifId,{
      method:"PATCH",headers:{"Content-Type":"application/json"},
      body:JSON.stringify({action:"reset_facture"})
    }).catch(()=>{});
    loadNotifs(notifShowAll);
  };

  const executeNotifAction=async(notifId,actionType,pathOverride)=>{
    try{
      const body={action_type:actionType,confirmed:true};
      if(pathOverride) body.oneDrivePath=pathOverride;
      const r=await window.apiFetch("/api/agent/notifications/"+notifId+"/execute",{
        method:"POST",headers:{"Content-Type":"application/json"},
        body:JSON.stringify(body)
      });
      const d=await r.json();
      if(d.error){ alert("Erreur exécution : "+d.error); return false; }
      loadNotifs(notifShowAll);
      return true;
    }catch(e){ alert("Erreur réseau : "+e.message); return false; }
  };

  // ── Re-classification / forçage manuel ───────────────────────────────────
  const [reclassifyingIds,setReclassifyingIds]=React.useState({});
  // forceCatState : { [notifId]: selectedCategory }
  const [forceCatState,setForceCatState]=React.useState({});
  const [forcingIds,setForcingIds]=React.useState({});

  const ALL_CATS=['facture','eg_appel_fonds','notaire','architecte',
                  'architecte_attestation','lia_retour','diagnostic','autre'];

  const reclassify=async(notifId)=>{
    setReclassifyingIds(s=>({...s,[notifId]:true}));
    try{
      const r=await window.apiFetch("/api/agent/notifications/"+notifId+"/reclassify",{method:"POST"});
      const d=await r.json();
      if(d.error) alert("Erreur re-classification : "+d.error);
      else {
        const msg=d.new_category===d.old_category
          ?"Résultat inchangé : "+d.new_category+" ("+d.confidence+")"
          :"✓ Re-classifié : "+d.old_category+" → "+d.new_category+" ("+d.confidence+")";
        alert(msg);
        loadNotifs(notifShowAll);
      }
    }catch(e){alert("Erreur réseau : "+e.message);}
    setReclassifyingIds(s=>({...s,[notifId]:false}));
  };

  const forceCategory=async(notifId)=>{
    const cat=forceCatState[notifId];
    if(!cat){alert("Sélectionnez d'abord une catégorie.");return;}
    setForcingIds(s=>({...s,[notifId]:true}));
    try{
      const r=await window.apiFetch("/api/agent/notifications/"+notifId,{
        method:"PATCH",headers:{"Content-Type":"application/json"},
        body:JSON.stringify({action:"force_category",category:cat})
      });
      const d=await r.json();
      if(d.error) alert("Erreur : "+d.error);
      else{ loadNotifs(notifShowAll); setForceCatState(s=>({...s,[notifId]:undefined})); }
    }catch(e){alert("Erreur réseau : "+e.message);}
    setForcingIds(s=>({...s,[notifId]:false}));
  };

  // État de l'éditeur inline de chemin OneDrive (un seul ouvert à la fois)
  // { notifId, actionType, folder, file, programmeRoot,
  //   checking, checkResult, browserOpen, browserPath, browserData }
  const [archiveInline,setArchiveInline]=React.useState(null);

  // ── Modale « ranger les diagnostics » (envoi diagnostiqueur, multi-PJ) ───────
  const [diagModalNotif,setDiagModalNotif]=React.useState(null);

  // ── Modale LIA incomplète ──────────────────────────────────────────────────
  // { notifId, loading, emailData: { to, cc, subject, body, attachment, hasAttachment } }
  const [incompleteLiaModal,setIncompleteLiaModal]=React.useState(null);

  const openIncompleteLiaModal=async(notifId)=>{
    setIncompleteLiaModal({notifId,loading:true,emailData:null});
    try{
      const r=await window.apiFetch("/api/agent/notifications/"+notifId+"/execute",{
        method:"POST",headers:{"Content-Type":"application/json"},
        body:JSON.stringify({action_type:"send_incomplete_lia_email",confirmed:true})
      });
      const d=await r.json();
      if(d.error){alert("Erreur préparation email : "+d.error);setIncompleteLiaModal(null);return;}
      setIncompleteLiaModal({notifId,loading:false,emailData:d.emailData});
    }catch(e){alert("Erreur réseau : "+e.message);setIncompleteLiaModal(null);}
  };

  /* ── Ouvre l'éditeur inline pour une notification ── */
  const openArchiveInline=async(notifId,action,actionType)=>{
    const fp=action?.params?.oneDrivePath||'';
    const last=fp.lastIndexOf('\\');
    const folder=last>=0?fp.slice(0,last):'';
    const file=last>=0?fp.slice(last+1):fp;
    const segs=fp.replace(/\\/g,'/').split('/').filter(Boolean);
    const programmeRoot=segs.length>=4?'\\'+segs.slice(0,4).join('\\'):fp;
    setArchiveInline({notifId,actionType,folder,file,programmeRoot,
      checking:true,checkResult:null,browserOpen:false,browserPath:'',browserData:null});
    try{
      const r=await window.apiFetch('/api/agent/onedrive/browse?path='+encodeURIComponent(folder));
      const d=await r.json();
      setArchiveInline(p=>p?.notifId===notifId?{...p,checking:false,checkResult:d}:p);
    }catch(e){
      setArchiveInline(p=>p?.notifId===notifId?{...p,checking:false,checkResult:{exists:false,folders:[],error:e.message}}:p);
    }
  };

  /* ── Vérifie / re-vérifie le chemin courant ── */
  const recheckArchiveFolder=async(path)=>{
    if(!path)return;
    setArchiveInline(p=>p?{...p,checking:true,checkResult:null}:p);
    try{
      const r=await window.apiFetch('/api/agent/onedrive/browse?path='+encodeURIComponent(path));
      const d=await r.json();
      setArchiveInline(p=>p?{...p,checking:false,checkResult:d}:p);
    }catch(e){
      setArchiveInline(p=>p?{...p,checking:false,checkResult:{exists:false,folders:[],error:e.message}}:p);
    }
  };

  /* ── Navigue dans un dossier OneDrive ── */
  const loadArchiveBrowser=async(path)=>{
    setArchiveInline(p=>p?{...p,browserOpen:true,browserPath:path,browserData:{folders:[],loading:true}}:p);
    try{
      const r=await window.apiFetch('/api/agent/onedrive/browse?path='+encodeURIComponent(path));
      const d=await r.json();
      setArchiveInline(p=>p?{...p,browserData:{folders:d.folders||[],loading:false}}:p);
    }catch(e){
      setArchiveInline(p=>p?{...p,browserData:{folders:[],loading:false,error:e.message}}:p);
    }
  };

  /* ── Sélectionne un dossier depuis le navigateur ── */
  const selectArchiveBrowserFolder=async()=>{
    const selectedPath=archiveInline?.browserPath;
    if(!selectedPath)return;
    setArchiveInline(p=>p?{...p,folder:selectedPath,browserOpen:false,checkResult:null,checking:true}:p);
    try{
      const r=await window.apiFetch('/api/agent/onedrive/browse?path='+encodeURIComponent(selectedPath));
      const d=await r.json();
      setArchiveInline(p=>p?{...p,checking:false,checkResult:d}:p);
    }catch(e){
      setArchiveInline(p=>p?{...p,checking:false,checkResult:{exists:false,folders:[],error:e.message}}:p);
    }
  };

  return (
  <div style={{padding:24,maxWidth:860,margin:"0 auto"}}>

    {/* ── Header + filtres ── */}
    <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:20,flexWrap:"wrap",gap:8}}>
      <div style={{fontWeight:800,fontSize:18}}>🔔 Notifications & Actions</div>
      <div style={{display:"flex",gap:6,flexWrap:"wrap",alignItems:"center"}}>
        {/* Bouton refresh : déclenche un run de l'agent (nouveaux emails depuis
            le dernier curseur de scan) puis recharge les notifications après un
            délai. Le verrou PID de l'agent évite les exécutions concurrentes. */}
        <button
          onClick={async()=>{
            if(notifLoading||agentRunning) return;
            setAgentRunning(true);
            try{
              const r=await window.apiFetch("/api/agent/trigger",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({resetCursor:false})});
              const d=await r.json();
              if(!r.ok||d.error){
                alert("Erreur déclenchement agent : "+(d.error||r.status));
                loadNotifs(notifShowAll);
              }else{
                // Recharge auto une première fois rapidement (notifs déjà en DB)
                // puis une seconde fois après que le scan a eu le temps de finir.
                setTimeout(()=>loadNotifs(notifShowAll),2000);
                setTimeout(()=>loadNotifs(notifShowAll),10000);
              }
            }catch(e){
              alert("Erreur réseau : "+e.message);
              loadNotifs(notifShowAll);
            }
            finally{setTimeout(()=>setAgentRunning(false),11000);}
          }}
          disabled={notifLoading||agentRunning}
          title="Actualiser et scanner les nouveaux emails"
          style={{background:"none",border:"1px solid "+C.border,borderRadius:6,padding:"4px 9px",fontSize:13,cursor:(notifLoading||agentRunning)?"default":"pointer",color:C.muted,lineHeight:1}}>
          {agentRunning?"⏳":"🔄"}
        </button>
        <button onClick={()=>setNotifShowAll(v=>!v)} style={btnS(notifShowAll?"#334155":"#2563eb",true)}>
          {notifShowAll?"Actives uniquement":"Tout afficher (archivées)"}
        </button>
        <select value={notifFilterBal} onChange={e=>setNotifFilterBal(e.target.value)}
          style={{...inp,width:"auto",fontSize:12,padding:"4px 8px"}}>
          <option value="all">Toutes les BAL</option>
          {[...new Set(notifications.map(n=>n.mailbox))].map(m=><option key={m} value={m}>{m}</option>)}
        </select>
      </div>
    </div>

    {notifError&&<div style={{background:"#fee2e2",border:"1px solid #fca5a5",borderRadius:8,padding:"10px 14px",marginBottom:16,fontSize:12,color:"#dc2626"}}>⚠️ Impossible de charger les notifications : {notifError}</div>}
    {notifLoading&&<div style={{textAlign:"center",color:C.muted,padding:40}}>Chargement…</div>}

    {!notifLoading&&(
    <>
      {/* ══ SECTION FACTURES ══ */}
      <div style={{marginBottom:28}}>
        <div style={{display:"flex",alignItems:"center",gap:10,marginBottom:12}}>
          <div style={{fontWeight:700,fontSize:15}}>🧾 Factures</div>
          {factures.filter(n=>n.facture_status==="confirmée").length>0&&(
            <span style={{background:"#fef3c7",color:"#b45309",borderRadius:10,padding:"1px 8px",fontSize:11,fontWeight:700}}>
              {factures.filter(n=>n.facture_status==="confirmée").length} à régler
            </span>
          )}
          {factures.filter(n=>!n.facture_data&&n.status!=="dismissed").length>0&&(
            <span style={{background:"#dbeafe",color:"#1d4ed8",borderRadius:10,padding:"1px 8px",fontSize:11,fontWeight:700}}>
              {factures.filter(n=>!n.facture_data&&n.status!=="dismissed").length} à analyser
            </span>
          )}
        </div>

        {facturesVisible.length===0&&(
          <div style={{background:C.card,borderRadius:10,border:"1px dashed "+C.border,padding:24,textAlign:"center",color:C.muted,fontSize:13}}>
            {notifShowAll?"Aucune facture reçue.":"Aucune facture en attente de traitement. 🎉"}
          </div>
        )}

        {facturesVisible.map(notif=>{
          let ref=null;
          try{if(notif.attachment_ref)ref=JSON.parse(notif.attachment_ref);}catch(e){}
          const fdRaw=notif.facture_data;
          // Normalise : l'ancien format est un objet, le nouveau un tableau
          const fdArray=Array.isArray(fdRaw)?fdRaw:(fdRaw?[fdRaw]:[]);
          const fd=fdArray[0]||null;
          const isMultiFacture=fdArray.length>1;
          const fs=notif.facture_status;
          const fsCfg=FACTURE_STATUS_CONFIG[fs]||null;
          const pdfTmp=notif.pdf_tmp_path;
          const pdfOd=notif.pdf_onedrive_url;
          const isArchived=["réglée","refusée"].includes(fs)||notif.status==="dismissed";
          const isEditing=editingFacture?.id===notif.id;

          return (
            <div key={notif.id} style={{background:C.card,borderRadius:10,border:"1px solid "+(isArchived?"#e2e8f0":C.border),padding:16,marginBottom:10,opacity:isArchived?0.65:1}}>
              <div style={{display:"flex",alignItems:"center",gap:6,marginBottom:8,flexWrap:"wrap"}}>
                <span style={{background:"#dbeafe",color:"#1d4ed8",borderRadius:4,padding:"2px 8px",fontSize:11,fontWeight:700}}>FACTURE</span>
                {fsCfg&&<span style={{background:fsCfg.bg,color:fsCfg.color,borderRadius:4,padding:"2px 8px",fontSize:11,fontWeight:700}}>{fsCfg.label}</span>}
                {!fs&&!fd&&<span style={{background:"#fef9c3",color:"#92400e",borderRadius:4,padding:"2px 8px",fontSize:11,fontWeight:600}}>Non analysée</span>}
                {isMultiFacture&&<span style={{background:"#ede9fe",color:"#7c3aed",borderRadius:4,padding:"2px 8px",fontSize:11,fontWeight:700}}>{fdArray.length} factures</span>}
                <span style={{fontSize:11,color:C.muted,marginLeft:"auto"}}>{relTime(notif.received_at)}</span>
              </div>
              <div style={{fontSize:12,color:C.muted,marginBottom:2}}>De : {notif.from_name||""} {"<"+(notif.from_email||"")+">"}</div>
              {notif.to_recipients&&<div style={{fontSize:12,color:C.muted,marginBottom:2}}>À : {notif.to_recipients}</div>}
              {notif.cc_recipients&&<div style={{fontSize:12,color:C.muted,marginBottom:2}}>Cc : {notif.cc_recipients}</div>}
              <div style={{fontWeight:600,fontSize:13,marginBottom:8,color:C.text}}>{notif.subject}</div>
              {ref&&(
                <div style={{display:"flex",alignItems:"center",gap:8,marginBottom:6,background:"#f8fafc",borderRadius:6,padding:"5px 10px"}}>
                  <span style={{fontSize:12}}>📎 {ref.filename||"document.pdf"}</span>
                  {ref.size&&<span style={{fontSize:11,color:C.muted}}>({Math.round(ref.size/1024)} Ko)</span>}
                  <button onClick={()=>setNotifPdfModal(notif.id)} style={btnS("#334155",true)}>aperçu PDF</button>
                </div>
              )}
              {(pdfTmp||pdfOd)&&(
                <div style={{display:"inline-flex",alignItems:"center",gap:6,marginBottom:10,padding:"3px 10px",borderRadius:6,
                  background:pdfOd?"#f0fdf4":"#eff6ff",
                  border:"1px solid "+(pdfOd?"#bbf7d0":"#bfdbfe"),
                  fontSize:11,color:pdfOd?"#15803d":"#1d4ed8",fontWeight:600}}>
                  {pdfOd
                    ? <>☁️ Archivé OneDrive&nbsp;
                        <a href={pdfOd} target="_blank" rel="noopener noreferrer"
                          style={{color:"#15803d",textDecoration:"underline",fontWeight:700}}>ouvrir ↗</a>
                      </>
                    : <>📎 PDF sauvegardé localement</>
                  }
                </div>
              )}
              {fdArray.length>0&&!isEditing&&fdArray.map((facture,fi)=>(
                <div key={fi} style={{background:"#f0fdf4",border:"1px solid #bbf7d0",borderRadius:8,padding:12,marginBottom:isMultiFacture?6:10}}>
                  {isMultiFacture&&(
                    <div style={{display:"flex",alignItems:"center",justifyContent:"space-between",marginBottom:8}}>
                      <span style={{fontSize:11,fontWeight:700,color:"#7c3aed"}}>Facture {fi+1}/{fdArray.length}</span>
                      {fs==="confirmée"&&(
                        <button onClick={()=>setReglerModal({...notif,facture_data:facture})}
                          style={{background:"#2563eb",color:"#fff",border:"none",borderRadius:5,padding:"3px 10px",fontSize:11,cursor:"pointer",fontWeight:600}}>
                          💶 Régler cette facture
                        </button>
                      )}
                    </div>
                  )}
                  <div style={{display:"grid",gridTemplateColumns:"auto 1fr auto 1fr",gap:"3px 16px",fontSize:12,alignItems:"start"}}>
                    {facture.fournisseur&&<><span style={{color:"#64748b",fontWeight:600,whiteSpace:"nowrap"}}>Fournisseur</span><span style={{fontWeight:700}}>{facture.fournisseur}</span></>}
                    {facture.numero_facture&&<><span style={{color:"#64748b",fontWeight:600,whiteSpace:"nowrap"}}>N° facture</span><span>{facture.numero_facture}</span></>}
                    {facture.date_facture&&<><span style={{color:"#64748b",fontWeight:600,whiteSpace:"nowrap"}}>Date</span><span>{new Date(facture.date_facture+"T12:00:00Z").toLocaleDateString("fr-FR")}</span></>}
                    {facture.montant_ht!=null&&<><span style={{color:"#64748b",fontWeight:600,whiteSpace:"nowrap"}}>HT</span><span>{fmtEur(facture.montant_ht)}</span></>}
                    {facture.tva!=null&&<><span style={{color:"#64748b",fontWeight:600,whiteSpace:"nowrap"}}>TVA</span><span>{fmtEur(facture.tva)}</span></>}
                    {facture.montant_ttc!=null&&<><span style={{color:"#64748b",fontWeight:600,whiteSpace:"nowrap"}}>Montant TTC</span><span style={{fontWeight:800,color:"#1d4ed8",fontSize:13}}>{fmtEur(facture.montant_ttc)}</span></>}
                    {facture.description&&<><span style={{color:"#64748b",fontWeight:600,whiteSpace:"nowrap",gridColumn:"1"}}>Prestation</span><span style={{fontStyle:"italic",gridColumn:"2/-1",fontSize:11}}>{facture.description}</span></>}
                  </div>
                </div>
              ))}
              {isEditing&&(()=>{
                const ef=editingFacture.data;
                const inp2={width:"100%",padding:"4px 7px",border:"1px solid #e2e8f0",borderRadius:5,fontSize:12,background:"#f8fafc"};
                return (
                  <div style={{background:"#fffbeb",border:"1px solid #fde68a",borderRadius:8,padding:12,marginBottom:10}}>
                    <div style={{fontWeight:700,fontSize:12,color:"#92400e",marginBottom:8}}>✎ Corriger les données</div>
                    <div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:6,fontSize:12}}>
                      {[
                        {k:"fournisseur",l:"Fournisseur"},
                        {k:"numero_facture",l:"N° facture"},
                        {k:"date_facture",l:"Date (AAAA-MM-JJ)"},
                        {k:"montant_ht",l:"Montant HT (€)"},
                        {k:"tva",l:"TVA (€)"},
                        {k:"montant_ttc",l:"Montant TTC (€)"},
                      ].map(({k,l})=>(
                        <div key={k}>
                          <div style={{fontSize:10,color:"#64748b",marginBottom:2,fontWeight:600}}>{l}</div>
                          <input value={ef[k]!=null?ef[k]:""} onChange={e=>{
                            const v=["montant_ht","tva","montant_ttc"].includes(k)?parseFloat(e.target.value)||e.target.value:e.target.value;
                            setEditingFacture(s=>({...s,data:{...s.data,[k]:v}}));
                          }} style={inp2}/>
                        </div>
                      ))}
                      <div style={{gridColumn:"1/-1"}}>
                        <div style={{fontSize:10,color:"#64748b",marginBottom:2,fontWeight:600}}>Prestation</div>
                        <input value={ef.description||""} onChange={e=>setEditingFacture(s=>({...s,data:{...s.data,description:e.target.value}}))} style={inp2}/>
                      </div>
                    </div>
                    <div style={{display:"flex",gap:6,marginTop:8,justifyContent:"flex-end"}}>
                      <button onClick={()=>setEditingFacture(null)} style={{background:"#f1f5f9",border:"1px solid #e2e8f0",borderRadius:5,padding:"4px 12px",fontSize:11,cursor:"pointer"}}>Annuler</button>
                      <button onClick={()=>saveFactureData(notif.id,editingFacture.data)} style={{background:"#16a34a",color:"#fff",border:"none",borderRadius:5,padding:"4px 12px",fontSize:11,cursor:"pointer",fontWeight:600}}>✓ Confirmer les corrections</button>
                    </div>
                  </div>
                );
              })()}
              {!isArchived&&(
                <React.Fragment>
                <div style={{display:"flex",gap:6,flexWrap:"wrap",alignItems:"center"}}>
                  {!fd&&notif.attachment_ref&&(
                    <button onClick={()=>analyzeFacture(notif.id)} disabled={!!analyzingIds[notif.id]}
                      style={btnS(analyzingIds[notif.id]?"#94a3b8":"#7c3aed",true)}>
                      {analyzingIds[notif.id]?"⏳ Analyse en cours…":"🔍 Analyser la facture"}
                    </button>
                  )}
                  {!fd&&!notif.attachment_ref&&(
                    <div style={{display:"flex",alignItems:"center",gap:8}}>
                      <span style={{fontSize:11,color:"#94a3b8",fontStyle:"italic"}}>📭 Aucune PJ — saisie manuelle</span>
                      <button onClick={()=>setReglerModal(notif)}
                        style={btnS("#2563eb",true)}>💶 Saisir & intégrer au plan</button>
                    </div>
                  )}
                  {fd&&fs==="reçue"&&!isEditing&&(
                    <>
                      <button onClick={()=>patchFactureStatus(notif.id,"confirmée")} style={btnS("#16a34a",true)}>✓ Confirmer</button>
                      <button onClick={()=>setEditingFacture({id:notif.id,data:{...fd}})} style={btnS("#f59e0b",true)}>✎ Corriger</button>
                      <button onClick={()=>patchFactureStatus(notif.id,"refusée")} style={btnS("#64748b",true)}>✕ Refuser</button>
                    </>
                  )}
                  {fd&&fs==="confirmée"&&!isMultiFacture&&(
                    <button onClick={()=>setReglerModal(notif)} style={btnS("#2563eb",true)}>💶 Régler & intégrer au plan</button>
                  )}
                  {!fd&&(
                    <button onClick={async()=>{
                      await window.apiFetch("/api/agent/notifications/"+notif.id,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"dismiss"})}).catch(()=>{});
                      loadNotifs(notifShowAll);
                    }} style={{background:"none",border:"1px solid #e2e8f0",borderRadius:6,padding:"4px 10px",fontSize:11,cursor:"pointer",color:C.muted}}>Écarter</button>
                  )}
                  {fd&&(
                    <button onClick={()=>resetFacture(notif.id)}
                      style={{background:"none",border:"1px solid #fca5a5",borderRadius:6,padding:"4px 10px",fontSize:11,cursor:"pointer",color:"#dc2626"}}>↺ Réinitialiser</button>
                  )}
                  {/* Mauvais classement auto (ex. multi-PDF tous en « facture ») : relancer la lecture IA du PDF */}
                  <button
                    onClick={()=>reclassify(notif.id)}
                    disabled={!!reclassifyingIds[notif.id]}
                    title="Relancer la classification automatique (lit le PDF) sur cette pièce jointe uniquement"
                    style={{background:"none",border:"1px solid #e2e8f0",borderRadius:6,padding:"4px 10px",fontSize:11,cursor:reclassifyingIds[notif.id]?"default":"pointer",color:"#64748b"}}>
                    {reclassifyingIds[notif.id]?"⏳":"🔄"} Re-classifier
                  </button>
                </div>

                {/* Ligne 2 : forçage manuel de la catégorie (si la re-classification se trompe encore) */}
                <div style={{display:"flex",gap:6,alignItems:"center",flexWrap:"wrap",marginTop:8,paddingTop:8,borderTop:"1px dashed #e2e8f0"}}>
                  <span style={{fontSize:10,color:"#94a3b8",fontWeight:600,whiteSpace:"nowrap"}}>Forcer la catégorie :</span>
                  <select
                    value={forceCatState[notif.id]||""}
                    onChange={e=>setForceCatState(s=>({...s,[notif.id]:e.target.value}))}
                    style={{background:"#f8fafc",border:"1px solid #e2e8f0",borderRadius:5,fontSize:11,padding:"3px 6px",color:"#1e293b"}}>
                    <option value="">— choisir —</option>
                    {ALL_CATS.map(c=><option key={c} value={c}>{c}</option>)}
                  </select>
                  <button
                    onClick={()=>forceCategory(notif.id)}
                    disabled={!forceCatState[notif.id]||!!forcingIds[notif.id]}
                    style={{background:!forceCatState[notif.id]||forcingIds[notif.id]?"#94a3b8":"#7c3aed",color:"#fff",border:"none",borderRadius:5,padding:"3px 10px",fontSize:11,cursor:!forceCatState[notif.id]||forcingIds[notif.id]?"default":"pointer",fontWeight:600}}>
                    {forcingIds[notif.id]?"⏳":"✓"} Forcer
                  </button>
                </div>
                </React.Fragment>
              )}
            </div>
          );
        })}
      </div>

      {/* ══ SECTION AUTRES NOTIFICATIONS ══ */}
      {(notifFilterCat==="all"||notifFilterCat!=="facture")&&autresVisible.length>0&&(
        <div>
          <div style={{fontWeight:700,fontSize:14,marginBottom:10,color:C.muted,paddingTop:8,borderTop:"1px solid "+C.border}}>
            📬 Autres notifications
            <select value={notifFilterCat} onChange={e=>setNotifFilterCat(e.target.value)}
              style={{...inp,width:"auto",fontSize:11,padding:"2px 6px",marginLeft:10}}>
              <option value="all">Toutes catégories</option>
              {["notaire","architecte","lia_retour","diagnostic","autre"].map(c=><option key={c} value={c}>{c}</option>)}
            </select>
          </div>
          {autresVisible.map(notif=>{
            const cat=CAT_COLORS[notif.category]||CAT_COLORS.autre;
            let ref=null;
            try{if(notif.attachment_ref)ref=JSON.parse(notif.attachment_ref);}catch(e){}
            const action=notif.proposed_action;
            const isLow=notif.confidence==="rule_low";
            const meta=notif.metadata||{};
            const docType=action?.params?.docType||null;
            const avancPct=meta.avancement_pct;
            const isArchiveType=["archive_document","archive_and_update_statut"].includes(action?.type);
            const canExecute=!isLow&&isArchiveType;
            const isEditing=canExecute&&archiveInline?.notifId===notif.id;

            /* ── Titre / icône enrichis selon catégorie ── */
            let displayIcon="";
            let displayTitle=null;
            if(notif.category==="lia_retour"){
              displayIcon="📝 "; displayTitle="LIA signée reçue";
            } else if(notif.category==="notaire"){
              if(docType==="compromis_a_signer"){displayIcon="⚖️ "; displayTitle="Compromis reçu du notaire";}
              else if(docType==="acte_authentique"){displayIcon="🏛️ "; displayTitle="Acte authentique reçu";}
            } else if(notif.category==="architecte"&&avancPct!=null){
              const lotIdx=action?.params?.lotIdx;
              displayIcon="📐 "; displayTitle=`Attestation ${avancPct}% reçue${lotIdx!=null?` — Lot ${lotIdx+1}`:""}`;
            } else if(notif.category==="diagnostic"){
              const nb=Array.isArray(notif.metadata?.diagnostic_attachments)?notif.metadata.diagnostic_attachments.length:null;
              displayIcon="🔬 "; displayTitle=`Diagnostics reçus${nb?` (${nb} fichier${nb>1?"s":""})`:""}`;
            }

            const dismiss=async()=>{
              await window.apiFetch("/api/agent/notifications/"+notif.id,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"dismiss"})}).catch(()=>{});
              loadNotifs(notifShowAll);
            };
            const validate=async()=>{
              await window.apiFetch("/api/agent/notifications/"+notif.id,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"validate"})}).catch(()=>{});
              loadNotifs(notifShowAll);
            };
            const confirmArchive=async()=>{
              if(!archiveInline)return;
              const path=archiveInline.folder.replace(/\\+$/,'')+'\\'+ archiveInline.file;
              const ok=await executeNotifAction(notif.id,archiveInline.actionType,path);
              if(ok)setArchiveInline(null);
            };

            return (
              <div key={notif.id} style={{background:C.card,borderRadius:10,border:"1px solid "+(isLow?"#fed7aa":C.border),padding:14,marginBottom:10}}>

                {/* ── Badges ── */}
                <div style={{display:"flex",alignItems:"center",gap:6,marginBottom:6,flexWrap:"wrap"}}>
                  <span style={{background:cat.bg,color:cat.color,borderRadius:4,padding:"2px 8px",fontSize:11,fontWeight:700}}>
                    {displayIcon}{notif.category.toUpperCase()}
                  </span>
                  {notif.confidence==="ai"&&<span style={{background:"#fef3c7",color:"#b45309",borderRadius:4,padding:"1px 6px",fontSize:10,fontWeight:600}}>Claude Haiku</span>}
                  {isLow&&<span style={{background:"#ffedd5",color:"#c2410c",borderRadius:4,padding:"1px 6px",fontSize:10,fontWeight:700}}>⚠ à vérifier</span>}
                  {notif.category==="facture"&&notif.metadata?.doublon_probable&&(
                    <span style={{background:"#fff7ed",color:"#c2410c",borderRadius:4,padding:"1px 6px",fontSize:10,fontWeight:700}}
                      title={"Facture similaire reçue le "+new Date(notif.metadata.doublon_ref_date).toLocaleDateString("fr-FR")}
                    >⚠ doublon probable</span>
                  )}
                  <span style={{fontSize:11,color:C.muted,marginLeft:"auto"}}>{relTime(notif.received_at)}</span>
                </div>

                {/* ── Expéditeur ── */}
                <div style={{fontSize:12,color:C.muted,marginBottom:2}}>De : {notif.from_name||""} {"<"+(notif.from_email||"")+">"}</div>
                {notif.to_recipients&&<div style={{fontSize:12,color:C.muted,marginBottom:2}}>À : {notif.to_recipients}</div>}
                {notif.cc_recipients&&<div style={{fontSize:12,color:C.muted,marginBottom:2}}>Cc : {notif.cc_recipients}</div>}

                {/* ── Titre ── */}
                <div style={{fontWeight:700,fontSize:13,marginBottom:displayTitle?2:6,color:C.text}}>{displayTitle||notif.subject}</div>
                {displayTitle&&<div style={{fontSize:11,color:C.muted,marginBottom:4,fontStyle:"italic"}}>{notif.subject}</div>}
                {notif.category==="lia_retour"&&action?.params?.senderNom&&(
                  <div style={{fontSize:12,color:"#0369a1",marginBottom:6,fontWeight:600}}>👤 Envoyé par : {action.params.senderNom}</div>
                )}

                {/* ── Extrait du mail ── */}
                {notif.preview&&<div style={{fontSize:12,color:C.text,marginBottom:8,fontStyle:"italic",borderLeft:"3px solid #e2e8f0",paddingLeft:8,lineHeight:1.5}}>{notif.preview}</div>}

                {/* ── Pièce jointe ── */}
                {ref&&(
                  <div style={{display:"flex",alignItems:"center",gap:8,marginBottom:8,background:"#f8fafc",borderRadius:6,padding:"5px 10px"}}>
                    <span style={{fontSize:12}}>📎 {ref.filename||"document.pdf"}</span>
                    {ref.size&&<span style={{fontSize:11,color:C.muted}}>({Math.round(ref.size/1024)} Ko)</span>}
                    <button onClick={()=>setNotifPdfModal(notif.id)} style={btnS("#334155",true)}>aperçu</button>
                  </div>
                )}

                {/* ── Action proposée — affichage statique OU éditeur inline ── */}
                {action&&action.type&&action.type!=="dismiss_or_manual"&&(
                  isEditing ? (
                    /* ══ ÉDITEUR INLINE DE CHEMIN ONEDRIVE ══ */
                    <div style={{background:"#f0f9ff",border:"1px solid #bae6fd",borderRadius:8,padding:12,marginBottom:8}}>
                      <div style={{fontWeight:700,fontSize:11,color:"#0369a1",marginBottom:8}}>📁 Chemin OneDrive — vérifier et corriger si besoin</div>

                      {/* Dossier */}
                      <div style={{marginBottom:6}}>
                        <div style={{fontSize:10,color:C.muted,fontWeight:600,marginBottom:3}}>Dossier</div>
                        <div style={{display:"flex",gap:5}}>
                          <input value={archiveInline.folder}
                            onChange={e=>setArchiveInline(p=>({...p,folder:e.target.value,checkResult:null}))}
                            style={{background:"#fff",border:"1px solid #bae6fd",borderRadius:6,color:"#1e293b",padding:"5px 8px",fontSize:11,flex:1,fontFamily:"monospace"}}/>
                          <button onClick={()=>recheckArchiveFolder(archiveInline.folder)} disabled={archiveInline.checking}
                            style={btnS("#64748b",true)}>{archiveInline.checking?"…":"🔍"}</button>
                          <button
                            onClick={()=>archiveInline.browserOpen
                              ?setArchiveInline(p=>({...p,browserOpen:false}))
                              :loadArchiveBrowser(archiveInline.programmeRoot)}
                            style={btnS(archiveInline.browserOpen?"#334155":"#0369a1",true)}>
                            {archiveInline.browserOpen?"↑ Fermer":"📂 Parcourir"}
                          </button>
                        </div>
                      </div>

                      {/* Résultat vérification */}
                      {archiveInline.checkResult&&(
                        <div style={{marginBottom:6,padding:"5px 9px",borderRadius:6,fontSize:11,
                          background:archiveInline.checkResult.exists?"#f0fdf4":"#fff7ed",
                          border:"1px solid "+(archiveInline.checkResult.exists?"#bbf7d0":"#fed7aa")}}>
                          {archiveInline.checkResult.exists
                            ?<span style={{color:"#15803d",fontWeight:700}}>✅ Dossier trouvé sur OneDrive</span>
                            :<>
                              <span style={{color:"#c2410c",fontWeight:700}}>⚠️ Dossier introuvable</span>
                              {archiveInline.checkResult.folders?.length>0&&(
                                <div style={{display:"flex",flexWrap:"wrap",gap:3,marginTop:4}}>
                                  {archiveInline.checkResult.folders.map(f=>(
                                    <button key={f.path}
                                      onClick={()=>{setArchiveInline(p=>({...p,folder:f.path,checkResult:null}));recheckArchiveFolder(f.path);}}
                                      style={{background:"#ffedd5",border:"1px solid #fed7aa",borderRadius:4,padding:"2px 7px",fontSize:10,cursor:"pointer",color:"#92400e",fontWeight:600}}>
                                      📁 {f.name}
                                    </button>
                                  ))}
                                </div>
                              )}
                              {archiveInline.checkResult.error&&<div style={{color:"#dc2626",marginTop:3,fontSize:10}}>{archiveInline.checkResult.error}</div>}
                            </>
                          }
                        </div>
                      )}

                      {/* Navigateur inline */}
                      {archiveInline.browserOpen&&(
                        <div style={{background:"#fff",border:"1px solid #e2e8f0",borderRadius:6,padding:8,marginBottom:6}}>
                          {/* Fil d'Ariane */}
                          <div style={{fontSize:10,color:"#64748b",marginBottom:5,fontFamily:"monospace",wordBreak:"break-all",display:"flex",alignItems:"center",flexWrap:"wrap",gap:2}}>
                            {archiveInline.browserPath.split("\\").filter(Boolean).map((seg,i,arr)=>(
                              <span key={i} style={{display:"flex",alignItems:"center",gap:2}}>
                                {i>0&&<span style={{color:"#cbd5e1"}}>\</span>}
                                <span
                                  onClick={()=>{if(i<arr.length-1)loadArchiveBrowser("\\"+arr.slice(0,i+1).join("\\"));}}
                                  style={{cursor:i<arr.length-1?"pointer":"default",color:i<arr.length-1?"#2563eb":"#1e293b",fontWeight:i===arr.length-1?700:400,textDecoration:i<arr.length-1?"underline":"none"}}>
                                  {seg}
                                </span>
                              </span>
                            ))}
                          </div>
                          {/* Remonter */}
                          {archiveInline.browserPath&&archiveInline.browserPath!==archiveInline.programmeRoot&&(
                            <button onClick={()=>{
                              const segs=archiveInline.browserPath.replace(/\\+$/,"").split("\\").filter(Boolean);
                              segs.pop();
                              loadArchiveBrowser(segs.length?"\\"+segs.join("\\"):"\\");
                            }} style={{background:"#f1f5f9",border:"1px solid #e2e8f0",borderRadius:5,padding:"3px 8px",fontSize:10,cursor:"pointer",color:"#334155",marginBottom:5}}>
                              ← Remonter
                            </button>
                          )}
                          {/* Liste dossiers */}
                          {!archiveInline.browserData||archiveInline.browserData.loading
                            ?<div style={{color:"#94a3b8",fontSize:11}}>Chargement…</div>
                            :archiveInline.browserData.error
                            ?<div style={{color:"#dc2626",fontSize:11}}>{archiveInline.browserData.error}</div>
                            :archiveInline.browserData.folders?.length===0
                            ?<div style={{color:"#94a3b8",fontSize:11,fontStyle:"italic"}}>Aucun sous-dossier</div>
                            :<div style={{display:"flex",flexDirection:"column",gap:2,maxHeight:160,overflowY:"auto"}}>
                              {archiveInline.browserData.folders.map(f=>(
                                <button key={f.path} onClick={()=>loadArchiveBrowser(f.path)}
                                  style={{background:"none",border:"1px solid #e2e8f0",borderRadius:5,padding:"4px 9px",fontSize:11,cursor:"pointer",textAlign:"left",color:"#1e293b",display:"flex",alignItems:"center",gap:6}}>
                                  <span>📁</span><span style={{flex:1}}>{f.name}</span><span style={{color:"#94a3b8",fontSize:10}}>▶</span>
                                </button>
                              ))}
                            </div>
                          }
                          {/* Sélectionner ce dossier */}
                          {archiveInline.browserData&&!archiveInline.browserData.loading&&(
                            <div style={{marginTop:6,paddingTop:6,borderTop:"1px solid #e2e8f0",display:"flex",justifyContent:"flex-end"}}>
                              <button onClick={selectArchiveBrowserFolder} style={btnS("#0369a1",true)}>✓ Sélectionner ce dossier</button>
                            </div>
                          )}
                        </div>
                      )}

                      {/* Nom du fichier */}
                      <div>
                        <div style={{fontSize:10,color:C.muted,fontWeight:600,marginBottom:3}}>Nom du fichier</div>
                        <input value={archiveInline.file}
                          onChange={e=>setArchiveInline(p=>({...p,file:e.target.value}))}
                          style={{background:"#fff",border:"1px solid #bae6fd",borderRadius:6,color:"#1e293b",padding:"5px 8px",fontSize:11,width:"100%",boxSizing:"border-box"}}/>
                      </div>
                    </div>
                  ) : (
                    /* ══ AFFICHAGE STATIQUE ══ */
                    <div style={{background:"#eff6ff",borderRadius:6,padding:"6px 10px",marginBottom:8,fontSize:12,borderLeft:"3px solid "+C.accent}}>
                      <span style={{fontWeight:700}}>▸ </span><span>{action.label||action.type}</span>
                      {canExecute&&action.params?.oneDrivePath&&(
                        <div style={{display:"flex",alignItems:"center",gap:6,marginTop:4}}>
                          <div style={{fontSize:10,color:C.muted,fontFamily:"monospace",wordBreak:"break-all",flex:1}}>
                            📁 {action.params.oneDrivePath}
                          </div>
                          <button onClick={()=>openArchiveInline(notif.id,action,action.type)}
                            style={{background:"#0369a1",color:"#fff",border:"none",borderRadius:5,padding:"2px 8px",fontSize:10,cursor:"pointer",fontWeight:600,flexShrink:0}}>
                            📂 Vérifier
                          </button>
                        </div>
                      )}
                      {!canExecute&&action.params?.oneDrivePath&&(
                        <div style={{fontSize:10,color:C.muted,marginTop:3,fontFamily:"monospace",wordBreak:"break-all"}}>
                          📁 {action.params.oneDrivePath}
                        </div>
                      )}
                    </div>
                  )
                )}

                {/* ── Boutons d'action ── */}
                {notif.status==="new"&&(
                  <div style={{display:"flex",flexDirection:"column",gap:0}}>

                    {/* Ligne 1 : boutons principaux */}
                    <div style={{display:"flex",gap:6,flexWrap:"wrap"}}>
                      {isEditing&&(
                        <>
                          <button onClick={confirmArchive} disabled={!archiveInline?.file||!archiveInline?.folder}
                            style={btnS(!archiveInline?.file||!archiveInline?.folder?"#94a3b8":"#16a34a",true)}>
                            ✓ Confirmer l'archivage
                          </button>
                          {action.type==="archive_and_update_statut"&&(
                            <button onClick={()=>{setArchiveInline(null);openIncompleteLiaModal(notif.id);}}
                              style={btnS("#f59e0b",true)}>⚠ Document incomplet</button>
                          )}
                          <button onClick={()=>setArchiveInline(null)} style={btnS("#94a3b8",true)}>✕ Annuler</button>
                        </>
                      )}
                      {!isEditing&&canExecute&&action.type==="archive_and_update_statut"&&(
                        <button onClick={()=>openArchiveInline(notif.id,action,"archive_and_update_statut")}
                          style={btnS("#0369a1",true)}>✓ Archiver + passer en Sous LIA</button>
                      )}
                      {!isEditing&&canExecute&&action.type==="archive_document"&&docType==="compromis_a_signer"&&(
                        <button onClick={()=>openArchiveInline(notif.id,action,"archive_document")}
                          style={btnS("#7c3aed",true)}>✓ Archiver le compromis</button>
                      )}
                      {!isEditing&&canExecute&&action.type==="archive_document"&&docType==="acte_authentique"&&(
                        <button onClick={()=>openArchiveInline(notif.id,action,"archive_document")}
                          style={btnS("#7c3aed",true)}>✓ Archiver l'acte</button>
                      )}
                      {notif.category==="diagnostic"&&(
                        <button onClick={()=>setDiagModalNotif(notif)} style={btnS("#a21caf",true)}>🗂 Ranger les diagnostics</button>
                      )}
                      {!canExecute&&notif.category!=="diagnostic"&&<button onClick={validate} style={btnS("#16a34a",true)}>✓ Valider</button>}
                      {!isEditing&&<button onClick={dismiss} style={btnS("#64748b",true)}>✕ Écarter</button>}
                      <button
                        onClick={()=>reclassify(notif.id)}
                        disabled={!!reclassifyingIds[notif.id]}
                        title="Relancer la classification automatique sur cet email uniquement"
                        style={{background:"none",border:"1px solid #e2e8f0",borderRadius:6,padding:"4px 10px",fontSize:11,cursor:reclassifyingIds[notif.id]?"default":"pointer",color:"#64748b"}}>
                        {reclassifyingIds[notif.id]?"⏳":"🔄"} Re-classifier
                      </button>
                    </div>

                    {/* Ligne 2 : forçage manuel — séparée visuellement */}
                    <div style={{display:"flex",gap:6,alignItems:"center",flexWrap:"wrap",marginTop:8,paddingTop:8,borderTop:"1px dashed #e2e8f0"}}>
                      <span style={{fontSize:10,color:"#94a3b8",fontWeight:600,whiteSpace:"nowrap"}}>Forcer la catégorie :</span>
                      <select
                        value={forceCatState[notif.id]||""}
                        onChange={e=>setForceCatState(s=>({...s,[notif.id]:e.target.value}))}
                        style={{background:"#f8fafc",border:"1px solid #e2e8f0",borderRadius:5,fontSize:11,padding:"3px 6px",color:"#1e293b"}}>
                        <option value="">— choisir —</option>
                        {ALL_CATS.map(c=><option key={c} value={c}>{c}</option>)}
                      </select>
                      <button
                        onClick={()=>forceCategory(notif.id)}
                        disabled={!forceCatState[notif.id]||!!forcingIds[notif.id]}
                        style={{background:!forceCatState[notif.id]||forcingIds[notif.id]?"#94a3b8":"#7c3aed",color:"#fff",border:"none",borderRadius:5,padding:"3px 10px",fontSize:11,cursor:!forceCatState[notif.id]||forcingIds[notif.id]?"default":"pointer",fontWeight:600}}>
                        {forcingIds[notif.id]?"⏳":"✓"} Forcer
                      </button>
                    </div>

                  </div>
                )}
              </div>
            );
          })}
        </div>
      )}

      {facturesVisible.length===0&&autresVisible.length===0&&(
        <div style={{background:C.card,borderRadius:12,border:"1px dashed "+C.border,padding:32,textAlign:"center"}}>
          <div style={{fontSize:40,marginBottom:12}}>🔕</div>
          <div style={{fontWeight:700,fontSize:15,marginBottom:6}}>Aucune action en attente</div>
          <div style={{fontSize:12,color:C.muted}}>Toutes les notifications ont été traitées.</div>
        </div>
      )}

      {/* ── Purge ── */}
      <div style={{marginTop:16,textAlign:"right"}}>
        <button onClick={async()=>{
          if(!confirm("Supprimer toutes les notifications traitées ou refusées de plus de 12 mois ?")) return;
          try{
            const r=await window.apiFetch("/api/agent/notifications/purge",{method:"POST",headers:{"Content-Type":"application/json"}});
            const d=await r.json();
            if(d.error){alert("Erreur : "+d.error);return;}
            if(d.deleted===0) alert("Aucune notification à purger (critères : traitées/refusées et antérieures à 12 mois).");
            else{alert(d.deleted+" notification(s) supprimée(s).");loadNotifs(notifShowAll);}
          }catch(e){alert("Erreur réseau : "+e.message);}
        }} style={{background:"none",border:"1px solid #e2e8f0",borderRadius:7,padding:"5px 14px",
          fontSize:11,cursor:"pointer",color:"#94a3b8",fontWeight:600}}>
          🗑 Purger les anciennes (&gt;12 mois)
        </button>
      </div>
    </>
    )}

    {/* ── Modale prévisualisation PDF ── */}
    {notifPdfModal&&(
      <div style={{position:"fixed",inset:0,background:"rgba(0,0,0,0.75)",zIndex:3000,display:"flex",flexDirection:"column"}}
        onClick={e=>{if(e.target===e.currentTarget)setNotifPdfModal(null);}}>
        <div style={{display:"flex",justifyContent:"flex-end",padding:"8px 16px",flexShrink:0}}>
          <button onClick={()=>setNotifPdfModal(null)} style={{background:"#fff",border:"none",borderRadius:6,padding:"5px 16px",fontWeight:700,cursor:"pointer",fontSize:14}}>✕ Fermer</button>
        </div>
        <iframe src={"/api/agent/notifications/"+notifPdfModal+"/attachment"} style={{flex:1,border:"none",background:"#fff"}} title="Prévisualisation PDF"/>
      </div>
    )}

    {/* ── Modale Régler facture ── */}
    {reglerModal&&(
      <FactureReglerModal
        notifId={reglerModal.id}
        factureData={reglerModal.facture_data}
        proposedAction={reglerModal.proposed_action}
        projects={projects}
        rows={rows}
        fiche={fiches}
        allValues={values}
        onSave={(rowId,weekIso,montant,redist)=>{ handleCellSave(rowId,weekIso,montant,redist,true); }}
        logMouvementAuto={logMouvementAuto}
        onClose={()=>{ setReglerModal(null); loadNotifs(notifShowAll); }}
      />
    )}

    {/* ── Modale LIA incomplète ── */}
    {incompleteLiaModal&&(
      <IncompleteLiaModal
        state={incompleteLiaModal}
        onSent={async()=>{
          await window.apiFetch("/api/agent/notifications/"+incompleteLiaModal.notifId,{
            method:"PATCH",headers:{"Content-Type":"application/json"},
            body:JSON.stringify({action:"mark_done"})
          }).catch(()=>{});
          setIncompleteLiaModal(null);
          loadNotifs(notifShowAll);
        }}
        onClose={()=>setIncompleteLiaModal(null)}
      />
    )}

    {/* ── Modale « ranger les diagnostics » ── */}
    {diagModalNotif&&(
      <DiagnosticArchiveModal
        C={C}
        notif={diagModalNotif}
        projects={projects}
        fiches={fiches}
        onClose={()=>setDiagModalNotif(null)}
        onDone={()=>{ setDiagModalNotif(null); loadNotifs(notifShowAll); }}
      />
    )}

  </div>
  );
}

/* ── IncompleteLiaModal déplacée dans public/components/IncompleteLiaModal.jsx
   (dette D1, 2026-06-24). Portée globale conservée ; rendue par NotificationsView. ── */
