// ──────────────────────────── Documenti ────────────────────────────

const { useState: useStateD, useMemo: useMemoD } = React;

// Helper salvataggio documenti: crea un documento (risolve nome cliente/fornitore
// e totale dalle righe) o ne cambia lo stato, mostrando un toast di conferma.
const _docCreate = (kind, testata, lines, status, msg) => {
  const header = { ...testata, status };
  if (testata.customerId && typeof CUSTOMERS !== 'undefined') {
    const c = CUSTOMERS.find(x => x.id === testata.customerId); if (c) header.customer = c.name;
  }
  if (testata.supplierId && typeof SUPPLIERS !== 'undefined') {
    const s = SUPPLIERS.find(x => x.id === testata.supplierId); if (s) header.supplier = s.name;
  }
  if (lines && lines.length && header.total == null) {
    header.total = Math.round(lines.reduce((s, l) => s + (l.qty || 0) * (l.unitPrice || l.price || 0) * (1 - ((l.discount || 0) / 100)), 0) * 100) / 100;
  }
  if (window.__API__) {
    window.__API__.mutate('/api/documents/create', { kind, header, lines: lines || null })
      .then(() => { if (window.__toast) window.__toast(msg, 'success'); }).catch(() => {});
  }
};
const _docStatus = (kind, id, status, msg) => {
  if (window.__API__) {
    window.__API__.mutate('/api/documents/status', { kind, id, status })
      .then(() => { if (window.__toast) window.__toast(msg, 'success'); }).catch(() => {});
  }
};

const DOC_TYPES = [
  { id: 'Tutti',        label: 'Tutti',          count: DOCUMENTS.length },
  { id: 'Scontrino',    label: 'Scontrini',      count: DOCUMENTS.filter(d=>d.type==='Scontrino').length },
  { id: 'Fattura',      label: 'Fatture',        count: DOCUMENTS.filter(d=>d.type==='Fattura').length },
  { id: 'Ordine',       label: 'Ordini',         count: DOCUMENTS.filter(d=>d.type==='Ordine').length },
  { id: 'DDT',          label: 'DDT',            count: DOCUMENTS.filter(d=>d.type==='DDT').length },
  { id: 'Nota credito', label: 'Note di credito',count: DOCUMENTS.filter(d=>d.type==='Nota credito').length },
];

// Tipi visibili al Magazziniere: solo documenti legati alla movimentazione merce
const MERCE_TYPE_IDS = ['Ordine', 'DDT', 'Nota credito'];

const DocStatusPill = ({ status }) => {
  if (status === 'Emesso')         return <Pill tone="pos">{status}</Pill>;
  if (status === 'Emessa')         return <Pill tone="pos">{status}</Pill>;
  if (status === 'Inviata SDI')    return <Pill tone="info">{status}</Pill>;
  if (status === 'In viaggio')     return <Pill tone="warn">{status}</Pill>;
  if (status === 'In lavorazione') return <Pill tone="warn">{status}</Pill>;
  return <Pill tone="neutral">{status}</Pill>;
};

// Mappa tipo documento → icona + colore semantico (riconoscibile a colpo d'occhio).
//  verde=incasso/vendita · blu=fattura · rosso=nota credito (storno) · arancio=DDT/logistica
//  viola=ordine · indaco=riserva · grigio=fornitore
const DOC_TYPE_META = {
  'Scontrino':              { icon: 'Receipt', fg: 'var(--success-700)',   bg: 'var(--success-50)' },
  'Fattura':                { icon: 'Doc',     fg: 'var(--accent-blue)',   bg: 'rgba(0,122,255,0.12)' },
  'Fattura cliente':        { icon: 'Doc',     fg: 'var(--accent-blue)',   bg: 'rgba(0,122,255,0.12)' },
  'Nota credito':           { icon: 'Return',  fg: 'var(--danger-700)',    bg: 'var(--danger-50)' },
  'Nota credito fornitore': { icon: 'Return',  fg: 'var(--danger-700)',    bg: 'var(--danger-50)' },
  'Ordine':                 { icon: 'Box',     fg: 'var(--accent-purple)', bg: 'rgba(175,82,222,0.13)' },
  'Ordine cliente':         { icon: 'Box',     fg: 'var(--accent-purple)', bg: 'rgba(175,82,222,0.13)' },
  'Riservato':              { icon: 'Tag',     fg: 'var(--accent-indigo)', bg: 'rgba(88,86,214,0.13)' },
  'DDT':                    { icon: 'Truck',   fg: 'var(--warning-700)',   bg: 'var(--warning-50)' },
  'DDT cliente':            { icon: 'Truck',   fg: 'var(--warning-700)',   bg: 'var(--warning-50)' },
  'Fattura fornitore':      { icon: 'Doc',     fg: 'var(--text-secondary)', bg: 'var(--bg-hover)' },
};
const docTypeMeta = (type) => DOC_TYPE_META[type] || { icon: 'Doc', fg: 'var(--text-secondary)', bg: 'var(--bg-hover)' };

// Icona del tipo dentro un chip colorato (usata nelle righe e nei tab famiglia).
const DocTypeIcon = ({ type, size = 16, chip = false }) => {
  const m = docTypeMeta(type);
  const Ico = I[m.icon] || I.Doc;
  if (!chip) return <Ico size={size}/>;
  const box = size + 16;
  return (
    <span className="rounded-lg flex items-center justify-center shrink-0" style={{ width: box, height: box, background: m.bg, color: m.fg }}>
      <Ico size={size}/>
    </span>
  );
};

// Helpers: compute totals from lines
const computeTotals = (lines) => {
  let subtotal = 0, discount = 0;
  lines.forEach(l => {
    const gross = l.price * l.qty;
    subtotal += gross;
    discount += gross * ((l.discount || 0) / 100);
  });
  const totalGross = subtotal - discount;
  const tax = totalGross - (totalGross / 1.22);
  return { subtotal, discount, totalGross, tax, net: totalGross - tax };
};

// ───────────────────────────── List + Preview ─────────────────────────
const _NEW_DOC_TYPES = ['Ordine cliente', 'Riservato', 'Fattura cliente', 'DDT cliente', 'Fattura fornitore', 'Nota credito fornitore'];

// I 10 tipi raggruppati in 3 FAMIGLIE (meno caos): si sceglie prima la famiglia,
// poi si filtra il tipo dentro la famiglia. Ogni voce ha id + label.
// `new:true` = tipo "nuovo" con sezione dedicata; altrimenti filtra DOCUMENTS per d.type.
const DOC_FAMILIES_UI = [
  { id: 'vendite',  label: 'Vendite',  icon: 'Receipt', types: [
    { id: 'Scontrino', label: 'Scontrini' },
    { id: 'Fattura', label: 'Fatture' },
    { id: 'Fattura cliente', label: 'Fatture cliente', new: true },
    { id: 'Nota credito', label: 'Note di credito' },
  ]},
  { id: 'ordini',   label: 'Ordini & Riserve', icon: 'Box', types: [
    { id: 'Ordine cliente', label: 'Ordini cliente', new: true },
    { id: 'Riservato', label: 'Riservati', new: true },
    { id: 'Ordine', label: 'Ordini' },
  ]},
  { id: 'logistica', label: 'Logistica', icon: 'Truck', types: [
    { id: 'DDT', label: 'DDT' },
    { id: 'DDT cliente', label: 'DDT cliente', new: true },
  ]},
  { id: 'fornitori', label: 'Fornitori', icon: 'Doc', types: [
    { id: 'Fattura fornitore', label: 'Fatture fornitore', new: true },
    { id: 'Nota credito fornitore', label: 'Note credito fornitore', new: true },
  ]},
];
const _countFor = (typeId) => {
  switch (typeId) {
    case 'Ordine cliente':  return (typeof CUSTOMER_ORDERS !== 'undefined' ? CUSTOMER_ORDERS : []).length;
    case 'Riservato':       return (typeof CUSTOMER_RESERVES !== 'undefined' ? CUSTOMER_RESERVES : []).length;
    case 'Fattura cliente': return (typeof CUSTOMER_INVOICES !== 'undefined' ? CUSTOMER_INVOICES : []).length;
    case 'DDT cliente':     return (typeof DDT_CLIENTI !== 'undefined' ? DDT_CLIENTI : []).length;
    case 'Fattura fornitore':      return (typeof SUPPLIER_INVOICES !== 'undefined' ? SUPPLIER_INVOICES : []).length;
    case 'Nota credito fornitore': return (typeof SUPPLIER_CREDIT_NOTES !== 'undefined' ? SUPPLIER_CREDIT_NOTES : []).length;
    default: return (typeof DOCUMENTS !== 'undefined' ? DOCUMENTS : []).filter(d => d.type === typeId).length;
  }
};
// Famiglie visibili per ruolo (Magazziniere: solo Logistica; Cassiere: niente Fornitori).
const _visibleFamilies = (role) => DOC_FAMILIES_UI.filter(f =>
  role === 'Magazziniere' ? f.id === 'logistica' : role === 'Cassiere' ? f.id !== 'fornitori' : true);
// Tipo di default entrando in una famiglia: "Tutti" se ha ≥2 tipi classici, altrimenti il primo.
const _defaultTypeFor = (fam) => {
  const classics = fam.types.filter(t => !t.new).map(t => t.id);
  return classics.length > 1 ? 'Tutti' : fam.types[0].id;
};

