/* Review workspace — the hero screen
   Left: source viewer (tabs + provenance highlights)
   Right: CMR form grouped + goods table + validation panel
   Sticky action bar.
*/

// ---- Source documents (rendered as faux paper pages with highlights) ----
const InvoiceDoc = ({ refs, activeKey, onActivate }) => (
  <div className="doc-page" id="doc-invoice">
    <div style={{display:"flex", justifyContent:"space-between", alignItems:"start", marginBottom:14}}>
      <div>
        <div className="doc-h">SOREMED Industries SARL</div>
        <div style={{fontSize:11, color:"var(--muted)"}}>Zone Industrielle Sidi Bernoussi · 20600 Casablanca · Maroc</div>
        <div className="doc-meta">ICE 001745829000034 · RC 132 445</div>
      </div>
      <div style={{textAlign:"right"}}>
        <div style={{fontSize:13, fontWeight:600}}>FACTURE COMMERCIALE</div>
        <div className="doc-meta">N° INV-2026-77231</div>
        <div className="doc-meta">22 / 05 / 2026</div>
      </div>
    </div>

    <div style={{display:"grid", gridTemplateColumns:"1fr 1fr", gap:18, marginBottom:18}}>
      <Block label="Vendeur / Expéditeur">
        SOREMED Industries SARL<br/>
        Zone Industrielle Sidi Bernoussi<br/>
        20600 Casablanca, Maroc<br/>
        <span className="mono" style={{fontSize:11, color:"var(--muted)"}}>ICE: 001745829000034</span>
      </Block>
      <Block label="Acheteur / Destinataire">
        Logística Ibérica Distribución S.A.<br/>
        Calle del Comercio 142<br/>
        28038 Madrid, España<br/>
        <span className="mono" style={{fontSize:11, color:"var(--muted)"}}>CIF: A-87614520</span>
      </Block>
    </div>

    <hr className="doc-hr"/>

    <div style={{display:"grid", gridTemplateColumns:"1fr 1fr", gap:14, marginBottom:14}}>
      <div>
        <Label>Lieu et date de chargement</Label>
        <div>Port de Casablanca — 24/05/2026</div>
      </div>
      <div>
        <Label>Lieu de déchargement</Label>
        <div>Entrepôt Vallecas — Madrid (ES)</div>
      </div>
    </div>

    <Label>Documents annexés</Label>
    <div style={{fontSize:11.5, color:"var(--muted)"}}>
      Facture INV-2026-77231 · Liste de colisage PKL-77231 · Certificat d'origine EUR.1 N° A 4421987
    </div>

    <hr className="doc-hr"/>

    <table style={{width:"100%", fontSize:11, borderCollapse:"collapse"}}>
      <thead>
        <tr style={{borderBottom:"1px solid #999"}}>
          <th style={{textAlign:"left", padding:"4px 0"}}>Désignation</th>
          <th style={{textAlign:"right", padding:"4px 0"}}>Qté</th>
          <th style={{textAlign:"right", padding:"4px 0"}}>P.U. €</th>
          <th style={{textAlign:"right", padding:"4px 0"}}>Total €</th>
        </tr>
      </thead>
      <tbody>
        <tr><td>Conserves de poisson — sardines</td><td style={{textAlign:"right"}}>12 pal.</td><td style={{textAlign:"right"}}>185,00</td><td style={{textAlign:"right"}}>2 220,00</td></tr>
        <tr><td>Textile coton — vêtements travail</td><td style={{textAlign:"right"}}>8 cart.</td><td style={{textAlign:"right"}}>62,50</td><td style={{textAlign:"right"}}>500,00</td></tr>
        <tr><td>Pièces auto Renault — radiateurs</td><td style={{textAlign:"right"}}>3 cs.</td><td style={{textAlign:"right"}}>118,00</td><td style={{textAlign:"right"}}>354,00</td></tr>
        <tr><td>Phosphates 70BPL — sacs OCP</td><td style={{textAlign:"right"}}>1 ctn.</td><td style={{textAlign:"right"}}>—</td><td style={{textAlign:"right"}}>—</td></tr>
      </tbody>
      <tfoot>
        <tr><td colSpan="3" style={{textAlign:"right", padding:"6px 0", fontWeight:600}}>Total HT</td><td style={{textAlign:"right", fontWeight:600}}>3 074,00 €</td></tr>
      </tfoot>
    </table>

    <div style={{marginTop:18, fontSize:11, color:"var(--muted)"}}>
      Établi à Casablanca, le 22/05/2026 · H. El Khattabi, Service logistique
    </div>

    {/* Highlights — absolutely positioned over the page */}
    {refs.filter(r => r.doc === "invoice").map((r) => (
      <Highlight key={r.id} r={r} active={r.id === activeKey} onClick={() => onActivate(r.id)} />
    ))}
  </div>
);

const PackingDoc = ({ refs, activeKey, onActivate }) => (
  <div className="doc-page" id="doc-packing">
    <div style={{display:"flex", justifyContent:"space-between"}}>
      <div>
        <div className="doc-h">LISTE DE COLISAGE / PACKING LIST</div>
        <div className="doc-meta">PKL-77231 · 22/05/2026</div>
      </div>
      <div style={{textAlign:"right", fontSize:11, color:"var(--muted)"}}>
        SOREMED Industries → Logística Ibérica
      </div>
    </div>
    <hr className="doc-hr"/>
    <table style={{width:"100%", fontSize:11, borderCollapse:"collapse"}}>
      <thead>
        <tr style={{background:"#f0eee5"}}>
          <th style={{textAlign:"left", padding:6, border:"1px solid #aaa"}}>Marques</th>
          <th style={{textAlign:"left", padding:6, border:"1px solid #aaa"}}>Colis</th>
          <th style={{textAlign:"left", padding:6, border:"1px solid #aaa"}}>Emballage</th>
          <th style={{textAlign:"left", padding:6, border:"1px solid #aaa"}}>Nature de la marchandise</th>
          <th style={{textAlign:"left", padding:6, border:"1px solid #aaa"}}>SH</th>
          <th style={{textAlign:"right", padding:6, border:"1px solid #aaa"}}>kg</th>
          <th style={{textAlign:"right", padding:6, border:"1px solid #aaa"}}>m³</th>
        </tr>
      </thead>
      <tbody>
        <tr><td style={{padding:6, border:"1px solid #ccc"}}>SRM/77231-A</td><td style={{padding:6, border:"1px solid #ccc"}}>12</td><td style={{padding:6, border:"1px solid #ccc"}}>Palettes EUR</td><td style={{padding:6, border:"1px solid #ccc"}}>Conserves sardines à l'huile d'olive</td><td style={{padding:6, border:"1px solid #ccc"}}>1604.13</td><td style={{padding:6, border:"1px solid #ccc", textAlign:"right"}}>4 820</td><td style={{padding:6, border:"1px solid #ccc", textAlign:"right"}}>8,40</td></tr>
        <tr><td style={{padding:6, border:"1px solid #ccc"}}>SRM/77231-B</td><td style={{padding:6, border:"1px solid #ccc"}}>8</td><td style={{padding:6, border:"1px solid #ccc"}}>Cartons</td><td style={{padding:6, border:"1px solid #ccc"}}>Textile coton — vêtements travail</td><td style={{padding:6, border:"1px solid #ccc"}}>6203.32</td><td style={{padding:6, border:"1px solid #ccc", textAlign:"right"}}>1 240</td><td style={{padding:6, border:"1px solid #ccc", textAlign:"right"}}>3,10</td></tr>
        <tr><td style={{padding:6, border:"1px solid #ccc"}}>SRM/77231-C</td><td style={{padding:6, border:"1px solid #ccc"}}>3</td><td style={{padding:6, border:"1px solid #ccc"}}>Caisses bois</td><td style={{padding:6, border:"1px solid #ccc"}}>Pièces auto — radiateurs Renault Clio</td><td style={{padding:6, border:"1px solid #ccc"}}>8708.91 ?</td><td style={{padding:6, border:"1px solid #ccc", textAlign:"right"}}>186</td><td style={{padding:6, border:"1px solid #ccc", textAlign:"right"}}>0,90</td></tr>
        <tr><td style={{padding:6, border:"1px solid #ccc"}}>SRM/77231-D</td><td style={{padding:6, border:"1px solid #ccc"}}>1</td><td style={{padding:6, border:"1px solid #ccc"}}>Conteneur 20'</td><td style={{padding:6, border:"1px solid #ccc"}}>Phosphates en sacs 70BPL</td><td style={{padding:6, border:"1px solid #ccc"}}>2510.20</td><td style={{padding:6, border:"1px solid #ccc", textAlign:"right"}}>—</td><td style={{padding:6, border:"1px solid #ccc", textAlign:"right"}}>24,0</td></tr>
      </tbody>
    </table>
    <div style={{marginTop:8, fontSize:10.5, color:"var(--muted)"}}>
      Note (manuscrit) : conteneur D — poids approximatif, à vérifier à l'embarquement
    </div>
    {refs.filter(r => r.doc === "packing").map((r) => (
      <Highlight key={r.id} r={r} active={r.id === activeKey} onClick={() => onActivate(r.id)} />
    ))}
  </div>
);