const DocumentiView = ({ role }) => {
  const isMagazziniere = role === 'Magazziniere';
  const isCassiere     = role === 'Cassiere';
  const _initFam = _visibleFamilies(role)[0] || DOC_FAMILIES_UI[0];
  const [family, setFamily] = useStateD(_initFam.id);
  const [type, setType] = useStateD(() => _defaultTypeFor(_initFam));
  const [q, setQ] = useStateD('');
  const [range, setRange] = useStateD('30g');
  const [selected, setSelected] = useStateD(null); // null = nessuna anteprima aperta

  // Famiglie visibili per ruolo (con conteggio totale).
  const families = useMemoD(() => _visibleFamilies(role)
    .map(f => ({ ...f, count: f.types.reduce((s, t) => s + _countFor(t.id), 0) })), [role]);

  const activeFamily = families.find(f => f.id === family) || families[0];
  // tipi della famiglia attiva (con "Tutti" = aggregato dei tipi classici della famiglia)
  const famTypes = activeFamily ? activeFamily.types : [];
  const classicTypesInFam = famTypes.filter(t => !t.new).map(t => t.id);

  const isNewType = _NEW_DOC_TYPES.includes(type);

  const filtered = useMemoD(() => {
    if (isNewType) return [];
    const ql = q.trim().toLowerCase();
    const allowed = type === 'Tutti' ? classicTypesInFam : [type];
    return DOCUMENTS.filter(d => {
      if (!allowed.includes(d.type)) return false;
      if (ql && !(d.id.toLowerCase().includes(ql) || (d.customer || '').toLowerCase().includes(ql))) return false;
      return true;
    });
  }, [type, q, isNewType, family]);

  // Anteprima SOLO se l'utente ha cliccato un documento (niente apertura di default).
  const doc = useMemoD(() => {
    if (isNewType || !selected) return null;
    return filtered.find(d => d.id === selected) || null;
  }, [selected, filtered, isNewType]);

  // sotto-tab tipo nella famiglia: "Tutti" + ogni tipo, con conteggio
  const subTabs = activeFamily ? [
    ...(classicTypesInFam.length > 1 ? [{ id: 'Tutti', label: 'Tutti', count: classicTypesInFam.reduce((s, t) => s + _countFor(t), 0) }] : []),
    ...famTypes.map(t => ({ id: t.id, label: t.label, count: _countFor(t.id) })),
  ] : [];

  // quando si cambia famiglia, riparti dal primo tipo sensato
  const switchFamily = (fid) => {
    const f = families.find(x => x.id === fid);
    if (!f) return;
    setFamily(fid);
    setType(_defaultTypeFor(f));
  };

  return (
    <>
      <Topbar
        eyebrow={`Documenti · ${STORE.name}`}
        title="Documenti"
        right={!isNewType && (
          <>
            <Btn variant="outline" size="md" leading={<I.ArrowD size={16}/>}
              onClick={() => window.__csv && window.__csv(
                'documenti.csv',
                ['Numero', 'Tipo', 'Data', 'Ora', 'Cliente', 'Stato', 'Importo'],
                filtered.map(d => [d.id, d.type, d.date, d.time || '', d.customer || '', d.status, d.total])
              )}>Esporta elenco</Btn>
            <Btn variant="ink" size="md" leading={<I.Plus size={16}/>}
              onClick={() => isMagazziniere
                ? (window.__toast && window.__toast('Crea ordini e DDT dalla sezione Acquisti', 'info'))
                : (setFamily('ordini'), setType('Ordine cliente'))}>Nuovo documento</Btn>
          </>
        )}
      />

      {/* Famiglie (livello 1): pochi tab grandi, niente più overflow caotico */}
      <div className="px-7 pt-3 bg-paper">
        <div className="flex items-center gap-2 flex-wrap">
          {families.map(f => {
            const active = family === f.id;
            const Ico = I[f.icon] || I.Doc;
            return (
              <button key={f.id} onClick={() => switchFamily(f.id)}
                className={`focus-ring flex items-center gap-2.5 h-11 px-4 rounded-xl text-[14px] font-semibold transition-all duration-fast ease-standard
                  ${active ? 'bg-[var(--accent-blue)] text-[var(--text-inverse)] shadow-soft' : 'bg-surface text-ink shadow-sm hover:shadow-md'}`}>
                <Ico size={17}/>
                {f.label}
                <span className={`num text-[11px] px-1.5 py-0.5 rounded ${active ? 'bg-white/20 text-[var(--text-inverse)]' : 'bg-line2 text-muted'}`}>{f.count}</span>
              </button>
            );
          })}
        </div>
      </div>

      {/* Tipi della famiglia (livello 2): sotto-filtro */}
      <div className="px-7 hairline bg-paper">
        <div className="flex items-center gap-1 overflow-x-auto">
          {subTabs.map(t => {
            const active = type === t.id;
            return (
              <button key={t.id} onClick={()=>setType(t.id)}
                className={`flex items-center gap-2 h-10 px-3 text-[13px] font-medium transition-all duration-fast ease-standard border-b-2 -mb-px whitespace-nowrap
                  ${active ? 'text-ink border-ink' : 'text-muted border-transparent hover:text-ink'}`}>
                {t.id !== 'Tutti' && <DocTypeIcon type={t.id} size={13}/>}
                {t.label}
                <span className={`num text-[10.5px] px-1.5 py-0.5 rounded ${active ? 'bg-[var(--bg-selected)] text-[var(--accent-blue)]' : 'bg-line2 text-muted'}`}>{t.count}</span>
              </button>
            );
          })}
        </div>
      </div>

      {/* Nuovo tipo: delega alla sezione dedicata */}
      {isNewType ? (
        type === 'Ordine cliente'         ? <OrdineClienteSection/> :
        type === 'Riservato'              ? <RiservatoSection/> :
        type === 'Fattura cliente'        ? <FatturaClienteSection/> :
        type === 'DDT cliente'            ? <DDTClienteSection/> :
        type === 'Fattura fornitore'      ? <FatturaFornitoreSection/> :
                                           <NotaCreditoFornitoreSection/>
      ) : (
        /* Tipi classici: master-detail esistente */
        <div className="px-7 py-5 max-w-[1600px]">
          <div className="bg-surface rounded-2xl p-3.5 shadow-soft mb-4">
            <div className="flex flex-wrap items-center gap-2.5">
              <div className="relative flex-1 min-w-[260px]">
                <I.Search size={18} className="absolute left-3.5 top-1/2 -translate-y-1/2 text-muted"/>
                <input value={q} onChange={(e)=>setQ(e.target.value)}
                  placeholder="Cerca per numero documento o cliente…"
                  className="w-full h-11 pl-11 pr-4 rounded-md bg-sunken text-[14px] shadow-[inset_0_0_0_0.5px_var(--border-default)] focus:bg-surface focus:shadow-[var(--shadow-focus),inset_0_0_0_1px_var(--accent-blue)] transition-all duration-fast ease-standard"/>
              </div>
              <FilterSelect label="Periodo" value={range} onChange={setRange} options={[
                { v:'oggi', l:'Oggi' }, { v:'7g', l:'Ultimi 7 giorni' }, { v:'30g', l:'Ultimi 30 giorni' }, { v:'mese', l:'Questo mese' }, { v:'anno', l:'Quest\'anno' }
              ]}/>
              <span className="ml-auto text-[13px] text-muted">
                <span className="num text-ink font-medium">{filtered.length}</span> documenti
              </span>
            </div>
          </div>

          <div className={`grid grid-cols-1 gap-5 ${doc ? 'xl:grid-cols-[minmax(0,1fr)_520px]' : ''}`}>
            <Card padded={false}>
              <div className="max-h-[calc(100vh-310px)] overflow-auto">
                <table className="w-full text-[13.5px]">
                  <thead className="sticky top-0 bg-surface z-10">
                    <tr className="text-left text-muted uppercase text-[11px] tracking-[0.08em] hairline">
                      <th className="px-4 py-3 font-medium">Numero</th>
                      <th className="px-4 py-3 font-medium">Tipo</th>
                      <th className="px-4 py-3 font-medium">Data</th>
                      <th className="px-4 py-3 font-medium">Cliente</th>
                      <th className="px-4 py-3 font-medium">Stato</th>
                      <th className="px-4 py-3 font-medium text-right">Importo</th>
                    </tr>
                  </thead>
                  <tbody>
                    {filtered.map(d => {
                      const isSel = doc?.id === d.id;
                      return (
                        <tr key={d.id} onClick={()=>setSelected(d.id)}
                          className={`border-b border-line2 last:border-0 cursor-pointer transition-all duration-fast ease-standard
                            ${isSel ? 'bg-[var(--bg-selected)]' : 'hover:bg-paper'}`}>
                          <td className="px-4 py-2.5 num font-medium text-ink whitespace-nowrap">
                            <div className="flex items-center gap-2">
                              <span className={`w-1 h-5 rounded-full shrink-0 ${isSel ? 'bg-[var(--accent-blue)]' : 'bg-transparent'}`}/>
                              <span>{d.id}</span>
                            </div>
                          </td>
                          <td className="px-4 py-2.5">
                            <span className="inline-flex items-center gap-2.5 text-ink">
                              <DocTypeIcon type={d.type} size={15} chip/>
                              <span className="font-medium">{d.type}</span>
                              {d.taxfree && <Pill tone="info"><I.Globe size={10}/></Pill>}
                            </span>
                          </td>
                          <td className="px-4 py-2.5 num text-[12.5px] text-muted whitespace-nowrap">
                            {d.date}{d.time ? <span className="text-[var(--text-tertiary)]"> · {d.time}</span> : ''}
                          </td>
                          <td className="px-4 py-2.5 text-ink"><span className="block truncate max-w-[180px]">{d.customer || <span className="text-muted">—</span>}</span></td>
                          <td className="px-4 py-2.5"><DocStatusPill status={d.status}/></td>
                          <td className={`px-4 py-2.5 num text-right font-semibold whitespace-nowrap ${d.total < 0 ? 'text-neg' : 'text-ink'}`}>
                            {d.total === 0 ? '—' : fmtEur(d.total)}
                          </td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
                {filtered.length === 0 && (
                  <div className="py-16 text-center text-muted text-[14px]">Nessun documento corrisponde ai filtri.</div>
                )}
              </div>
            </Card>

            {doc && (
              <div className="self-start">
                <DocPreviewPanel doc={doc} onClose={() => setSelected(null)}/>
              </div>
            )}
          </div>
        </div>
      )}
    </>
  );
};

// ───────────────────────────── Preview panel ─────────────────────────
const DocPreviewPanel = ({ doc, onClose }) => {
  if (!doc) {
    return (
      <Card>
        <div className="py-12 text-center text-muted">Seleziona un documento dall'elenco per vedere l'anteprima.</div>
      </Card>
    );
  }

  const totals = computeTotals(doc.lines || []);
  const isCredit = doc.type === 'Nota credito';
  const isOrder = doc.type === 'Ordine';
  const isDDT = doc.type === 'DDT';
  const isInvoice = doc.type === 'Fattura';
  const isReceipt = doc.type === 'Scontrino';
  const customer = doc.customerId ? CUSTOMERS.find(c => c.id === doc.customerId) : null;

  // Export PDF mirato del documento classico (scontrino/fattura/ordine/DDT/NC).
  const exportDocPdf = () => {
    const esc = (s) => String(s == null ? '' : s).replace(/[&<>]/g, ch => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' }[ch]));
    const meta = [
      ['Tipo', doc.type], ['Numero', doc.id], ['Data', doc.date || doc.time || '—'],
      ['Cliente', (customer && customer.name) || doc.customer || '—'], ['Stato', doc.status || '—'],
    ].map(([l, v]) => `<div><span class="l">${esc(l)}</span><span>${esc(v)}</span></div>`).join('');
    const rows = (doc.lines || []).map(l => {
      const price = l.price != null ? l.price : (l.unitPrice || 0);
      const qty = l.qty || 0;
      return `<tr><td>${esc(l.name || l.sku || '')}</td><td class="n">${esc(qty)}</td><td class="n">${esc(fmtEur(price))}</td><td class="n">${esc(fmtEur(price * qty))}</td></tr>`;
    }).join('');
    const tot = (totals && totals.total != null) ? totals.total : (doc.total || 0);
    const html =
      `<div class="row"><h1>${esc(doc.type || 'Documento')}</h1><div style="text-align:right"><div class="brand">EASY2SELL</div><div class="muted">${esc(doc.id || '')}</div></div></div>` +
      `<div class="meta">${meta}</div>` +
      `<table><thead><tr><th>Descrizione</th><th class="n">Q.tà</th><th class="n">Prezzo</th><th class="n">Totale</th></tr></thead><tbody>${rows}</tbody></table>` +
      `<div class="tot"><span class="muted">Totale</span><span>${esc(fmtEur(tot))}</span></div>`;
    if (window.__printDoc) window.__printDoc(`${doc.type || 'Documento'} ${doc.id || ''}`, html);
  };

  return (
    <div className="bg-surface rounded-2xl shadow-soft overflow-hidden flex flex-col" style={{ maxHeight: 'calc(100vh - 318px)' }}>
      {/* Header bar */}
      <header className="px-5 py-4 hairline flex items-center justify-between bg-surface shrink-0">
        <div className="flex items-center gap-2.5">
          <DocTypeIcon type={doc.type} size={16} chip/>
          <div>
            <div className="text-[12px] uppercase tracking-[0.08em] text-muted font-medium">{doc.type}</div>
            <div className="num text-[14px] font-semibold text-ink leading-tight">{doc.id}</div>
          </div>
        </div>
        <div className="flex items-center gap-2">
          <DocStatusPill status={doc.status}/>
          {onClose && (
            <button onClick={onClose} title="Chiudi anteprima"
              className="focus-ring w-8 h-8 rounded-lg flex items-center justify-center text-muted hover:text-ink hover:bg-[var(--bg-hover)] transition-colors">
              <I.X size={16}/>
            </button>
          )}
        </div>
      </header>

      {/* Document body — printable look */}
      <div className="flex-1 overflow-auto bg-paper">
        {/* "Paper" canvas */}
        <div className="m-5 bg-surface rounded-md shadow-soft">
          {/* Choose layout */}
          {isReceipt || isCredit ? <ReceiptLayout doc={doc} totals={totals} isCredit={isCredit}/> :
           isInvoice              ? <InvoiceLayout doc={doc} totals={totals} customer={customer}/> :
           isOrder                ? <OrderLayout   doc={doc} totals={totals} customer={customer}/> :
           isDDT                  ? <DdtLayout     doc={doc}/> :
                                    <InvoiceLayout doc={doc} totals={totals} customer={customer}/>
          }
        </div>
      </div>

      {/* Action footer */}
      <div className="p-4 border-t border-line bg-surface">
        <div className="grid grid-cols-2 gap-2 mb-2">
          <Btn variant="outline" size="lg" leading={<I.Receipt size={16}/>}
            onClick={exportDocPdf}>Ristampa</Btn>
          <Btn variant="ink" size="lg" leading={<I.ArrowD size={16}/>}
            onClick={exportDocPdf}>Esporta PDF</Btn>
        </div>
        {(isReceipt || isInvoice) && (
          <Btn variant="ghost" size="md" className="w-full" leading={<I.Return size={16}/>}
            onClick={() => _docCreate('CUSTOMER_CREDIT_NOTE',
              { customerId: doc.customerId, customer: doc.customer, refDoc: doc.id, total: -Math.abs(doc.total), payment: doc.payment },
              (doc.lines || []).map(l => ({ ...l, unitPrice: l.price })),
              'Emessa', 'Nota di credito creata')}>
            Crea nota di credito
          </Btn>
        )}
        {isOrder && (
          <Btn variant="success" size="md" className="w-full" leading={<I.Check size={16}/>}
            onClick={() => _docStatus('CUSTOMER_ORDER', doc.id, 'Evaso', 'Ordine evaso')}>
            Evadi ordine
          </Btn>
        )}
      </div>
    </div>
  );
};

// ─── Receipt layout (Scontrino / Nota credito) ───
// Dati azienda REALI (impostazioni persistite, iniettate dal server in __BI_COMPANY__).
const company = () => (window.__BI_COMPANY__ || {});
const companyFiscalLine = () => {
  const c = company();
  const parts = [];
  if (c.piva) parts.push('P.IVA ' + c.piva);
  if (c.tel) parts.push('Tel. ' + c.tel);
  return parts.join(' · ') || '—';
};

const ReceiptLayout = ({ doc, totals, isCredit }) => {
  const c = company();
  return (
    <div className="p-7 num text-[12.5px] text-ink" style={{ fontFamily: '"Geist Mono", ui-monospace, monospace', letterSpacing: '-0.01em' }}>
      {/* Store header */}
      <div className="text-center pb-3 border-b border-dashed border-line">
        <div className="text-[13px] font-semibold tracking-wider uppercase">{c.ragioneSociale || STORE.name}</div>
        <div className="text-[11px] text-muted mt-0.5">{[c.via, c.citta].filter(Boolean).join(', ') || STORE.address}</div>
        <div className="text-[11px] text-muted">{companyFiscalLine()}</div>
      </div>

      {/* Title */}
      <div className="text-center py-3 border-b border-dashed border-line">
        <div className="text-[13px] font-semibold uppercase tracking-wider">
          {isCredit ? 'Nota di credito' : 'Documento commerciale di vendita'}
        </div>
        <div className="text-[11px] text-muted mt-0.5">
          n. <span className="text-ink">{doc.id}</span> · {doc.date} · {doc.time}
        </div>
        {doc.refDoc && (
          <div className="text-[11px] text-muted mt-1">Rif. documento originale: <span className="text-ink">{doc.refDoc}</span></div>
        )}
      </div>

      {/* Lines */}
      <div className="py-3 border-b border-dashed border-line space-y-1.5">
        {(doc.lines || []).map((l, i) => {
          const gross = l.price * l.qty;
          const disc = gross * ((l.discount || 0) / 100);
          const net = gross - disc;
          return (
            <div key={i}>
              <div className="text-[12.5px] leading-tight">{l.name}</div>
              <div className="flex items-baseline justify-between text-[11.5px] text-muted leading-tight">
                <span>{l.qty} × {fmtEur(l.price)}{l.discount ? ` · −${l.discount}%` : ''}</span>
                <span className="text-ink">{isCredit ? '−' : ''}{fmtEur(net)}</span>
              </div>
            </div>
          );
        })}
      </div>

      {/* Totals */}
      <div className="py-3 border-b border-dashed border-line space-y-1">
        <Row k="Subtotale" v={fmtEur(totals.subtotal)} />
        {totals.discount > 0 && <Row k="Sconti" v={`−${fmtEur(totals.discount)}`} />}
        <Row k="IVA inclusa 22%" v={fmtEur(totals.tax)} />
      </div>
      <div className="pt-3 flex items-baseline justify-between border-b border-dashed border-line pb-3">
        <span className="text-[14px] font-semibold uppercase tracking-wider">{isCredit ? 'Rimborso' : 'Totale'}</span>
        <span className="text-[20px] font-semibold">{isCredit ? '−' : ''}{fmtEur(Math.abs(doc.total))}</span>
      </div>

      {/* Payment */}
      <div className="py-3 border-b border-dashed border-line space-y-1">
        <Row k={isCredit ? 'Rimborso in' : 'Pagamento'} v={doc.payment} />
        {doc.taxfree && <Row k="Tax-free emesso" v="Global Blue" />}
      </div>

      {/* Footer */}
      <div className="pt-3 text-center text-[10.5px] text-muted leading-relaxed">
        Documento conservato sul portale Agenzia Entrate · ID trasmissione 26052102871.<br/>
        Grazie. La merce può essere cambiata o resa entro 14 giorni con scontrino e cartellino integri.
      </div>
    </div>
  );
};

const Row = ({ k, v }) => (
  <div className="flex items-baseline justify-between">
    <span className="text-muted">{k}</span>
    <span className="text-ink">{v}</span>
  </div>
);

// ─── Invoice layout (Fattura) ───
const InvoiceLayout = ({ doc, totals, customer }) => {
  return (
    <div className="p-8">
      {/* Top header */}
      <div className="flex items-start justify-between pb-5 border-b-2 border-ink">
        <div>
          <div className="w-9 h-9 rounded-sm bg-[var(--bg-selected)] text-[var(--accent-blue)] flex items-center justify-center mb-2">
            <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="1.6"><path d="M5 4h9l5 5v11H5z"/><path d="M14 4v5h5"/></svg>
          </div>
          <div className="text-[14px] font-semibold text-ink leading-tight">{company().ragioneSociale || STORE.name}</div>
          <div className="text-[11.5px] text-muted leading-snug mt-0.5">
            {[company().via, [company().cap, company().citta, company().provincia && '(' + company().provincia + ')'].filter(Boolean).join(' ')].filter(Boolean).join(', ') || STORE.address}<br/>
            {[company().piva && 'P.IVA ' + company().piva, company().cf && 'C.F. ' + company().cf].filter(Boolean).join(' · ') || '—'}<br/>
            {[company().tel && 'Tel ' + company().tel, company().email].filter(Boolean).join(' · ')}
          </div>
        </div>
        <div className="text-right">
          <div className="text-[11px] uppercase tracking-[0.1em] text-muted font-medium">Fattura elettronica</div>
          <div className="num text-[20px] font-semibold text-ink mt-0.5">{doc.id}</div>
          <div className="text-[12px] text-muted mt-1">
            Data <span className="text-ink num">{doc.date}</span><br/>
            Trasmessa SDI · ID <span className="num text-ink">2605210281</span>
          </div>
        </div>
      </div>

      {/* Customer block */}
      <div className="grid grid-cols-2 gap-6 py-5 border-b border-line">
        <div>
          <div className="text-[10.5px] uppercase tracking-[0.1em] text-muted font-medium mb-2">Cliente</div>
          {customer ? (
            <>
              <div className="text-[14px] font-semibold text-ink">{customer.fiscal.name}</div>
              <div className="text-[12px] text-muted mt-0.5 leading-relaxed">
                {customer.fiscal.address}<br/>
                P.IVA <span className="num text-ink">{customer.fiscal.vat}</span><br/>
                C.F. <span className="num text-ink">{customer.fiscal.cf}</span>
                {customer.fiscal.sdi && <><br/>SDI <span className="num text-ink">{customer.fiscal.sdi}</span></>}
              </div>
            </>
          ) : (
            <div className="text-[12.5px] text-muted">Cliente non specificato</div>
          )}
        </div>
        <div>
          <div className="text-[10.5px] uppercase tracking-[0.1em] text-muted font-medium mb-2">Modalità di pagamento</div>
          <div className="text-[13px] text-ink">{doc.payment}</div>
          <div className="text-[12px] text-muted mt-2">Scadenza: 30 gg fine mese · IBAN IT 76 X 03069 09606 ********</div>
        </div>
      </div>

      {/* Lines table */}
      <table className="w-full text-[12.5px] mt-5">
        <thead>
          <tr className="border-b-2 border-strong text-left text-[10.5px] uppercase tracking-[0.08em] text-muted font-medium">
            <th className="py-2 font-medium">Descrizione</th>
            <th className="py-2 font-medium text-right">Q.tà</th>
            <th className="py-2 font-medium text-right">Prezzo</th>
            <th className="py-2 font-medium text-right">Sconto</th>
            <th className="py-2 font-medium text-right">Importo</th>
            <th className="py-2 font-medium text-right">IVA</th>
          </tr>
        </thead>
        <tbody>
          {(doc.lines || []).map((l, i) => {
            const gross = l.price * l.qty;
            const disc = gross * ((l.discount || 0) / 100);
            const net = gross - disc;
            return (
              <tr key={i} className="border-b border-line2">
                <td className="py-2.5 text-ink">{l.name}</td>
                <td className="py-2.5 num text-ink text-right">{l.qty}</td>
                <td className="py-2.5 num text-ink text-right">{fmtEur(l.price)}</td>
                <td className="py-2.5 num text-right text-muted">{l.discount ? `${l.discount}%` : '—'}</td>
                <td className="py-2.5 num text-ink text-right font-medium">{fmtEur(net)}</td>
                <td className="py-2.5 num text-muted text-right">22%</td>
              </tr>
            );
          })}
        </tbody>
      </table>

      {/* Totals */}
      <div className="mt-4 flex justify-end">
        <div className="w-[280px] text-[13px]">
          <div className="flex justify-between py-1.5">
            <span className="text-muted">Imponibile</span>
            <span className="num text-ink">{fmtEur(totals.net)}</span>
          </div>
          <div className="flex justify-between py-1.5">
            <span className="text-muted">IVA 22%</span>
            <span className="num text-ink">{fmtEur(totals.tax)}</span>
          </div>
          {totals.discount > 0 && (
            <div className="flex justify-between py-1.5 border-t border-line2">
              <span className="text-muted">Sconti totali</span>
              <span className="num text-neg">−{fmtEur(totals.discount)}</span>
            </div>
          )}
          <div className="flex justify-between py-3 mt-1.5 border-t-2 border-ink">
            <span className="text-[14px] font-semibold text-ink">Totale fattura</span>
            <span className="num text-[18px] font-semibold text-ink">{fmtEur(doc.total)}</span>
          </div>
        </div>
      </div>

      <div className="mt-6 pt-3 border-t border-line2 text-[10.5px] text-muted leading-relaxed">
        Documento conforme al D.M. 17/06/2014 · Operazione soggetta a IVA secondo D.P.R. 633/72.
      </div>
    </div>
  );
};

// ─── Order layout ───
const OrderLayout = ({ doc, totals, customer }) => {
  const advance = doc.advance || 0;
  const balance = doc.total - advance;
  return (
    <div className="p-8">
      <div className="flex items-start justify-between pb-5 border-b-2 border-ink">
        <div>
          <div className="text-[14px] font-semibold text-ink">{STORE.name}</div>
          <div className="text-[11.5px] text-muted mt-0.5">{STORE.address}</div>
        </div>
        <div className="text-right">
          <div className="text-[11px] uppercase tracking-[0.1em] text-muted font-medium">Conferma d'ordine</div>
          <div className="num text-[20px] font-semibold text-ink mt-0.5">{doc.id}</div>
          <div className="text-[12px] text-muted mt-1">Emesso il <span className="num text-ink">{doc.date}</span></div>
        </div>
      </div>

      <div className="grid grid-cols-2 gap-6 py-5 border-b border-line">
        <div>
          <div className="text-[10.5px] uppercase tracking-[0.1em] text-muted font-medium mb-2">Cliente</div>
          <div className="text-[14px] font-semibold text-ink">{doc.customer}</div>
          {customer && (
            <div className="text-[12px] text-muted mt-0.5 leading-relaxed">
              {customer.fiscal.address}<br/>
              {customer.email}<br/>
              <span className="num">{customer.phone}</span>
            </div>
          )}
        </div>
        <div>
          <div className="text-[10.5px] uppercase tracking-[0.1em] text-muted font-medium mb-2">Stato ordine</div>
          <DocStatusPill status={doc.status}/>
          <div className="text-[12px] text-muted mt-3">Consegna prevista entro 7 giorni lavorativi dalla disponibilità di tutti gli articoli.</div>
        </div>
      </div>

      <table className="w-full text-[12.5px] mt-5">
        <thead>
          <tr className="border-b-2 border-strong text-left text-[10.5px] uppercase tracking-[0.08em] text-muted font-medium">
            <th className="py-2 font-medium">Articolo</th>
            <th className="py-2 font-medium">SKU</th>
            <th className="py-2 font-medium text-right">Q.tà</th>
            <th className="py-2 font-medium text-right">Prezzo</th>
            <th className="py-2 font-medium text-right">Importo</th>
          </tr>
        </thead>
        <tbody>
          {(doc.lines || []).map((l, i) => (
            <tr key={i} className="border-b border-line2">
              <td className="py-2.5 text-ink">{l.name}</td>
              <td className="py-2.5 num text-muted">{l.sku}</td>
              <td className="py-2.5 num text-ink text-right">{l.qty}</td>
              <td className="py-2.5 num text-ink text-right">{fmtEur(l.price)}</td>
              <td className="py-2.5 num text-ink text-right font-medium">{fmtEur(l.price * l.qty)}</td>
            </tr>
          ))}
        </tbody>
      </table>

      <div className="mt-4 flex justify-end">
        <div className="w-[300px] text-[13px]">
          <div className="flex justify-between py-1.5">
            <span className="text-muted">Totale ordine</span>
            <span className="num text-ink">{fmtEur(doc.total)}</span>
          </div>
          {advance > 0 && (
            <>
              <div className="flex justify-between py-1.5 border-t border-line2">
                <span className="text-pos">Acconto versato</span>
                <span className="num text-pos">−{fmtEur(advance)}</span>
              </div>
              <div className="flex justify-between py-3 mt-1.5 border-t-2 border-ink">
                <span className="text-[14px] font-semibold text-ink">Residuo da saldare</span>
                <span className="num text-[18px] font-semibold text-ink">{fmtEur(balance)}</span>
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
};

// ─── DDT layout ───
const DdtLayout = ({ doc }) => (
  <div className="p-8">
    <div className="flex items-start justify-between pb-5 border-b-2 border-ink">
      <div>
        <div className="text-[14px] font-semibold text-ink">{STORE.name}</div>
        <div className="text-[11.5px] text-muted mt-0.5">{STORE.address} · P.IVA IT 04421109820</div>
      </div>
      <div className="text-right">
        <div className="text-[11px] uppercase tracking-[0.1em] text-muted font-medium">Documento di trasporto</div>
        <div className="num text-[20px] font-semibold text-ink mt-0.5">{doc.id}</div>
        <div className="text-[12px] text-muted mt-1">Emesso il <span className="num text-ink">{doc.date}</span></div>
      </div>
    </div>

    <div className="grid grid-cols-2 gap-6 py-5 border-b border-line">
      <div>
        <div className="text-[10.5px] uppercase tracking-[0.1em] text-muted font-medium mb-2">Mittente</div>
        <div className="text-[13.5px] font-semibold text-ink">{STORE.name}</div>
        <div className="text-[12px] text-muted">{STORE.address}</div>
      </div>
      <div>
        <div className="text-[10.5px] uppercase tracking-[0.1em] text-muted font-medium mb-2">Destinatario</div>
        <div className="text-[13.5px] font-semibold text-ink">{doc.customer}</div>
        <div className="text-[12px] text-muted">{doc.destinazione || '—'}</div>
      </div>
    </div>

    <div className="grid grid-cols-4 gap-4 py-4 border-b border-line text-[12px]">
      <div><span className="text-muted">Causale</span><div className="text-ink font-medium mt-0.5">{doc.causale || '—'}</div></div>
      <div><span className="text-muted">Aspetto</span><div className="text-ink font-medium mt-0.5">{doc.aspetto || '—'}</div></div>
      <div><span className="text-muted">Colli</span><div className="text-ink font-medium mt-0.5 num">{doc.nColli ?? '—'}</div></div>
      <div><span className="text-muted">Peso lordo</span><div className="text-ink font-medium mt-0.5 num">{(doc.peso != null && doc.peso !== '') ? doc.peso + ' kg' : '—'}</div></div>
    </div>

    <table className="w-full text-[12.5px] mt-4">
      <thead>
        <tr className="border-b-2 border-strong text-left text-[10.5px] uppercase tracking-[0.08em] text-muted font-medium">
          <th className="py-2 font-medium">Articolo</th>
          <th className="py-2 font-medium">SKU</th>
          <th className="py-2 font-medium text-right">Q.tà</th>
        </tr>
      </thead>
      <tbody>
        {(doc.lines || []).map((l, i) => (
          <tr key={i} className="border-b border-line2">
            <td className="py-2.5 text-ink">{l.name}</td>
            <td className="py-2.5 num text-muted">{l.sku}</td>
            <td className="py-2.5 num text-ink text-right">{l.qty}</td>
          </tr>
        ))}
      </tbody>
    </table>

    <div className="mt-8 grid grid-cols-2 gap-8 pt-6 border-t border-line">
      <div>
        <div className="text-[10.5px] uppercase tracking-[0.08em] text-muted font-medium mb-8">Firma mittente</div>
        <div className="border-t border-line w-3/4 pt-1 text-[10.5px] text-muted">{STORE.cashier}</div>
      </div>
      <div>
        <div className="text-[10.5px] uppercase tracking-[0.08em] text-muted font-medium mb-8">Firma destinatario</div>
        <div className="border-t border-line w-3/4 pt-1 text-[10.5px] text-muted">Per ricevuta</div>
      </div>
    </div>
  </div>
);

// ─── tone helpers per nuovi tipi ───
const _ocTone = s => s==='Confermato'?'pos':s==='Evaso'?'info':s==='Annullato'?'neg':'neutral';
const _rsTone = s => s==='Attivo'?'pos':s==='Ritirato'?'info':s==='Scaduto'?'warn':s==='Annullato'?'neg':'neutral';
const _ftTone = s => s==='Pagata'?'pos':s==='Emessa'?'info':s==='Annullata'?'neg':'neutral';

// Colonne righe con sconto condivise tra OC e FT
const _colonneConSconto = (fmtTot) => [
  { key: 'name',      label: 'Articolo / Descrizione', width: '1fr',
    render: l => <DocProductCell name={l.name} sku={l.sku} tmpSku={l.tmpSku}/> },
  { key: 'qty',       label: 'Q.tà',         width: '70px',
    headerClassName: 'text-right', className: 'num text-ink text-right', render: l => l.qty },
  { key: 'unitPrice', label: 'Prezzo unit.',  width: '120px',
    headerClassName: 'text-right', className: 'num text-ink text-right', render: l => fmtEur(l.unitPrice) },
  { key: 'discount',  label: 'Sconto',        width: '70px',
    headerClassName: 'text-right', className: 'num text-muted text-right', render: l => l.discount ? `${l.discount}%` : '—' },
  { key: 'tot',       label: 'Totale riga',   width: '130px',
    headerClassName: 'text-right', className: 'num font-semibold text-ink text-right',
    render: l => fmtTot ? fmtTot(l) : fmtEur(l.qty * l.unitPrice * (1-(l.discount||0)/100)) },
];

const _campiClienti = () => CUSTOMERS.map(c => ({ v: c.id, l: c.name }));
const _campiNegozi  = () => STORES.map(s => ({ v: s.id, l: s.name }));

// ══════════════════════════════════════════════════════════════════════
//  OrdineClienteSection
// ══════════════════════════════════════════════════════════════════════
const OrdineClienteSection = () => {
  const [view, setView] = useStateD('list');
  const [selId, setSelId] = useStateD(null);
  const terms = window.__BI_TERMINI__ || PAYMENT_TERMS;
  const doc   = CUSTOMER_ORDERS.find(o => o.id === selId);
  const lines = selId ? (CUSTOMER_ORDER_LINES[selId] || []) : [];

  const goList   = () => setView('list');
  const goDetail = d => { setSelId(d.id); setView('detail'); };
  const goNew    = () => setView('nuovo');

  const lineTotal = l => l.qty * l.unitPrice * (1-(l.discount||0)/100);

  if (view === 'nuovo') return (
    <DocumentWizard
      title="Nuovo ordine cliente"
      labelTorna="Torna agli ordini cliente"
      labelStep2="Articoli"
      labelConferma="Conferma ordine"
      labelBozza="Salva come bozza"
      campiTestata={[
        { key: 'customerId',   label: 'Cliente',                type: 'select', required: true, span: 2, options: _campiClienti() },
        { key: 'store',        label: 'Negozio',                type: 'select', required: true, options: _campiNegozi() },
        { key: 'status',       label: 'Stato',                  type: 'select', options: ['Bozza','Confermato'] },
        { key: 'dateOrder',    label: 'Data ordine',            type: 'date', required: true },
        { key: 'dateConsegna', label: 'Consegna prevista',      type: 'date' },
        { key: 'paymentTermId',label: 'Termini di pagamento',   type: 'select', options: terms.map(t => ({ v: t.id, l: t.desc })) },
      ]}
      valoriIniziali={{ store: STORE.id, status: 'Bozza', dateOrder: '2026-05-30' }}
      onConferma={(t,l)=>{ _docCreate('CUSTOMER_ORDER', t, l, 'Confermato', 'Ordine cliente creato'); goList(); }} onSalvaBozza={(t,l)=>{ _docCreate('CUSTOMER_ORDER', t, l, 'Bozza', 'Bozza ordine salvata'); goList(); }} onAnnulla={goList}
    />
  );

  if (view === 'detail' && doc) {
    const store = STORES.find(s => s.id === doc.store);
    const term  = terms.find(t => t.id === doc.paymentTermId);
    return (
      <DocumentDetail
        labelTipo="Ordine cliente" labelTorna="Torna agli ordini cliente"
        onBack={goList} doc={doc} statusTone={_ocTone}
        headerFields={[
          { label: 'Cliente',              value: doc.customer },
          { label: 'Negozio',              value: store?.name || doc.store },
          { label: 'Data ordine',          value: doc.date },
          { label: 'Consegna prevista',    value: doc.dateConsegna || '—' },
          { label: 'Termini di pagamento', value: term?.desc || '—' },
          { label: 'Numero documento',     value: doc.id, mono: true },
        ]}
        linee={lines} lineeLabel="Articoli ordinati"
        totaleLabel="Totale ordine" totale={doc.total}
        colonneLinee={_colonneConSconto(lineTotal)}
        azioni={doc.status === 'Confermato' && (
          <div className="flex gap-3">
            <button onClick={() => { _docStatus('CUSTOMER_ORDER', doc.id, 'Evaso', 'Ordine evaso'); goList(); }}
              className="h-16 px-8 rounded-md font-semibold text-[17px] flex items-center gap-3 transition-all duration-fast ease-standard shadow-soft"
              style={{ background: 'var(--success-500)', color: '#fff' }}>
              <I.Check size={20}/>Evadi ordine
            </button>
          </div>
        )}
      />
    );
  }

  const kpis = [
    { label: 'Ordini totali', value: CUSTOMER_ORDERS.length },
    { label: 'Confermati',    value: CUSTOMER_ORDERS.filter(o=>o.status==='Confermato').length, tone: 'pos' },
    { label: 'Bozze',         value: CUSTOMER_ORDERS.filter(o=>o.status==='Bozza').length, tone: 'warn' },
    { label: 'Valore aperto', value: fmtEur(CUSTOMER_ORDERS.filter(o=>o.status==='Confermato').reduce((s,o)=>s+o.total,0)) },
  ];
  return (
    <DocumentList
      title="Ordini cliente" subtitle="Articoli ordinati dai clienti, da consegnare"
      nuovoLabel="Nuovo ordine" documents={CUSTOMER_ORDERS} kpis={kpis}
      columns={[
        { key: 'id',          label: 'Numero',         render: d => <span className="num font-medium text-ink">{d.id}</span> },
        { key: 'customer',    label: 'Cliente' },
        { key: 'date',        label: 'Data ordine' },
        { key: 'dateConsegna',label: 'Consegna prev.', render: d => d.dateConsegna || '—' },
        { key: 'status',      label: 'Stato',          render: d => <Pill tone={_ocTone(d.status)}>{d.status}</Pill> },
        { key: 'total',       label: 'Totale', headerClassName: 'text-right',
          className: 'num text-right font-medium text-ink', render: d => d.total ? fmtEur(d.total) : '—' },
      ]}
      filters={[{ key: 'status', label: 'Stato', options: ['Tutti','Bozza','Confermato','Evaso','Annullato'], filterFn: (d,v) => d.status===v }]}
      searchFilter={(d,ql) => d.id.toLowerCase().includes(ql) || d.customer.toLowerCase().includes(ql)}
      searchPlaceholder="Cerca per numero o cliente…"
      onNuovo={goNew} onSeleziona={goDetail}
      emptyMessage="Nessun ordine cliente corrisponde ai filtri."
    />
  );
};

// ══════════════════════════════════════════════════════════════════════
//  RiservatoSection
// ══════════════════════════════════════════════════════════════════════
const RiservatoSection = () => {
  const [view, setView] = useStateD('list');
  const [selId, setSelId] = useStateD(null);
  const doc   = CUSTOMER_RESERVES.find(r => r.id === selId);
  const lines = selId ? (CUSTOMER_RESERVE_LINES[selId] || []) : [];

  const goList   = () => setView('list');
  const goDetail = d => { setSelId(d.id); setView('detail'); };
  const goNew    = () => setView('nuovo');

  if (view === 'nuovo') return (
    <DocumentWizard
      title="Nuova riserva cliente"
      labelTorna="Torna alle riserve"
      labelStep2="Articoli riservati"
      labelConferma="Attiva riserva"
      qtaField="qtyRiservata" qtaLabel="Q.tà riservata"
      mostraNuovoProdotto={false}
      campiTestata={[
        { key: 'customerId',  label: 'Cliente',         type: 'select', required: true, span: 2, options: _campiClienti() },
        { key: 'store',       label: 'Negozio',         type: 'select', required: true, options: _campiNegozi() },
        { key: 'status',      label: 'Stato',           type: 'select', options: ['Attivo','Ritirato','Scaduto','Annullato'] },
        { key: 'dateRiserva', label: 'Data riserva',    type: 'date', required: true },
        { key: 'dateScadenza',label: 'Scadenza riserva',type: 'date', required: true },
        { key: 'note',        label: 'Note',            type: 'textarea', span: 2, placeholder: 'Informazioni per il personale…' },
      ]}
      valoriIniziali={{ store: STORE.id, status: 'Attivo', dateRiserva: '2026-05-30' }}
      onConferma={(t,l)=>{ _docCreate('CUSTOMER_RESERVE', t, l, 'Attivo', 'Riserva attivata'); goList(); }} onAnnulla={goList}
    />
  );

  if (view === 'detail' && doc) {
    const store = STORES.find(s => s.id === doc.store);
    const totPezzi = lines.reduce((s,l) => s+(l.qtyRiservata||0), 0);
    return (
      <DocumentDetail
        labelTipo="Riservato cliente" labelTorna="Torna alle riserve"
        onBack={goList} doc={doc} statusTone={_rsTone}
        headerFields={[
          { label: 'Cliente',      value: doc.customer },
          { label: 'Negozio',      value: store?.name || doc.store },
          { label: 'Data riserva', value: doc.date },
          { label: 'Scadenza',     value: doc.dateScadenza || '—' },
          ...(doc.note ? [{ label: 'Note', value: doc.note }] : []),
        ]}
        linee={lines} lineeLabel="Articoli riservati"
        totaleLabel="Pezzi totali" totale={totPezzi}
        colonneLinee={[
          { key: 'name',        label: 'Articolo',       width: '1fr',
            render: l => <DocProductCell name={l.name} sku={l.sku}/> },
          { key: 'qtyRiservata',label: 'Q.tà riservata', width: '150px',
            headerClassName: 'text-right', className: 'num font-semibold text-ink text-right',
            render: l => l.qtyRiservata },
        ]}
        azioni={doc.status === 'Attivo' && (
          <div className="flex gap-3">
            <button onClick={() => { _docStatus('CUSTOMER_RESERVE', doc.id, 'Ritirato', 'Riserva segnata come ritirata'); goList(); }}
              className="h-16 px-8 rounded-md font-semibold text-[17px] flex items-center gap-3 transition-all duration-fast ease-standard shadow-soft"
              style={{ background: 'var(--success-500)', color: '#fff' }}>
              <I.Check size={20}/>Segna come ritirato
            </button>
            <Btn variant="outline" size="lg"
              onClick={() => { _docStatus('CUSTOMER_RESERVE', doc.id, 'Annullato', 'Riserva annullata'); goList(); }}>Annulla riserva</Btn>
          </div>
        )}
      />
    );
  }

  const kpis = [
    { label: 'Riserve totali', value: CUSTOMER_RESERVES.length },
    { label: 'Attive',         value: CUSTOMER_RESERVES.filter(r=>r.status==='Attivo').length,   tone: 'pos'  },
    { label: 'Scadute',        value: CUSTOMER_RESERVES.filter(r=>r.status==='Scaduto').length,  tone: 'warn' },
    { label: 'Ritirate',       value: CUSTOMER_RESERVES.filter(r=>r.status==='Ritirato').length, tone: 'info' },
  ];
  return (
    <DocumentList
      title="Riservati cliente" subtitle="Articoli messi da parte per un cliente fino a una data"
      nuovoLabel="Nuova riserva" documents={CUSTOMER_RESERVES} kpis={kpis}
      columns={[
        { key: 'id',          label: 'Numero',       render: d => <span className="num font-medium text-ink">{d.id}</span> },
        { key: 'customer',    label: 'Cliente' },
        { key: 'date',        label: 'Data riserva' },
        { key: 'dateScadenza',label: 'Scadenza',     render: d => d.dateScadenza || '—' },
        { key: 'status',      label: 'Stato',        render: d => <Pill tone={_rsTone(d.status)}>{d.status}</Pill> },
        { key: 'pezzi',       label: 'Pezzi', headerClassName: 'text-right', className: 'num text-right text-ink',
          render: d => (CUSTOMER_RESERVE_LINES[d.id]||[]).reduce((s,l)=>s+(l.qtyRiservata||0),0) },
      ]}
      filters={[{ key: 'status', label: 'Stato', options: ['Tutti','Attivo','Ritirato','Scaduto','Annullato'], filterFn: (d,v) => d.status===v }]}
      searchFilter={(d,ql) => d.id.toLowerCase().includes(ql) || d.customer.toLowerCase().includes(ql)}
      searchPlaceholder="Cerca per numero o cliente…"
      onNuovo={goNew} onSeleziona={goDetail}
      emptyMessage="Nessuna riserva corrisponde ai filtri."
    />
  );
};

// ══════════════════════════════════════════════════════════════════════
//  FatturaClienteSection
// ══════════════════════════════════════════════════════════════════════
const FatturaClienteSection = () => {
  const [view, setView] = useStateD('list');
  const [selId, setSelId] = useStateD(null);
  const terms    = window.__BI_TERMINI__ || PAYMENT_TERMS;
  const aliquote = window.__BI_ALIQUOTE__ || [{ id: 1, desc: 'Ordinaria', pct: 22 }];
  const doc   = CUSTOMER_INVOICES.find(f => f.id === selId);
  const lines = selId ? (CUSTOMER_INVOICE_LINES[selId] || []) : [];

  const goList   = () => setView('list');
  const goDetail = d => { setSelId(d.id); setView('detail'); };
  const goNew    = () => setView('nuovo');

  const getPct   = ivaId => aliquote.find(a=>a.id===ivaId)?.pct ?? 22;
  const lineNet  = l => l.qty * l.unitPrice * (1-(l.discount||0)/100);
  const ftTotals = ls => {
    let imponibile = 0; const ivaMap = {};
    ls.forEach(l => {
      const net = lineNet(l); imponibile += net;
      const pct = getPct(l.ivaId);
      ivaMap[pct] = (ivaMap[pct]||0) + net * pct / 100;
    });
    const ivaTotal = Object.values(ivaMap).reduce((s,v)=>s+v,0);
    return { imponibile, ivaMap, ivaTotal, totale: imponibile + ivaTotal };
  };

  const ftAlert = customerId => {
    const c = CUSTOMERS.find(x => x.id === customerId);
    if (!c) return null;
    const isAz = c.personType === 'azienda' || c.kind === 'Azienda';
    if (isAz && (!c.piva || c.piva === '—')) return 'P.IVA mancante';
    if (!c.cf || c.cf === '—') return 'Codice fiscale mancante';
    return null;
  };

  if (view === 'nuovo') return (
    <DocumentWizard
      title="Nuova fattura cliente"
      labelTorna="Torna alle fatture cliente"
      labelStep2="Righe fattura"
      labelConferma="Emetti fattura"
      labelBozza="Salva come bozza"
      campiTestata={[
        { key: 'customerId',          label: 'Cliente',                  type: 'select', required: true, span: 2, options: _campiClienti() },
        { key: 'store',               label: 'Negozio emittente',        type: 'select', required: true, options: _campiNegozi() },
        { key: 'status',              label: 'Stato',                    type: 'select', options: ['Bozza','Emessa','Pagata','Annullata'] },
        { key: 'dateDoc',             label: 'Data fattura',             type: 'date', required: true },
        { key: 'dateScadenza',        label: 'Data scadenza',            type: 'date' },
        { key: 'paymentTermId',       label: 'Termini di pagamento',     type: 'select', options: terms.map(t=>({v:t.id,l:t.desc})) },
        { key: 'pagamento',           label: 'Modalità di pagamento',    type: 'select', options: ['Bonifico','Contanti','Carta','Assegno'] },
        { key: 'indirizzoFatturazione',label: 'Indirizzo di fatturazione',type: 'text', span: 2, placeholder: 'Via, CAP, Città (Prov.)' },
      ]}
      valoriIniziali={{ store: STORE.id, status: 'Bozza', dateDoc: '2026-05-30', pagamento: 'Bonifico' }}
      onConferma={(t,l)=>{ _docCreate('CUSTOMER_INVOICE', t, l, 'Emessa', 'Fattura cliente emessa'); goList(); }} onSalvaBozza={(t,l)=>{ _docCreate('CUSTOMER_INVOICE', t, l, 'Bozza', 'Bozza fattura salvata'); goList(); }} onAnnulla={goList}
    />
  );

  if (view === 'detail' && doc) {
    const store   = STORES.find(s=>s.id===doc.store);
    const term    = terms.find(t=>t.id===doc.paymentTermId);
    const customer= CUSTOMERS.find(c=>c.id===doc.customerId);
    const alert   = ftAlert(doc.customerId);
    const totals  = ftTotals(lines);

    const colonneLineeIVA = [
      { key: 'name',      label: 'Descrizione',  width: '1fr',
        render: l => <DocProductCell name={l.name} sku={l.sku} tmpSku={l.tmpSku}/> },
      { key: 'qty',       label: 'Q.tà',         width: '60px',
        headerClassName: 'text-right', className: 'num text-ink text-right', render: l => l.qty },
      { key: 'unitPrice', label: 'Prezzo unit.', width: '110px',
        headerClassName: 'text-right', className: 'num text-ink text-right', render: l => fmtEur(l.unitPrice) },
      { key: 'discount',  label: 'Sconto',       width: '65px',
        headerClassName: 'text-right', className: 'num text-muted text-right', render: l => l.discount ? `${l.discount}%` : '—' },
      { key: 'iva',       label: 'IVA',          width: '65px',
        headerClassName: 'text-right', className: 'num text-muted text-right', render: l => `${getPct(l.ivaId)}%` },
      { key: 'tot',       label: 'Totale riga',  width: '120px',
        headerClassName: 'text-right', className: 'num font-semibold text-ink text-right', render: l => fmtEur(lineNet(l)) },
    ];

    return (
      <DocumentDetail
        labelTipo="Fattura cliente" labelTorna="Torna alle fatture cliente"
        onBack={goList} doc={doc} statusTone={_ftTone}
        headerFields={[
          { label: 'Cliente',            value: doc.customer },
          { label: 'Negozio emittente',  value: store?.name || doc.store },
          { label: 'Data fattura',       value: doc.date },
          { label: 'Scadenza',           value: doc.dateScadenza || '—' },
          { label: 'Termini',            value: term?.desc || '—' },
          { label: 'Pagamento',          value: doc.pagamento || '—' },
          { label: 'Ind. fatturazione',  value: doc.indirizzoFatturazione || '—' },
          { label: 'P.IVA cliente',      value: customer?.piva || '—', mono: true },
        ]}
        renderExtraTestata={alert && (
          <div className="flex items-center gap-2 px-3 py-2 rounded-md text-[13px]"
            style={{ background: 'var(--warning-50)', color: 'var(--warning-700)' }}>
            <I.Bell size={14}/>
            Attenzione: {alert} — verifica i dati fiscali del cliente prima di emettere.
          </div>
        )}
        linee={lines} lineeLabel="Righe fattura"
        totaleLabel="Totale fattura" totale={totals.totale}
        colonneLinee={colonneLineeIVA}
        azioni={
          <Card>
            <div className="flex items-start gap-8">
              <div className="flex-1">
                <div className="text-[11px] uppercase tracking-[0.08em] text-muted font-medium mb-3">Riepilogo IVA</div>
                <div className="space-y-2 text-[13px]">
                  <div className="flex justify-between">
                    <span className="text-muted">Imponibile</span>
                    <span className="num text-ink">{fmtEur(totals.imponibile)}</span>
                  </div>
                  {Object.entries(totals.ivaMap).map(([pct,val]) => (
                    <div key={pct} className="flex justify-between">
                      <span className="text-muted">IVA {pct}%</span>
                      <span className="num text-ink">{fmtEur(val)}</span>
                    </div>
                  ))}
                  <div className="flex justify-between pt-2 border-t border-line font-semibold">
                    <span className="text-ink">Totale fattura</span>
                    <span className="num text-[18px] text-ink">{fmtEur(totals.totale)}</span>
                  </div>
                </div>
              </div>
              <div className="flex flex-col gap-2 shrink-0">
                {doc.status === 'Emessa' && (
                  <button onClick={() => { _docStatus('CUSTOMER_INVOICE', doc.id, 'Pagata', 'Fattura segnata come pagata'); goList(); }}
                    className="h-16 px-8 rounded-md font-semibold text-[17px] flex items-center gap-3 transition-all duration-fast ease-standard shadow-soft"
                    style={{ background: 'var(--success-500)', color: '#fff' }}>
                    <I.Check size={20}/>Segna come pagata
                  </button>
                )}
              </div>
            </div>
          </Card>
        }
      />
    );
  }

  const kpis = [
    { label: 'Fatture totali', value: CUSTOMER_INVOICES.length },
    { label: 'Emesse',         value: CUSTOMER_INVOICES.filter(f=>f.status==='Emessa').length, tone: 'info' },
    { label: 'Pagate',         value: CUSTOMER_INVOICES.filter(f=>f.status==='Pagata').length, tone: 'pos'  },
    { label: 'Valore emesso',  value: fmtEur(CUSTOMER_INVOICES.filter(f=>['Emessa','Pagata'].includes(f.status)).reduce((s,f)=>s+f.total,0)) },
  ];
  return (
    <DocumentList
      title="Fatture cliente" subtitle="Fatture formali emesse ai clienti"
      nuovoLabel="Nuova fattura" documents={CUSTOMER_INVOICES} kpis={kpis}
      columns={[
        { key: 'id',       label: 'Numero',    render: d => <span className="num font-medium text-ink">{d.id}</span> },
        { key: 'customer', label: 'Cliente' },
        { key: 'date',     label: 'Data' },
        { key: 'dateScadenza', label: 'Scadenza', render: d => d.dateScadenza || '—' },
        { key: 'pagamento',label: 'Pagamento' },
        { key: 'status',   label: 'Stato',     render: d => <Pill tone={_ftTone(d.status)}>{d.status}</Pill> },
        { key: 'total',    label: 'Totale', headerClassName: 'text-right',
          className: 'num text-right font-medium text-ink', render: d => d.total ? fmtEur(d.total) : '—' },
      ]}
      filters={[{ key: 'status', label: 'Stato', options: ['Tutti','Bozza','Emessa','Pagata','Annullata'], filterFn: (d,v) => d.status===v }]}
      searchFilter={(d,ql) => d.id.toLowerCase().includes(ql) || d.customer.toLowerCase().includes(ql)}
      searchPlaceholder="Cerca per numero o cliente…"
      onNuovo={goNew} onSeleziona={goDetail}
      emptyMessage="Nessuna fattura cliente corrisponde ai filtri."
    />
  );
};

// ─── helper IVA condiviso (FatturaFornitore + NotaCreditoFornitore) ───
const _fornPct    = (aliquote, ivaId) => (aliquote.find(a=>a.id===ivaId)?.pct ?? 22);
const _fornTotals = (lines, aliquote) => {
  let imponibile = 0; const ivaMap = {};
  lines.forEach(l => {
    const net = (l.qty||0) * (l.unitPrice||0);
    imponibile += net;
    const pct = _fornPct(aliquote, l.ivaId);
    ivaMap[pct] = (ivaMap[pct]||0) + net * pct / 100;
  });
  const ivaTotal = Object.values(ivaMap).reduce((s,v)=>s+v,0);
  return { imponibile, ivaMap, ivaTotal, totale: imponibile + ivaTotal };
};
const _colonneIVAForn = (aliquote) => [
  { key: 'name',      label: 'Descrizione',  width: '1fr',
    render: l => <DocProductCell name={l.name} sku={l.sku}/> },
  { key: 'qty',       label: 'Q.tà',         width: '70px',
    headerClassName: 'text-right', className: 'num text-ink text-right', render: l => l.qty },
  { key: 'unitPrice', label: 'Prezzo unit.', width: '120px',
    headerClassName: 'text-right', className: 'num text-ink text-right', render: l => fmtEur(l.unitPrice) },
  { key: 'iva',       label: 'IVA',          width: '70px',
    headerClassName: 'text-right', className: 'num text-muted text-right',
    render: l => `${_fornPct(aliquote, l.ivaId)}%` },
  { key: 'tot',       label: 'Totale riga',  width: '120px',
    headerClassName: 'text-right', className: 'num font-semibold text-ink text-right',
    render: l => fmtEur((l.qty||0)*(l.unitPrice||0)) },
];
const _azioniIVA = (totals, doc, extraBtn) => (
  <Card>
    <div className="flex items-start gap-8">
      <div className="flex-1">
        <div className="text-[11px] uppercase tracking-[0.08em] text-muted font-medium mb-3">Riepilogo IVA</div>
        <div className="space-y-2 text-[13px]">
          <div className="flex justify-between">
            <span className="text-muted">Imponibile</span>
            <span className="num text-ink">{fmtEur(totals.imponibile)}</span>
          </div>
          {Object.entries(totals.ivaMap).map(([pct,val]) => (
            <div key={pct} className="flex justify-between">
              <span className="text-muted">IVA {pct}%</span>
              <span className="num text-ink">{fmtEur(val)}</span>
            </div>
          ))}
          <div className="flex justify-between pt-2 border-t border-line font-semibold">
            <span className="text-ink">Totale</span>
            <span className="num text-[18px] text-ink">{fmtEur(totals.totale)}</span>
          </div>
        </div>
      </div>
      <div className="flex flex-col gap-2 shrink-0">
        {extraBtn}
      </div>
    </div>
  </Card>
);
const _campiFornnitori = () => SUPPLIERS.map(s => ({ v: s.id, l: s.name }));

// ══════════════════════════════════════════════════════════════════════
//  DDTClienteSection
// ══════════════════════════════════════════════════════════════════════
const DDTClienteSection = () => {
  const [view, setView] = useStateD('list');
  const [selId, setSelId] = useStateD(null);
  const doc   = DDT_CLIENTI.find(d => d.id === selId);
  const lines = selId ? (DDT_CLIENTI_LINES[selId] || []) : [];

  const goList   = () => setView('list');
  const goDetail = d => { setSelId(d.id); setView('detail'); };
  const goNew    = () => setView('nuovo');

  const dttTone  = s => s==='Emesso'?'pos':s==='Fatturato'?'info':s==='Annullato'?'neg':'neutral';
  const pezziTot = ls => ls.reduce((s,l)=>s+(l.qty||0),0);
  const valoreTot = ls => ls.reduce((s,l)=>s+(l.qty||0)*(l.unitPrice||0),0);

  if (view === 'nuovo') return (
    <DocumentWizard
      title="Nuovo DDT cliente"
      labelTorna="Torna ai DDT cliente"
      labelStep2="Articoli"
      labelConferma="Emetti DDT"
      labelBozza="Salva come bozza"
      campiTestata={[
        { key: 'customerId',   label: 'Cliente',               type: 'select', required: true, span: 2, options: _campiClienti() },
        { key: 'destinazione', label: 'Indirizzo destinazione', type: 'text',   required: true, span: 2, placeholder: 'Via, CAP, Città (Prov.)' },
        { key: 'store',        label: 'Negozio mittente',       type: 'select', required: true, options: _campiNegozi() },
        { key: 'status',       label: 'Stato',                  type: 'select', options: ['Bozza','Emesso','Fatturato'] },
        { key: 'dateDdt',      label: 'Data DDT',               type: 'date',   required: true },
        { key: 'causale',      label: 'Causale trasporto',       type: 'select', options: ['Vendita','Conto vendita','Reso a fornitore','Reso da cliente','Riparazione','Altro'] },
        { key: 'aspetto',      label: 'Aspetto esteriore',       type: 'select', options: ['Colli','Sacchi','Cartoni','Buste'] },
        { key: 'nColli',       label: 'N° colli',                type: 'number', placeholder: '1' },
        { key: 'peso',         label: 'Peso totale (kg)',         type: 'number', placeholder: '0.0' },
        { key: 'trasportoCura',label: 'Trasporto a cura di',      type: 'select', options: ['Mittente','Destinatario','Vettore'] },
      ]}
      valoriIniziali={{ store: STORE.id, status: 'Bozza', dateDdt: '2026-05-30', causale: 'Vendita', aspetto: 'Colli', trasportoCura: 'Mittente' }}
      onConferma={(t,l)=>{ _docCreate('DDT_CLIENTE', t, l, 'Emesso', 'DDT emesso'); goList(); }} onSalvaBozza={(t,l)=>{ _docCreate('DDT_CLIENTE', t, l, 'Bozza', 'Bozza DDT salvata'); goList(); }} onAnnulla={goList}
    />
  );

  if (view === 'detail' && doc) {
    const store  = STORES.find(s=>s.id===doc.store);
    const pezzi  = pezziTot(lines);
    const valore = valoreTot(lines);
    return (
      <DocumentDetail
        labelTipo="DDT cliente" labelTorna="Torna ai DDT cliente"
        onBack={goList} doc={doc} statusTone={dttTone}
        headerFields={[
          { label: 'Cliente',             value: doc.customer },
          { label: 'Destinazione',        value: doc.destinazione || '—' },
          { label: 'Negozio mittente',    value: store?.name || doc.store },
          { label: 'Data DDT',            value: doc.date },
          { label: 'Causale trasporto',   value: doc.causale || '—' },
          { label: 'Aspetto esteriore',   value: doc.aspetto || '—' },
          { label: 'N° colli',            value: doc.nColli ?? '—' },
          { label: 'Peso (kg)',           value: doc.peso ?? '—' },
          { label: 'Trasporto a cura di', value: doc.trasportoCura || '—' },
        ]}
        linee={lines} lineeLabel="Articoli trasportati"
        totaleLabel="Valore totale" totale={valore > 0 ? valore : undefined}
        colonneLinee={[
          { key: 'name',      label: 'Articolo', width: '1fr',
            render: l => <DocProductCell name={l.name} sku={l.sku}/> },
          { key: 'qty',       label: 'Q.tà', width: '80px',
            headerClassName: 'text-right', className: 'num font-semibold text-ink text-right', render: l => l.qty },
          { key: 'unitPrice', label: 'Valore unit.', width: '130px',
            headerClassName: 'text-right', className: 'num text-ink text-right',
            render: l => l.unitPrice != null ? fmtEur(l.unitPrice) : '—' },
          { key: 'totriga',   label: 'Valore riga', width: '130px',
            headerClassName: 'text-right', className: 'num text-ink text-right',
            render: l => l.unitPrice != null ? fmtEur((l.qty||0)*l.unitPrice) : '—' },
        ]}
        azioni={
          <div className="flex gap-3">
            {doc.status === 'Emesso' && (
              <button onClick={() => {
                  _docCreate('CUSTOMER_INVOICE',
                    { customerId: doc.customerId, customer: doc.customer, store: doc.store, deliveryRef: doc.id, indirizzoFatturazione: doc.destinazione },
                    lines, 'Emessa', 'Fattura creata dal DDT');
                  _docStatus('DDT_CLIENTE', doc.id, 'Fatturato', 'DDT segnato come fatturato');
                  goList();
                }}
                className="h-16 px-8 rounded-md font-semibold text-[17px] flex items-center gap-3 transition-all duration-fast ease-standard shadow-soft"
                style={{ background: 'var(--success-500)', color: '#fff' }}>
                <I.Doc size={20}/>Crea fattura
              </button>
            )}
          </div>
        }
      />
    );
  }

  const kpis = [
    { label: 'DDT totali', value: DDT_CLIENTI.length },
    { label: 'Emessi',    value: DDT_CLIENTI.filter(d=>d.status==='Emesso').length,    tone: 'pos'  },
    { label: 'Fatturati', value: DDT_CLIENTI.filter(d=>d.status==='Fatturato').length, tone: 'info' },
    { label: 'Bozze',     value: DDT_CLIENTI.filter(d=>d.status==='Bozza').length,     tone: 'warn' },
  ];
  return (
    <DocumentList
      title="DDT cliente" subtitle="Documenti di trasporto verso clienti in uscita"
      nuovoLabel="Nuovo DDT" documents={DDT_CLIENTI} kpis={kpis}
      columns={[
        { key: 'id',       label: 'Numero',   render: d => <span className="num font-medium text-ink">{d.id}</span> },
        { key: 'customer', label: 'Cliente' },
        { key: 'date',     label: 'Data' },
        { key: 'causale',  label: 'Causale' },
        { key: 'status',   label: 'Stato',    render: d => <Pill tone={dttTone(d.status)}>{d.status}</Pill> },
        { key: 'pezzi',    label: 'Pezzi', headerClassName: 'text-right', className: 'num text-right text-ink',
          render: d => pezziTot(DDT_CLIENTI_LINES[d.id]||[]) },
      ]}
      filters={[{ key: 'status', label: 'Stato', options: ['Tutti','Bozza','Emesso','Fatturato','Annullato'], filterFn: (d,v)=>d.status===v }]}
      searchFilter={(d,ql) => d.id.toLowerCase().includes(ql) || d.customer.toLowerCase().includes(ql)}
      searchPlaceholder="Cerca per numero o cliente…"
      onNuovo={goNew} onSeleziona={goDetail}
      emptyMessage="Nessun DDT corrisponde ai filtri."
    />
  );
};

// ══════════════════════════════════════════════════════════════════════
//  FatturaFornitoreSection
// ══════════════════════════════════════════════════════════════════════
const FatturaFornitoreSection = () => {
  const [view, setView] = useStateD('list');
  const [selId, setSelId] = useStateD(null);
  const terms    = window.__BI_TERMINI__ || PAYMENT_TERMS;
  const aliquote = window.__BI_ALIQUOTE__ || [{ id: 1, desc: 'Ordinaria', pct: 22 }];
  const doc   = SUPPLIER_INVOICES.find(f => f.id === selId);
  const lines = selId ? (SUPPLIER_INVOICE_LINES[selId] || []) : [];

  const goList   = () => setView('list');
  const goDetail = d => { setSelId(d.id); setView('detail'); };
  const goNew    = () => setView('nuovo');

  const ffTone   = s => s==='Da pagare'?'warn':s==='Pagata'?'pos':s==='Parzialmente pagata'?'info':s==='Contestata'?'neg':'neutral';

  if (view === 'nuovo') return (
    <DocumentWizard
      title="Nuova fattura fornitore"
      labelTorna="Torna alle fatture fornitore"
      labelStep2="Righe"
      labelConferma="Registra fattura"
      labelBozza="Salva come bozza"
      mostraNuovoProdotto={false}
      campiTestata={[
        { key: 'supplierId',      label: 'Fornitore',                type: 'select', required: true, span: 2, options: _campiFornnitori() },
        { key: 'numDocFornitore', label: 'N° fattura fornitore',     type: 'text',   required: true, placeholder: 'es. FAT-2026-0001' },
        { key: 'status',          label: 'Stato',                    type: 'select', options: ['Bozza','Da pagare','Pagata','Parzialmente pagata','Contestata'] },
        { key: 'dateDoc',         label: 'Data fattura fornitore',   type: 'date',   required: true },
        { key: 'dateRicezione',   label: 'Data ricezione',           type: 'date' },
        { key: 'dateScadenza',    label: 'Data scadenza',            type: 'date' },
        { key: 'paymentTermId',   label: 'Termini di pagamento',     type: 'select', options: terms.map(t=>({v:t.id,l:t.desc})) },
        { key: 'pagamento',       label: 'Modalità di pagamento',    type: 'select', options: ['Bonifico','Contanti','Carta','Assegno'] },
        { key: 'deliveryRef',     label: 'Rif. consegna (opz.)',     type: 'text',   placeholder: 'es. DC 2026-0001' },
      ]}
      valoriIniziali={{ status: 'Bozza', dateDoc: '2026-05-30', pagamento: 'Bonifico' }}
      onConferma={(t,l)=>{ _docCreate('SUPPLIER_INVOICE', t, l, 'Da pagare', 'Fattura fornitore registrata'); goList(); }} onSalvaBozza={(t,l)=>{ _docCreate('SUPPLIER_INVOICE', t, l, 'Bozza', 'Bozza fattura salvata'); goList(); }} onAnnulla={goList}
    />
  );

  if (view === 'detail' && doc) {
    const supplier = SUPPLIERS.find(s=>s.id===doc.supplierId);
    const term     = terms.find(t=>t.id===doc.paymentTermId);
    const totals   = _fornTotals(lines, aliquote);
    return (
      <DocumentDetail
        labelTipo="Fattura fornitore" labelTorna="Torna alle fatture fornitore"
        onBack={goList} doc={doc} statusTone={ffTone}
        headerFields={[
          { label: 'Fornitore',             value: doc.supplier },
          { label: 'N° fattura fornitore',  value: doc.numDocFornitore || '—', mono: true },
          { label: 'Data fattura',          value: doc.dateDoc || '—' },
          { label: 'Data ricezione',        value: doc.dateRicezione || '—' },
          { label: 'Scadenza',              value: doc.dateScadenza || '—' },
          { label: 'Termini di pagamento',  value: term?.desc || '—' },
          { label: 'Pagamento',             value: doc.pagamento || '—' },
          { label: 'Rif. consegna',         value: doc.deliveryRef || '—' },
        ]}
        linee={lines} lineeLabel="Righe fattura fornitore"
        totaleLabel="Totale imponibile" totale={totals.imponibile}
        colonneLinee={_colonneIVAForn(aliquote)}
        azioni={_azioniIVA(totals, doc,
          doc.status === 'Da pagare' && (
            <button onClick={() => { _docStatus('SUPPLIER_INVOICE', doc.id, 'Pagata', 'Fattura fornitore segnata come pagata'); goList(); }}
              className="h-16 px-8 rounded-md font-semibold text-[17px] flex items-center gap-3 transition-all duration-fast ease-standard shadow-soft"
              style={{ background: 'var(--success-500)', color: '#fff' }}>
              <I.Check size={20}/>Segna come pagata
            </button>
          )
        )}
      />
    );
  }

  const kpis = [
    { label: 'Fatture totali', value: SUPPLIER_INVOICES.length },
    { label: 'Da pagare',      value: SUPPLIER_INVOICES.filter(f=>f.status==='Da pagare').length,  tone: 'warn' },
    { label: 'Pagate',         value: SUPPLIER_INVOICES.filter(f=>f.status==='Pagata').length,      tone: 'pos'  },
    { label: 'Valore aperto',  value: fmtEur(SUPPLIER_INVOICES.filter(f=>f.status==='Da pagare').reduce((s,f)=>s+f.total,0)) },
  ];
  return (
    <DocumentList
      title="Fatture fornitore" subtitle="Fatture ricevute dai fornitori da registrare in contabilità"
      nuovoLabel="Nuova fattura" documents={SUPPLIER_INVOICES} kpis={kpis}
      columns={[
        { key: 'id',              label: 'N° interno',       render: d => <span className="num font-medium text-ink">{d.id}</span> },
        { key: 'numDocFornitore', label: 'N° doc. fornitore',render: d => <span className="num text-muted">{d.numDocFornitore || '—'}</span> },
        { key: 'supplier',        label: 'Fornitore' },
        { key: 'dateRicezione',   label: 'Data ricezione',   render: d => d.dateRicezione || '—' },
        { key: 'dateScadenza',    label: 'Scadenza',         render: d => d.dateScadenza || '—' },
        { key: 'status',          label: 'Stato',            render: d => <Pill tone={ffTone(d.status)}>{d.status}</Pill> },
        { key: 'total',           label: 'Totale', headerClassName: 'text-right',
          className: 'num text-right font-medium text-ink', render: d => d.total ? fmtEur(d.total) : '—' },
      ]}
      filters={[{ key: 'status', label: 'Stato', options: ['Tutti','Bozza','Da pagare','Pagata','Parzialmente pagata','Contestata'], filterFn: (d,v)=>d.status===v }]}
      searchFilter={(d,ql) => d.id.toLowerCase().includes(ql) || d.supplier.toLowerCase().includes(ql) || (d.numDocFornitore||'').toLowerCase().includes(ql)}
      searchPlaceholder="Cerca per numero interno, num. fornitore o fornitore…"
      onNuovo={goNew} onSeleziona={goDetail}
      emptyMessage="Nessuna fattura fornitore corrisponde ai filtri."
    />
  );
};

// ══════════════════════════════════════════════════════════════════════
//  NotaCreditoFornitoreSection
// ══════════════════════════════════════════════════════════════════════
const NotaCreditoFornitoreSection = () => {
  const [view, setView] = useStateD('list');
  const [selId, setSelId] = useStateD(null);
  const aliquote = window.__BI_ALIQUOTE__ || [{ id: 1, desc: 'Ordinaria', pct: 22 }];
  const doc   = SUPPLIER_CREDIT_NOTES.find(n => n.id === selId);
  const lines = selId ? (SUPPLIER_CREDIT_NOTE_LINES[selId] || []) : [];

  const goList   = () => setView('list');
  const goDetail = d => { setSelId(d.id); setView('detail'); };
  const goNew    = () => setView('nuovo');

  const ncfTone  = s => s==='Registrata'?'info':s==='Compensata'?'pos':s==='Rimborsata'?'pos':'neutral';

  if (view === 'nuovo') return (
    <DocumentWizard
      title="Nuova nota credito fornitore"
      labelTorna="Torna alle note credito fornitore"
      labelStep2="Righe"
      labelConferma="Registra nota credito"
      mostraNuovoProdotto={false}
      campiTestata={[
        { key: 'supplierId',      label: 'Fornitore',                     type: 'select', required: true, span: 2, options: _campiFornnitori() },
        { key: 'numDocFornitore', label: 'N° nota credito fornitore',     type: 'text',   required: true, placeholder: 'es. NC-2026-0001' },
        { key: 'status',          label: 'Stato',                         type: 'select', options: ['Registrata','Compensata','Rimborsata'] },
        { key: 'dateDoc',         label: 'Data nota credito',             type: 'date',   required: true },
        { key: 'fatturaRef',      label: 'Riferimento fattura (opz.)',    type: 'text',   placeholder: 'es. FF-2026-0001' },
        { key: 'motivo',          label: 'Motivo',                        type: 'select', options: ['Merce difettosa','Sconto a posteriori','Reso','Errore di fatturazione','Altro'] },
      ]}
      valoriIniziali={{ status: 'Registrata', dateDoc: '2026-05-30', motivo: 'Merce difettosa' }}
      onConferma={(t,l)=>{ _docCreate('SUPPLIER_CREDIT_NOTE', t, l, 'Registrata', 'Nota credito registrata'); goList(); }} onAnnulla={goList}
    />
  );

  if (view === 'detail' && doc) {
    const totals = _fornTotals(lines, aliquote);
    return (
      <DocumentDetail
        labelTipo="Nota credito fornitore" labelTorna="Torna alle note credito fornitore"
        onBack={goList} doc={doc} statusTone={ncfTone}
        headerFields={[
          { label: 'Fornitore',                 value: doc.supplier },
          { label: 'N° nota credito fornitore', value: doc.numDocFornitore || '—', mono: true },
          { label: 'Data nota credito',          value: doc.dateDoc || '—' },
          { label: 'Riferimento fattura',        value: doc.fatturaRef || '—', mono: true },
          { label: 'Motivo',                     value: doc.motivo || '—' },
        ]}
        linee={lines} lineeLabel="Righe nota credito"
        totaleLabel="Totale a credito (imponibile)" totale={totals.imponibile}
        colonneLinee={_colonneIVAForn(aliquote)}
        azioni={_azioniIVA(totals, doc, null)}
      />
    );
  }

  const kpis = [
    { label: 'Note totali',  value: SUPPLIER_CREDIT_NOTES.length },
    { label: 'Registrate',  value: SUPPLIER_CREDIT_NOTES.filter(n=>n.status==='Registrata').length,  tone: 'info' },
    { label: 'Compensate',  value: SUPPLIER_CREDIT_NOTES.filter(n=>n.status==='Compensata').length,  tone: 'pos'  },
    { label: 'Valore tot.', value: fmtEur(SUPPLIER_CREDIT_NOTES.reduce((s,n)=>s+n.total,0)) },
  ];
  return (
    <DocumentList
      title="Note credito fornitore" subtitle="Accrediti ricevuti dai fornitori (resi, sconti, rettifiche)"
      nuovoLabel="Nuova nota credito" documents={SUPPLIER_CREDIT_NOTES} kpis={kpis}
      columns={[
        { key: 'id',              label: 'N° interno',        render: d => <span className="num font-medium text-ink">{d.id}</span> },
        { key: 'numDocFornitore', label: 'N° doc. fornitore', render: d => <span className="num text-muted">{d.numDocFornitore || '—'}</span> },
        { key: 'supplier',        label: 'Fornitore' },
        { key: 'dateDoc',         label: 'Data' },
        { key: 'motivo',          label: 'Motivo' },
        { key: 'status',          label: 'Stato',             render: d => <Pill tone={ncfTone(d.status)}>{d.status}</Pill> },
        { key: 'total',           label: 'Importo', headerClassName: 'text-right',
          className: 'num text-right font-medium text-pos', render: d => d.total ? `+${fmtEur(d.total)}` : '—' },
      ]}
      filters={[{ key: 'status', label: 'Stato', options: ['Tutti','Registrata','Compensata','Rimborsata'], filterFn: (d,v)=>d.status===v }]}
      searchFilter={(d,ql) => d.id.toLowerCase().includes(ql) || d.supplier.toLowerCase().includes(ql)}
      searchPlaceholder="Cerca per numero o fornitore…"
      onNuovo={goNew} onSeleziona={goDetail}
      emptyMessage="Nessuna nota credito fornitore corrisponde ai filtri."
    />
  );
};

Object.assign(window, { DocumentiView });