const EmailDoc = ({ refs, activeKey, onActivate }) => (
  <div className="doc-page" id="doc-email" style={{padding:"28px 36px"}}>
    <div style={{paddingBottom:12, borderBottom:"1px solid var(--hairline)"}}>
      <div style={{fontSize:14, fontWeight:600}}>RE: Expédition #DK-88421 — Casablanca → Madrid</div>
      <div style={{display:"flex", gap:18, marginTop:6, fontSize:11.5, color:"var(--muted)"}}>
        <div><b style={{color:"var(--ink-2)"}}>De</b> · H. El Khattabi &lt;logistique@soremed.ma&gt;</div>
        <div><b style={{color:"var(--ink-2)"}}>À</b> · ops+cargonote@atlas-maghreb.ma</div>
        <div><b style={{color:"var(--ink-2)"}}>Date</b> · 22 mai 2026, 09:12</div>
      </div>
    </div>
    <div style={{marginTop:14, whiteSpace:"pre-wrap", fontSize:12.5, lineHeight:1.6}}>
{`Bonjour,

Veuillez trouver ci-joint les documents pour l'expédition de demain : facture commerciale, liste de colisage et photo du BL signé.

Détails :

— Transporteur retenu : Transports Atlas Maghreb (licence TIR-MA-2241)
— Enlèvement : 24/05/2026 au Port de Casablanca
— Livraison : Entrepôt Vallecas, Madrid
— Contact destinataire : M. Martínez, +34 911 22 88 ●● (texte effacé)
— Tarif : franco, 2 850 € forfait porte-à-porte (cf. devis DV-2026-118)
— Température < 25 °C — livraison sur RDV uniquement

Merci de confirmer la prise en charge.

Cordialement,
H. El Khattabi
Service logistique, SOREMED Industries`}
    </div>
    {refs.filter(r => r.doc === "email").map((r) => (
      <Highlight key={r.id} r={r} active={r.id === activeKey} onClick={() => onActivate(r.id)} />
    ))}
  </div>
);

const PhotoDoc = ({ refs, activeKey, onActivate }) => (
  <div className="doc-page" style={{padding:0, background:"#1a1813", color:"#eee", overflow:"hidden"}}>
    <div style={{padding:"10px 14px", background:"#0f0d09", color:"#aaa", fontSize:11, display:"flex", justifyContent:"space-between"}}>
      <span>IMG_8842.jpg — photo BL manuscrit</span>
      <span className="mono">2 8 MB · 3024 × 4032</span>
    </div>
    <div style={{
      position:"relative",
      // Faked photo — paper-like with subtle gradient + ink lines
      background:`
        repeating-linear-gradient(transparent 0 38px, rgba(0,0,0,0.04) 38px 39px),
        radial-gradient(circle at 30% 30%, #f5ecd7 0%, #e7d9b6 100%)
      `,
      height: 800,
      padding: "36px 44px",
      color: "#1a1813",
      fontFamily: "var(--font-mono)",
      fontSize: 12,
      transform: "rotate(-1.5deg)",
      transformOrigin: "center",
      boxShadow: "inset 0 0 80px rgba(0,0,0,0.15)"
    }}>
      <div style={{fontWeight:700, fontSize:14, marginBottom:6}}>BORDEREAU DE LIVRAISON</div>
      <div style={{fontSize:11, color:"#5a4a30"}}>Atlas Maghreb · BL-MAN-3318</div>
      <div style={{marginTop:18, lineHeight:1.9}}>
        Lot SRM/77231-C  ·  3 caisses bois  ·  168 kg<br/>
        Lot SRM/77231-D  ·  1 conteneur 20'  ·  18 4__ kg (illisible)<br/>
        <br/>
        Observations: caisses bois (C) légèrement<br/>
        endommagées au chargement — coin sup. droit.<br/>
        <br/>
        Signature chauffeur: <span style={{fontFamily:"cursive", fontSize:18}}>Y. Benali</span>
      </div>
    </div>
    {refs.filter(r => r.doc === "photo").map((r) => (
      <Highlight key={r.id} r={r} active={r.id === activeKey} onClick={() => onActivate(r.id)} />
    ))}
  </div>
);

const Block = ({ label, children }) => (
  <div>
    <Label>{label}</Label>
    <div>{children}</div>
  </div>
);
const Label = ({ children }) => (
  <div style={{fontSize:10.5, textTransform:"uppercase", letterSpacing:"0.06em", color:"var(--muted)", marginBottom:4}}>{children}</div>
);

// ---- Real uploaded document (page image with persistent provenance overlays) ----
const RealDoc = ({ doc, refs, activeKey, onActivate }) => {
  if (!doc) return null;
  if (doc.kind === "image") {
    const pageRefs = (refs || []).filter((r) => r.doc === doc.id);
    return (
      <div className="doc-page" style={{ padding: 0, overflow: "hidden", position: "relative", width: "min(820px, 100%)" }}>
        <img src={doc.url} alt={doc.label} style={{ width: "100%", display: "block" }} />
        {pageRefs.map((r) => (
          <div
            key={r.id}
            className={`highlight ${r.id === activeKey ? "active" : ""}`}
            data-conf={r.conf}
            style={{
              left: `${r.rect[0]}%`, top: `${r.rect[1]}%`,
              width: `${r.rect[2]}%`, height: `${r.rect[3]}%`,
            }}
            onClick={() => onActivate && onActivate(r.id)}
            title={r.id}
          />
        ))}
      </div>
    );
  }
  if (doc.kind === "pdf") {
    return (
      <div style={{ width: "min(820px, 100%)" }}>
        <object data={doc.url} type="application/pdf" style={{ width: "100%", height: "920px", border: "1px solid var(--hairline)", borderRadius: 4, background: "#fff" }}>
          <div className="doc-page"><a href={doc.url} target="_blank" rel="noreferrer">Ouvrir {doc.label}</a></div>
        </object>
      </div>
    );
  }
  return <div className="doc-page"><div className="doc-h">{doc.label}</div></div>;
};

// Build the flat list of provenance refs from a real case's fields + goods rows.
// Matches the shape the seeded demo uses for InvoiceDoc/PackingDoc.
const buildRealRefs = (fields) => {
  const refs = [];
  for (const [key, f] of Object.entries(fields || {})) {
    if (key === "goods") continue;
    if (!f || typeof f !== "object") continue;
    if (f.doc && Array.isArray(f.rect) && f.rect.length === 4) {
      refs.push({ id: key, doc: f.doc, rect: f.rect, conf: f.bucket });
    }
  }
  for (const g of (fields && fields.goods) || []) {
    if (g.doc && Array.isArray(g.rect) && g.rect.length === 4) {
      const minConf = Math.min(g.marksConf, g.packagesConf, g.packingConf, g.natureConf, g.hsConf, g.weightConf, g.volumeConf);
      const bucket = minConf >= 0.9 ? "hi" : minConf >= 0.7 ? "med" : "lo";
      refs.push({ id: `goods.${g.id}`, doc: g.doc, rect: g.rect, conf: bucket });
    }
  }
  return refs;
};

// Parse a French-formatted number ("4 820", "8,40") to a float.
const parseFrNum = (s) => {
  const n = parseFloat(String(s == null ? "" : s).replace(/\s/g, "").replace(",", "."));
  return Number.isFinite(n) ? n : 0;
};
const goodsTotals = (rows) => rows.reduce((a, r) => ({
  packages: a.packages + parseFrNum(r.packages),
  weight: a.weight + parseFrNum(r.weight),
  volume: a.volume + parseFrNum(r.volume),
}), { packages: 0, weight: 0, volume: 0 });

const Highlight = ({ r, active, onClick }) => (
  <div
    className={`highlight ${active ? "active" : ""}`}
    data-conf={r.conf}
    style={{
      left: `${r.rect[0]}%`,
      top: `${r.rect[1]}%`,
      width: `${r.rect[2]}%`,
      height: `${r.rect[3]}%`,
    }}
    onClick={onClick}
    onMouseEnter={() => r.onHover && r.onHover(r.id)}
  />
);

// ---- The review workspace ----
const ReviewView = ({ data, onApprove, onBack }) => {
  const docList = data.heroCase.docs || [];
  const [activeField, setActiveField] = React.useState(null);
  const [edited, setEdited] = React.useState({});
  const [fields, setFields] = React.useState(data.heroCase.fields);
  // Real-case provenance refs — re-derive from current (possibly edited) fields.
  const realRefs = React.useMemo(() => buildRealRefs(fields), [fields]);
  // Open on the doc that actually has the most provenance — otherwise the first.
  const [activeDoc, setActiveDoc] = React.useState(() => {
    if (realRefs.length) {
      const counts = realRefs.reduce((m, r) => ((m[r.doc] = (m[r.doc] || 0) + 1), m), {});
      const best = Object.entries(counts).sort((a, b) => b[1] - a[1])[0];
      if (best) return best[0];
    }
    return (docList[0] && docList[0].id) || "invoice";
  });

  // Field activation also switches doc to its source
  const activate = (id, fromDoc) => {
    setActiveField(id);
    if (fromDoc) {
      setActiveDoc(fromDoc);
    } else {
      const f = fields[id];
      if (f && f.doc) setActiveDoc(f.doc);
    }
  };

  const editField = (id, val) => {
    setFields((prev) => ({ ...prev, [id]: { ...prev[id], value: val } }));
    setEdited((prev) => ({ ...prev, [id]: true }));
  };

  // Build list of highlight refs from current fields (single-field provenance)
  const docRefs = Object.entries(fields)
    .filter(([id, f]) => f.doc && f.rect)
    .map(([id, f]) => ({ id, doc: f.doc, rect: f.rect, conf: f.bucket }));

  const renderConf = (id, score, conflictWith) => {
    if (edited[id]) return "edited";
    if (conflictWith) return "conflict";
    return null;
  };

  return (
    <div style={{display:"grid", gridTemplateColumns:"minmax(560px, 1fr) minmax(540px, 640px)", height:"calc(100vh - 50px)", minWidth:1240, overflowX:"auto"}}>
      {/* LEFT — doc viewer */}
      <div className="docpane">
        <div className="tabs" style={{overflowX:"auto", overflowY:"hidden", flexWrap:"nowrap"}}>
          {docList.map((d) => {
            const label = d.url
              ? (d.label.length > 22 ? d.label.slice(0, 20) + "…" : d.label)
              : (d.kind === "email" ? "Email" : d.kind === "image" ? "Photo BL" : d.id === "invoice" ? "Facture" : "Colisage");
            return (
              <div key={d.id} className={`tab ${activeDoc === d.id ? "active" : ""}`}
                   onClick={() => setActiveDoc(d.id)} style={{whiteSpace:"nowrap", flexShrink:0}}>
                <Icon name={d.kind === "email" ? "mail" : d.kind === "image" ? "image" : "pdf"} size={13}/>
                <span>{label}</span>
              </div>
            );
          })}
          <div style={{marginLeft:"auto", display:"flex", gap:4, alignItems:"center", padding:"4px 4px", flexShrink:0}}>
            <button className="icon-btn" title="Recadrer"><Icon name="eye" size={14}/></button>
            <button className="icon-btn" title="Télécharger"><Icon name="download" size={14}/></button>
          </div>
        </div>

        <div style={{padding:"10px 14px", borderBottom:"1px solid var(--hairline)", background:"var(--surface-2)", display:"flex", alignItems:"center", gap:12, fontSize:12, color:"var(--muted)"}}>
          <span style={{display:"inline-flex", gap:6, alignItems:"center"}}>
            <Icon name="info" size={12}/>
            Cliquez un champ pour voir sa source. Cliquez une zone pour ouvrir le champ correspondant.
          </span>
          <span style={{marginLeft:"auto"}}><Legend/></span>
        </div>

        <div className="doc-canvas">
          {(() => {
            const docObj = docList.find((d) => d.id === activeDoc);
            if (docObj && docObj.url) {
              return <RealDoc doc={docObj} refs={realRefs} activeKey={activeField} onActivate={activate} />;
            }
            return (
              <>
                {activeDoc === "invoice" && <InvoiceDoc refs={docRefs} activeKey={activeField} onActivate={activate}/>}
                {activeDoc === "packing" && <PackingDoc refs={docRefs} activeKey={activeField} onActivate={activate}/>}
                {activeDoc === "email" && <EmailDoc refs={docRefs} activeKey={activeField} onActivate={activate}/>}
                {activeDoc === "photo" && <PhotoDoc refs={docRefs} activeKey={activeField} onActivate={activate}/>}
              </>
            );
          })()}
        </div>
      </div>

      {/* RIGHT — CMR form */}
      <div style={{display:"flex", flexDirection:"column", background:"var(--bg)", minWidth:0, overflow:"hidden"}}>
        <div style={{padding:"14px 18px", borderBottom:"1px solid var(--hairline)", display:"flex", alignItems:"center", gap:12, background:"var(--surface)"}}>
          <button className="icon-btn" onClick={onBack} title="Retour"><Icon name="arrow" size={14} style={{transform:"rotate(180deg)"}}/></button>
          <div>
            <div style={{fontSize:11, color:"var(--muted)", letterSpacing:"0.03em", textTransform:"uppercase"}}>Dossier CMR</div>
            <div style={{fontSize:15, fontWeight:600}}>{data.heroCase.ref}</div>
          </div>
          <StatusBadge status={data.heroCase.status}/>
          <div style={{marginLeft:"auto", display:"flex", gap:8, alignItems:"center", fontSize:12, color:"var(--muted)"}}>
            <span><b style={{color:"var(--ink)"}}>{Object.values(fields).filter(f => f.bucket === "hi").length + Object.keys(edited).length}</b>/{Object.keys(fields).length} champs validés</span>
            <div style={{width:80, height:5, borderRadius:99, background:"var(--bg-soft)", overflow:"hidden"}}>
              <div style={{width:`${data.heroCase.progress*100}%`, height:"100%", background:"var(--hi)"}}/>
            </div>
          </div>
        </div>

        <div style={{flex:1, overflow:"auto"}}>
          {/* Validation panel on top */}
          <ValidationPanel issues={data.heroCase.issues} fields={fields} onJump={(id)=>activate(id)}/>

          {/* PARTIES */}
          <Group title="Parties" count="4 boîtes">
            <div className="field-grid">
              <FieldCard id="sender" box="1" label="Expéditeur" value={fields.sender.value} conf={fields.sender.conf}
                status={renderConf("sender", fields.sender.conf)}
                active={activeField==="sender"} onActivate={activate} onEdit={editField}/>
              <FieldCard id="consignee" box="2" label="Destinataire" value={fields.consignee.value} conf={fields.consignee.conf}
                status={renderConf("consignee", fields.consignee.conf)}
                active={activeField==="consignee"} onActivate={activate} onEdit={editField}/>
              <FieldCard id="carrier" box="16" label="Transporteur" value={fields.carrier.value} conf={fields.carrier.conf}
                status={renderConf("carrier", fields.carrier.conf)}
                active={activeField==="carrier"} onActivate={activate} onEdit={editField}/>
              <FieldCard id="successive" box="17" label="Transporteurs successifs" value="" conf={null}
                placeholder="Aucun transporteur successif"
                active={activeField==="successive"} onActivate={activate} onEdit={editField}/>
            </div>
          </Group>

          {/* ROUTE */}
          <Group title="Itinéraire" count="2 boîtes">
            <div className="field-grid">
              <FieldCard id="placeOfTaking" box="4" label="Lieu de prise en charge" value={fields.placeOfTaking.value} conf={fields.placeOfTaking.conf}
                status={renderConf("placeOfTaking", fields.placeOfTaking.conf)}
                active={activeField==="placeOfTaking"} onActivate={activate} onEdit={editField}/>
              <FieldCard id="dateOfTaking" box="4" label="Date de prise en charge" value={fields.dateOfTaking.value} conf={fields.dateOfTaking.conf}
                status={renderConf("dateOfTaking", fields.dateOfTaking.conf)}
                active={activeField==="dateOfTaking"} onActivate={activate} onEdit={editField}/>
              <FieldCard id="placeOfDelivery" box="3" label="Lieu de livraison" value={fields.placeOfDelivery.value} conf={fields.placeOfDelivery.conf}
                status={renderConf("placeOfDelivery", fields.placeOfDelivery.conf)}
                active={activeField==="placeOfDelivery"} onActivate={activate} onEdit={editField}/>
            </div>
          </Group>

          {/* GOODS */}
          <Group title="Marchandises" count="4 lignes · boîtes 6–12" action={
            <button className="btn sm ghost" style={{marginLeft:"auto"}}><Icon name="plus" size={12}/> Ajouter une ligne</button>
          }>
            <GoodsTable rows={fields.goods} onActivate={(rowIdx, doc) => {
              const row = fields.goods[rowIdx];
              setActiveDoc(row.doc || "packing");
              setActiveField(`goods.${row.id}`);
            }}/>
            {(() => {
              const tot = goodsTotals(fields.goods);
              const fr = (n) => n.toLocaleString("fr-FR", { maximumFractionDigits: 2 });
              return (
                <div style={{marginTop:8, display:"flex", gap:14, fontSize:11.5, color:"var(--muted)", fontFamily:"var(--font-mono)"}}>
                  <span>Total colis : <b style={{color:"var(--ink-2)"}}>{fr(tot.packages)}</b></span>
                  <span>Poids brut total : <b style={{color:"var(--ink-2)"}}>{fr(tot.weight)} kg</b></span>
                  <span>Volume total : <b style={{color:"var(--ink-2)"}}>{fr(tot.volume)} m³</b></span>
                </div>
              );
            })()}
          </Group>

          {/* DOCUMENTS & INSTRUCTIONS */}
          <Group title="Documents & instructions" count="2 boîtes">
            <div className="field-grid cols-1">
              <FieldCard id="attachedDocs" box="5" label="Documents annexés" value={fields.attachedDocs.value} conf={fields.attachedDocs.conf}
                status={renderConf("attachedDocs", fields.attachedDocs.conf)} multiline
                active={activeField==="attachedDocs"} onActivate={activate} onEdit={editField}/>
              <FieldCard id="senderInstructions" box="13" label="Instructions de l'expéditeur" value={fields.senderInstructions.value} conf={fields.senderInstructions.conf}
                status={renderConf("senderInstructions", fields.senderInstructions.conf)} multiline
                active={activeField==="senderInstructions"} onActivate={activate} onEdit={editField}/>
            </div>
          </Group>

          {/* PAYMENT & CHARGES */}
          <Group title="Prix & frais" count="3 boîtes">
            <div className="field-grid">
              <FieldCard id="payment" box="14" label="Prix de transport (franco / non-franco)" value={fields.payment.value} conf={fields.payment.conf}
                status={renderConf("payment", fields.payment.conf)}
                active={activeField==="payment"} onActivate={activate} onEdit={editField}/>
              <FieldCard id="cashOnDelivery" box="15" label="Remboursement (cash on delivery)" value="" conf={null}
                placeholder="Aucun remboursement"
                active={activeField==="cashOnDelivery"} onActivate={activate} onEdit={editField}/>
            </div>
            <div style={{marginTop:10}}>
              <Label>À payer par <span className="mono" style={{color:"var(--muted-2)", fontSize:10}}>boîte 20</span></Label>
              <ChargesTable rows={data.heroCase.charges}/>
            </div>
          </Group>

          {/* RESERVATIONS */}
          <Group title="Réservations & conventions" count="2 boîtes">
            <div className="field-grid cols-1">
              <FieldCard id="reservations" box="18" label="Réservations du transporteur" value={fields.reservations.value} conf={fields.reservations.conf}
                status={renderConf("reservations", fields.reservations.conf)} multiline
                active={activeField==="reservations"} onActivate={activate} onEdit={editField}/>
              <FieldCard id="specialAgreements" box="19" label="Conventions particulières" value={fields.specialAgreements.value} conf={fields.specialAgreements.conf}
                status={renderConf("specialAgreements", fields.specialAgreements.conf)}
                active={activeField==="specialAgreements"} onActivate={activate} onEdit={editField}/>
            </div>
          </Group>

          {/* ISSUE */}
          <Group title="Établissement" count="boîtes 21–24">
            <div className="field-grid">
              <FieldCard id="placeOfIssue" box="21" label="Lieu d'établissement" value={fields.placeOfIssue.value} conf={fields.placeOfIssue.conf}
                status={renderConf("placeOfIssue", fields.placeOfIssue.conf)}
                active={activeField==="placeOfIssue"} onActivate={activate} onEdit={editField}/>
              <FieldCard id="dateOfIssue" box="21" label="Date d'établissement" value={fields.dateOfIssue.value} conf={fields.dateOfIssue.conf}
                status={renderConf("dateOfIssue", fields.dateOfIssue.conf)}
                active={activeField==="dateOfIssue"} onActivate={activate} onEdit={editField}/>
            </div>
            <div style={{marginTop:10, padding:10, background:"var(--surface-2)", border:"1px dashed var(--hairline-strong)", borderRadius:6, fontSize:12, color:"var(--muted)"}}>
              <Icon name="info" size={12}/> &nbsp; Signatures (boîtes 22–24) — apposées lors de l'enlèvement et de la livraison, laissées vierges sur le brouillon.
            </div>
          </Group>
        </div>

        {/* Sticky action bar */}
        <div className="action-bar">
          <div className="summary">
            <b>5</b> champs à vérifier · <b>{Object.keys(edited).length}</b> modifications manuelles · prêt à <b>78&nbsp;%</b>
          </div>
          <div style={{marginLeft:"auto", display:"flex", gap:8}}>
            <button className="btn"><Icon name="refresh" size={14}/> Régénérer</button>
            <button className="btn"><Icon name="save" size={14}/> Enregistrer le brouillon</button>
            <button className="btn accent" onClick={onApprove}><Icon name="check" size={14}/> Valider & générer le CMR</button>
          </div>
        </div>
      </div>
    </div>
  );
};

// ---- Goods table component ----
const GoodsTable = ({ rows, onActivate }) => {
  return (
    <table className="goods">
      <thead>
        <tr>
          <th style={{width:110}}>Marques<span className="num">6</span></th>
          <th style={{width:42}}>Col.<span className="num">7</span></th>
          <th style={{width:110}}>Emballage<span className="num">8</span></th>
          <th>Nature de la marchandise<span className="num">9</span></th>
          <th style={{width:78}}>SH<span className="num">10</span></th>
          <th style={{width:74, textAlign:"right"}}>kg<span className="num">11</span></th>
          <th style={{width:60, textAlign:"right"}}>m³<span className="num">12</span></th>
        </tr>
      </thead>
      <tbody>
        {rows.map((r, idx) => {
          const minConf = Math.min(r.marksConf, r.packagesConf, r.packingConf, r.natureConf, r.hsConf, r.weightConf, r.volumeConf);
          const cls = minConf >= 0.9 ? "hi" : minConf >= 0.7 ? "med" : "lo";
          return (
            <tr key={r.id} className={cls} onClick={()=>onActivate(idx)} style={{cursor:"pointer"}}>
              <td><span className="v mono" contentEditable suppressContentEditableWarning>{r.marks}</span></td>
              <td><span className="v" contentEditable suppressContentEditableWarning>{r.packages}</span></td>
              <td><span className="v" contentEditable suppressContentEditableWarning>{r.packing}</span></td>
              <td>
                <span className="v" contentEditable suppressContentEditableWarning>{r.nature}</span>
                {r.conflict && (
                  <div style={{marginTop:3, fontSize:10.5, color:"var(--conflict-ink)", display:"flex", gap:4, alignItems:"center"}}>
                    <Icon name="alert" size={10}/> Conflit poids ↗
                  </div>
                )}
              </td>
              <td>
                <span className={`v mono ${r.hsConf<0.7?"":""}`} contentEditable suppressContentEditableWarning style={{color: r.hsConf < 0.7 ? "var(--lo-ink)" : undefined}}>{r.hs}</span>
              </td>
              <td style={{textAlign:"right"}}>
                <span className="v mono" contentEditable suppressContentEditableWarning style={{color: r.weightConf < 0.7 ? "var(--lo-ink)" : undefined}}>{r.weight}</span>
                {r.conflict && r.conflict.field === "weight" && (
                  <div style={{fontSize:10, color:"var(--conflict-ink)", textDecoration:"line-through"}}>{r.conflict.other}</div>
                )}
              </td>
              <td style={{textAlign:"right"}}>
                <span className="v mono" contentEditable suppressContentEditableWarning style={{color: r.volumeConf < 0.7 ? "var(--lo-ink)" : undefined}}>{r.volume}</span>
              </td>
            </tr>
          );
        })}
      </tbody>
    </table>
  );
};

// ---- Charges table ----
const ChargesTable = ({ rows }) => (
  <table className="goods">
    <thead>
      <tr>
        <th>Libellé</th>
        <th style={{textAlign:"right", width:140}}>Payé par l'expéditeur</th>
        <th style={{textAlign:"right", width:140}}>Payé par le destinataire</th>
      </tr>
    </thead>
    <tbody>
      {rows.map((r, i) => (
        <tr key={i} style={r.bold?{background:"var(--surface-2)"}:undefined}>
          <td style={{fontWeight:r.bold?600:400}}>{r.label}</td>
          <td className="mono" style={{textAlign:"right", fontWeight:r.bold?600:400}}>{r.sender}</td>
          <td className="mono" style={{textAlign:"right", fontWeight:r.bold?600:400}}>{r.consignee}</td>
        </tr>
      ))}
    </tbody>
  </table>
);

// ---- Validation panel ----
const ValidationPanel = ({ issues, fields, onJump }) => {
  const [open, setOpen] = React.useState(true);
  return (
    <div style={{margin:"14px 16px 0", border:"1px solid var(--hairline)", borderRadius:8, background:"var(--surface)", overflow:"hidden"}}>
      <div style={{padding:"10px 12px", display:"flex", alignItems:"center", gap:10, borderBottom: open ? "1px solid var(--hairline)" : "0"}}>
        <Icon name="alert" size={14} style={{color:"var(--med)"}}/>
        <div style={{fontSize:12.5, fontWeight:600}}>{issues.length} points à vérifier</div>
        <div style={{fontSize:11.5, color:"var(--muted)"}}>· champs requis manquants & faibles confiances</div>
        <button className="btn sm ghost" style={{marginLeft:"auto"}} onClick={() => setOpen(!open)}>
          <Icon name={open?"chevD":"chev"} size={12}/> {open?"Réduire":"Voir"}
        </button>
      </div>
      {open && (
        <ul style={{margin:0, padding:0, listStyle:"none"}}>
          {issues.map((it, i) => (
            <li key={i}
              onClick={() => onJump(it.field.split(".")[0])}
              style={{display:"flex", alignItems:"start", gap:10, padding:"9px 12px", borderTop: i===0?"0":"1px solid var(--hairline)", cursor:"pointer", fontSize:12.5}}
            >
              <span className={`chip ${it.sev}`} style={{flex:"0 0 auto"}}>
                <span className="dot"></span>
                <span>{it.sev === "lo" ? "Faible" : "Moyenne"}</span>
              </span>
              <span style={{flex:1, color:"var(--ink-2)"}}>{it.msg}</span>
              <span className="mono" style={{color:"var(--muted-2)", fontSize:11}}>{it.field}</span>
              <Icon name="chev" size={12} style={{color:"var(--muted-2)"}}/>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
};

window.ReviewView = ReviewView;
