// ──────────────────────────── doc-template.jsx ────────────────────────────
// Componenti generici riutilizzabili per tutti i tipi di documento fiscale.
// Non espone voci di navigazione né registra dati propri.

const { useState: useStateDT, useMemo: useMemo_DT } = React;

// ─── Back button riutilizzabile ───
const DocBackButton = ({ label, onClick }) => (
  <button onClick={onClick}
    className="text-[13px] text-muted hover:text-ink inline-flex items-center gap-1.5 focus-ring rounded-md px-2 py-1 -ml-2">
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M15 6l-6 6 6 6"/>
    </svg>
    {label}
  </button>
);

// ─── KPI tile ───
const DocKpiTile = ({ label, value, sub, tone }) => {
  const c = tone === 'pos' ? 'text-pos' : tone === 'warn' ? 'text-warn' : tone === 'neg' ? 'text-neg' : 'text-ink';
  return (
    <div className="bg-surface rounded-2xl p-4 shadow-soft">
      <div className="text-[11px] uppercase tracking-[0.08em] text-muted font-medium">{label}</div>
      <div className={`num mt-1.5 text-[28px] font-semibold ${c}`}>{value}</div>
      {sub && <div className="text-[12px] text-muted mt-0.5">{sub}</div>}
    </div>
  );
};

// ─── Cella prodotto standard (thumbnail + nome + SKU + badge opzionale) ───
const DocProductCell = ({ name, sku, tmpSku, isNew, badge }) => (
  <div className="flex items-center gap-3 min-w-0">
    <div className="w-9 h-9 rounded-md stripe-ph shrink-0"/>
    <div className="min-w-0">
      <div className="text-[13.5px] font-medium text-ink truncate">{name}</div>
      <div className="flex items-center gap-1.5 mt-0.5">
        <span className="num text-[11px] text-muted">{sku || tmpSku || '—'}</span>
        {isNew && <Pill tone="warn">Nuovo</Pill>}
        {badge}
      </div>
    </div>
  </div>
);

// ─── Toggle switch iOS-style ───
// label opzionale: { on: 'Attivo', off: 'Non attivo' }
const DocToggle = ({ value, onChange, label }) => (
  <div className="flex items-center gap-3 h-11">
    <button type="button" onClick={() => onChange(!value)}
      className="focus-ring"
      style={{
        position: 'relative', flexShrink: 0, border: 'none', padding: 0, cursor: 'pointer',
        width: '44px', height: '26px', borderRadius: '13px',
        background: value ? 'var(--accent-blue)' : 'var(--border-strong)',
        transition: 'background 160ms cubic-bezier(0.32,0.72,0,1)',
      }}>
      <span style={{
        position: 'absolute', top: '3px', left: value ? '21px' : '3px',
        width: '20px', height: '20px', borderRadius: '50%',
        background: 'white', boxShadow: '0 1px 3px rgba(0,0,0,0.25)',
        transition: 'left 160ms cubic-bezier(0.32,0.72,0,1)',
      }}/>
    </button>
    {label && <span className="text-[13.5px] text-ink">{value ? label.on : label.off}</span>}
  </div>
);

// ══════════════════════════════════════════════════════════════════════
//  DocumentList — vista lista master generica
//
//  Props:
//    title, subtitle?          — intestazione sezione
//    nuovoLabel                — testo CTA "Nuovo …"
//    documents                 — array di oggetti documento
//    columns: [{ key, label, headerClassName?, className?, render? }]
//    filters?: [{ key, label, options, filterFn }]
//      options: string[] | { v, l }[]  (il primo elemento = "tutti"/default)
//      filterFn: (doc, val) => boolean
//    kpis?: [{ label, value, sub?, tone? }]
//    searchPlaceholder?
//    searchFilter?: (doc, ql) => boolean
//    onNuovo, onSeleziona
//    openLabel?: (doc) => string   — etichetta azione per riga (default Apri/Modifica)
//    emptyMessage?
// ══════════════════════════════════════════════════════════════════════
const DocumentList = ({
  title,
  subtitle,
  nuovoLabel = 'Nuovo',
  documents,
  columns,
  filters = [],
  kpis = [],
  searchPlaceholder = 'Cerca…',
  searchFilter,
  onNuovo,
  onSeleziona,
  openLabel,
  emptyMessage = 'Nessun documento corrisponde ai filtri.',
}) => {
  const [q, setQ] = useStateDT('');
  const [filterVals, setFilterVals] = useStateDT(() => {
    const init = {};
    filters.forEach(f => {
      init[f.key] = typeof f.options?.[0] === 'object' ? f.options[0].v : (f.options?.[0] ?? '');
    });
    return init;
  });

  const setFV = (key, val) => setFilterVals(prev => ({ ...prev, [key]: val }));

  const filtered = useMemo_DT(() => {
    const ql = q.trim().toLowerCase();
    return documents.filter(doc => {
      if (ql && searchFilter && !searchFilter(doc, ql)) return false;
      for (const f of filters) {
        const val = filterVals[f.key];
        const def = typeof f.options?.[0] === 'object' ? f.options[0].v : (f.options?.[0] ?? '');
        if (val !== def && f.filterFn && !f.filterFn(doc, val)) return false;
      }
      return true;
    });
  }, [q, filterVals, documents]);

  return (
    <div className="px-7 py-6 space-y-4 max-w-[1400px]">
      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-[18px] font-semibold tracking-tight text-ink">{title}</h2>
          {subtitle && <p className="text-[13.5px] text-muted mt-0.5">{subtitle}</p>}
        </div>
        <button onClick={onNuovo}
          className="h-16 px-6 rounded-md bg-[var(--accent-blue)] text-[var(--text-inverse)] font-semibold text-[17px] flex items-center gap-3 hover:bg-[var(--accent-blue-hover)] active:bg-[var(--accent-blue-active)] transition-all duration-fast ease-standard shadow-soft">
          <I.Plus size={20}/>
          {nuovoLabel}
        </button>
      </div>

      {kpis.length > 0 && (
        <div className="grid gap-4" style={{ gridTemplateColumns: `repeat(${kpis.length}, 1fr)` }}>
          {kpis.map((kpi, i) => <DocKpiTile key={i} {...kpi}/>)}
        </div>
      )}

      <div className="bg-surface rounded-2xl p-3.5 shadow-soft">
        <div className="flex flex-wrap items-center gap-2.5">
          <div className="relative flex-1 min-w-[240px]">
            <I.Search size={16} className="absolute left-3.5 top-1/2 -translate-y-1/2 text-muted"/>
            <input value={q} onChange={e => setQ(e.target.value)}
              placeholder={searchPlaceholder}
              className="w-full h-11 pl-10 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>
          {filters.map(f => (
            <FilterSelect key={f.key} label={f.label} value={filterVals[f.key]}
              onChange={v => setFV(f.key, v)} options={f.options}/>
          ))}
        </div>
      </div>

      <Card padded={false}>
        <table className="w-full text-[13.5px]">
          <thead>
            <tr className="text-left text-muted uppercase text-[11px] tracking-[0.08em] hairline">
              {columns.map(col => (
                <th key={col.key} className={`px-5 py-3 font-medium ${col.headerClassName || ''}`}>
                  {col.label}
                </th>
              ))}
              <th className="px-5 py-3 font-medium"/>
            </tr>
          </thead>
          <tbody>
            {filtered.map((doc, i) => (
              <tr key={doc.id ?? i} onClick={() => onSeleziona(doc)}
                  className="hover:bg-paper border-b border-line2 last:border-0 cursor-pointer">
                {columns.map(col => (
                  <td key={col.key} className={`px-5 py-4 ${col.className || ''}`}>
                    {col.render ? col.render(doc) : (doc[col.key] ?? '—')}
                  </td>
                ))}
                <td className="px-5 py-4 text-right">
                  <span className="text-[12.5px] text-[var(--accent-blue)] pointer-events-none">
                    {openLabel ? openLabel(doc) : (doc.status === 'Bozza' ? 'Modifica' : 'Apri')}
                  </span>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
        {filtered.length === 0 && (
          <div className="py-16 text-center text-muted text-[14px]">{emptyMessage}</div>
        )}
      </Card>
    </div>
  );
};

// ══════════════════════════════════════════════════════════════════════
//  DocumentWizard — wizard 2-step generico (Testata + Righe)
//
//  Props:
//    title                     — titolo wizard
//    labelTorna                — testo back button
//    labelStep2?               — etichetta step 2 (default 'Prodotti')
//    esistente?                — documento da modificare (pre-popola testata)
//    esistentiLinee?           — righe pre-esistenti
//
//    campiTestata: [{
//      key, label,
//      type: 'text'|'date'|'number'|'select'|'textarea'|'toggle',
//      options?: string[] | { v, l }[],   (per type='select')
//      toggleLabel?: { on, off },          (per type='toggle')
//      placeholder?, required?, disabled?,
//      span?: 2                            (occupa intera riga nella griglia)
//    }]
//    valoriIniziali?           — { [key]: value } — valori iniziali override
//
//    labelConferma             — testo CTA principale (64px)
//    labelBozza?               — testo bozza (se omesso, bottone non mostrato)
//    disabledConferma?         — override del disable CTA (default: lines.length === 0)
//
//    mostraRicercaCatalogo?    — mostra ricerca dal catalogo (default true)
//    mostraNuovoProdotto?      — mostra form prodotto nuovo (default true)
//    qtaField?                 — nome del campo quantità nelle righe (default 'qty')
//    qtaLabel?                 — etichetta colonna quantità (default 'Quantità')
//    totaleLabel?              — etichetta riga totale (default 'Totale')
//
//    validaTestata?            — (valori) => boolean — validazione extra step 1
//    renderExtraTestata?       — (valori, setField) => JSX — contenuto extra sotto il form
//    renderStep2Extra?         — JSX — contenuto extra sopra la ricerca catalogo (es. import CSV)
//    renderLinea?              — (l, idx, updateLine, removeLine) => JSX — riga custom
//    renderLineeHeader?        — () => JSX — header colonne custom (usato con renderLinea)
//
//    onSalvaBozza?             — (testata, linee) => void
//    onConferma                — (testata, linee) => void
//    onAnnulla                 — () => void
// ══════════════════════════════════════════════════════════════════════
const DocumentWizard = ({
  title,
  labelTorna = 'Torna',
  labelStep2 = 'Prodotti',
  esistente,
  esistentiLinee,
  campiTestata = [],
  valoriIniziali = {},
  labelConferma = 'Conferma',
  labelBozza,
  disabledConferma,
  mostraRicercaCatalogo = true,
  mostraNuovoProdotto = true,
  qtaField = 'qty',
  qtaLabel = 'Quantità',
  totaleLabel = 'Totale',
  validaTestata,
  renderExtraTestata,
  renderStep2Extra,
  renderLinea,
  renderLineeHeader,
  onSalvaBozza,
  onConferma,
  onAnnulla,
}) => {
  const [step, setStep] = useStateDT(1);

  const [testata, setTestata] = useStateDT(() => {
    const init = {};
    campiTestata.forEach(f => {
      init[f.key] = valoriIniziali[f.key] ?? (esistente?.[f.key] ?? '');
    });
    return init;
  });
  const setField = (key, val) => setTestata(prev => ({ ...prev, [key]: val }));

  const [lines, setLines] = useStateDT(esistentiLinee || []);
  const [searchQ, setSearchQ] = useStateDT('');
  const [showNewForm, setShowNewForm] = useStateDT(false);
  const [newName, setNewName] = useStateDT('');
  const [newSku, setNewSku] = useStateDT('');
  const [newQty, setNewQty] = useStateDT(1);
  const [newPrice, setNewPrice] = useStateDT('');

  const WIZ = [{ id: 1, label: 'Testata' }, { id: 2, label: labelStep2 }];

  const canNext1 = useMemo_DT(() => {
    const reqOk = campiTestata.filter(f => f.required).every(f => !!testata[f.key]);
    return reqOk && (!validaTestata || validaTestata(testata));
  }, [testata]);

  const total = useMemo_DT(() =>
    lines.reduce((s, l) => s + ((l[qtaField] || 0) * (l.unitPrice || 0)), 0),
  [lines, qtaField]);

  const searchResults = useMemo_DT(() => {
    const ql = searchQ.trim().toLowerCase();
    if (!ql) return [];
    return ARTICLES.filter(a =>
      a.name.toLowerCase().includes(ql) ||
      a.id.toLowerCase().includes(ql) ||
      (a.brand || '').toLowerCase().includes(ql)
    ).slice(0, 8);
  }, [searchQ]);

  const addCatalogLine = (article) => {
    if (lines.find(l => !l.isNew && l.articleId === article.id)) return;
    setLines(prev => [...prev, {
      articleId: article.id, name: article.name, sku: article.id, tmpSku: null,
      [qtaField]: 1, unitPrice: Math.round((article.basePrice || 0) * 0.5),
      isNew: false,
    }]);
    setSearchQ('');
  };

  const addNewLine = () => {
    if (!newName.trim() || !newSku.trim()) return;
    setLines(prev => [...prev, {
      articleId: null, name: newName.trim(), sku: null,
      tmpSku: newSku.trim().toUpperCase(),
      [qtaField]: newQty, unitPrice: parseFloat(newPrice) || 0,
      isNew: true,
    }]);
    setNewName(''); setNewSku(''); setNewQty(1); setNewPrice('');
    setShowNewForm(false);
  };

  const updateLine = (idx, field, val) =>
    setLines(prev => prev.map((l, i) => i !== idx ? l : { ...l, [field]: val }));
  const removeLine = (idx) =>
    setLines(prev => prev.filter((_, i) => i !== idx));

  const confirmDisabled = typeof disabledConferma === 'boolean'
    ? disabledConferma
    : lines.length === 0;

  const cls = 'w-full h-11 px-3 rounded-md border border-line bg-surface text-[14px] text-ink focus:border-strong focus:outline-none transition-all duration-fast ease-standard';
  const lbl = 'block text-[12px] font-semibold uppercase tracking-[0.04em] text-muted mb-1.5';

  return (
    <div className="px-7 py-6 max-w-[1400px]">
      {/* Wizard header con step indicator */}
      <div className="bg-surface rounded-2xl p-5 mb-5 shadow-soft">
        <DocBackButton label={labelTorna} onClick={onAnnulla}/>
        <h2 className="text-[22px] font-semibold tracking-tight text-ink mt-2">{title}</h2>
        <div className="mt-4 flex items-center gap-1">
          {WIZ.map((w, i) => {
            const active = step === w.id;
            const done   = step > w.id;
            return (
              <React.Fragment key={w.id}>
                <div className="flex items-center gap-3 px-1">
                  <span className={`w-9 h-9 rounded-full flex items-center justify-center text-[14px] font-semibold transition-all duration-fast ease-standard
                    ${done ? 'bg-pos text-white' : active ? 'bg-[var(--bg-selected)] text-[var(--accent-blue)]' : 'bg-line2 text-muted'}`}>
                    {done ? <I.Check size={16}/> : w.id}
                  </span>
                  <span className={`text-[14px] font-medium ${active || done ? 'text-ink' : 'text-muted'}`}>{w.label}</span>
                </div>
                {i < WIZ.length - 1 && <div className={`flex-1 h-px ${done ? 'bg-pos' : 'bg-line'}`}/>}
              </React.Fragment>
            );
          })}
        </div>
      </div>

      {/* Step 1: Testata — form generato dinamicamente */}
      {step === 1 && (
        <Card title="Intestazione documento">
          <div className="grid grid-cols-2 gap-5">
            {campiTestata.map(field => (
              <div key={field.key} className={field.span === 2 ? 'col-span-2' : ''}>
                <label className={lbl}>{field.label}{field.required ? ' *' : ''}</label>
                {field.type === 'select' ? (
                  <select className={cls} value={testata[field.key] || ''}
                    onChange={e => setField(field.key, e.target.value)}
                    disabled={!!field.disabled} style={field.disabled ? { opacity: 0.6 } : {}}>
                    <option value="">— Seleziona —</option>
                    {(field.options || []).map(o => {
                      const v = typeof o === 'object' ? o.v : o;
                      const l = typeof o === 'object' ? o.l : o;
                      return <option key={v} value={v}>{l}</option>;
                    })}
                  </select>
                ) : field.type === 'textarea' ? (
                  <textarea value={testata[field.key] || ''}
                    onChange={e => setField(field.key, e.target.value)}
                    placeholder={field.placeholder || ''}
                    className="w-full h-20 px-3 py-2 rounded-md border border-line bg-surface text-[14px] text-ink focus:border-strong focus:outline-none resize-none transition-all duration-fast ease-standard"/>
                ) : field.type === 'toggle' ? (
                  <DocToggle value={!!testata[field.key]}
                    onChange={v => setField(field.key, v)}
                    label={field.toggleLabel}/>
                ) : (
                  <input type={field.type || 'text'} className={cls}
                    value={testata[field.key] || ''}
                    onChange={e => setField(field.key, e.target.value)}
                    placeholder={field.placeholder || ''}
                    disabled={!!field.disabled}
                    style={field.disabled ? { opacity: 0.6 } : {}}/>
                )}
              </div>
            ))}
          </div>
          {renderExtraTestata && (
            <div className="mt-4 pt-4 border-t border-line">
              {renderExtraTestata(testata, setField)}
            </div>
          )}
        </Card>
      )}

      {/* Step 2: Prodotti / Righe */}
      {step === 2 && (
        <div className="space-y-4">
          {renderStep2Extra}

          {mostraRicercaCatalogo && (
            <Card title="Aggiungi prodotti dal catalogo">
              <div className="relative mb-3">
                <I.Search size={16} className="absolute left-3.5 top-1/2 -translate-y-1/2 text-muted"/>
                <input value={searchQ} onChange={e => setSearchQ(e.target.value)}
                  placeholder="Cerca prodotto per nome, codice o brand…"
                  className="w-full h-11 pl-10 pr-4 rounded-md border border-line bg-surface text-[14px] focus:border-strong transition-all duration-fast ease-standard"/>
              </div>
              {searchResults.length > 0 && (
                <div className="rounded-xl overflow-hidden" style={{ border: '0.5px solid var(--border-default)' }}>
                  {searchResults.map(a => (
                    <button key={a.id} onClick={() => addCatalogLine(a)}
                      className="w-full px-4 py-3 flex items-center gap-3 hover:bg-paper text-left border-b border-line2 last:border-0 transition-colors duration-fast ease-standard">
                      <div className="w-9 h-9 rounded-md stripe-ph shrink-0"/>
                      <div className="flex-1 min-w-0">
                        <div className="text-[13.5px] font-medium text-ink truncate">{a.name}</div>
                        <div className="text-[11.5px] text-muted">{a.brand} · {a.cat} · {a.id}</div>
                      </div>
                      <span className="flex items-center gap-1 text-[12px] text-[var(--accent-blue)] shrink-0">
                        <I.Plus size={13}/> Aggiungi
                      </span>
                    </button>
                  ))}
                </div>
              )}
              {searchQ.trim() !== '' && searchResults.length === 0 && (
                <p className="text-[13px] text-muted mt-1">Nessun prodotto trovato per "{searchQ}".</p>
              )}
            </Card>
          )}

          {mostraNuovoProdotto && (
            <Card title="Prodotto non ancora in catalogo">
              {!showNewForm ? (
                <button onClick={() => setShowNewForm(true)}
                  className="h-11 flex items-center gap-2 text-[13.5px] font-medium text-[var(--accent-blue)] hover:underline focus-ring rounded-md px-1">
                  <I.Plus size={14}/>
                  + Aggiungi prodotto non in catalogo
                </button>
              ) : (
                <div className="grid grid-cols-2 gap-4">
                  <div>
                    <label className={lbl}>Nome prodotto *</label>
                    <input value={newName} onChange={e => setNewName(e.target.value)}
                      placeholder="es. Cappello cashmere" className={cls}/>
                  </div>
                  <div>
                    <label className={lbl}>SKU / Codice *</label>
                    <input value={newSku} onChange={e => setNewSku(e.target.value)}
                      placeholder="es. HAT-0001" className={cls}/>
                  </div>
                  <div>
                    <label className={lbl}>{qtaLabel}</label>
                    <input type="number" min="1" value={newQty}
                      onChange={e => setNewQty(Math.max(1, parseInt(e.target.value) || 1))}
                      className={cls}/>
                  </div>
                  <div>
                    <label className={lbl}>Prezzo unitario (€)</label>
                    <input type="number" min="0" step="0.01" value={newPrice}
                      onChange={e => setNewPrice(e.target.value)}
                      placeholder="0.00" className={cls}/>
                  </div>
                  <div className="col-span-2 flex gap-2">
                    <Btn variant="primary" size="md"
                      disabled={!newName.trim() || !newSku.trim()} onClick={addNewLine}>
                      Aggiungi riga
                    </Btn>
                    <Btn variant="outline" size="md" onClick={() => setShowNewForm(false)}>Annulla</Btn>
                  </div>
                </div>
              )}
            </Card>
          )}

          <Card title={`Righe (${lines.length})`} padded={false}>
            {lines.length === 0 ? (
              <div className="p-8 text-center text-muted text-[13.5px]">
                Nessun prodotto aggiunto. Cerca nel catalogo o aggiungi un articolo.
              </div>
            ) : (
              <>
                {renderLineeHeader
                  ? renderLineeHeader()
                  : !renderLinea && (
                    <div className="grid grid-cols-[1fr_100px_150px_140px_48px] gap-2 px-5 h-11 items-center text-[11px] uppercase tracking-[0.08em] text-muted font-medium hairline">
                      <div>Prodotto</div>
                      <div className="text-right">{qtaLabel}</div>
                      <div className="text-right">Prezzo unit. (€)</div>
                      <div className="text-right">Totale riga</div>
                      <div/>
                    </div>
                  )
                }
                <div className="divide-y divide-line2">
                  {lines.map((l, idx) => (
                    <React.Fragment key={idx}>
                      {renderLinea
                        ? renderLinea(l, idx, updateLine, removeLine)
                        : (
                          <div className="row-h grid grid-cols-[1fr_100px_150px_140px_48px] gap-2 px-5 items-center">
                            <DocProductCell name={l.name} sku={l.sku} tmpSku={l.tmpSku} isNew={l.isNew}/>
                            <div className="flex justify-end">
                              <input type="number" min="1" value={l[qtaField] || ''}
                                onChange={e => updateLine(idx, qtaField, Math.max(1, parseInt(e.target.value) || 1))}
                                className="w-16 h-10 px-2 rounded-sm border border-line bg-surface num text-[14px] text-right focus:border-strong transition-all"/>
                            </div>
                            <div className="flex justify-end">
                              <input type="number" min="0" step="0.01" value={l.unitPrice || ''}
                                onChange={e => updateLine(idx, 'unitPrice', parseFloat(e.target.value) || 0)}
                                className="w-28 h-10 px-2 rounded-sm border border-line bg-surface num text-[14px] text-right focus:border-strong transition-all"/>
                            </div>
                            <div className="num text-[14px] font-semibold text-ink text-right">
                              {fmtEur((l[qtaField] || 0) * (l.unitPrice || 0))}
                            </div>
                            <div className="flex justify-center">
                              <button onClick={() => removeLine(idx)}
                                className="w-9 h-9 rounded-md flex items-center justify-center text-muted hover:bg-[var(--danger-50)] hover:text-[var(--danger-700)] transition-colors duration-fast ease-standard focus-ring">
                                <I.Trash size={14}/>
                              </button>
                            </div>
                          </div>
                        )
                      }
                    </React.Fragment>
                  ))}
                </div>
                <div className="px-5 py-4 border-t border-line flex justify-end items-center gap-6">
                  <span className="text-[13px] text-muted">{totaleLabel}</span>
                  <span className="num text-[22px] font-semibold text-ink">{fmtEur(total)}</span>
                </div>
              </>
            )}
          </Card>
        </div>
      )}

      {/* Footer navigazione wizard */}
      <div className="mt-5 flex items-center justify-between bg-surface rounded-2xl p-4 shadow-soft">
        <div>
          {step > 1 ? (
            <Btn variant="outline" size="lg" onClick={() => setStep(step - 1)}
              leading={
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M15 6l-6 6 6 6"/>
                </svg>
              }>
              Indietro
            </Btn>
          ) : (
            <Btn variant="outline" size="lg" onClick={onAnnulla}>Annulla</Btn>
          )}
        </div>
        <div className="flex items-center gap-3">
          <span className="text-[12.5px] text-muted">Step {step} di 2</span>
          {step < 2 ? (
            <Btn variant="primary" size="lg" disabled={!canNext1} onClick={() => setStep(2)}
              trailing={<I.ArrowR size={18}/>}>
              Avanti
            </Btn>
          ) : (
            <>
              {labelBozza && onSalvaBozza && (
                <Btn variant="outline" size="lg" onClick={() => onSalvaBozza(testata, lines)}>
                  {labelBozza}
                </Btn>
              )}
              <button onClick={() => onConferma(testata, lines)}
                disabled={confirmDisabled}
                className="h-16 px-8 rounded-md bg-[var(--accent-blue)] text-[var(--text-inverse)] font-semibold text-[17px] flex items-center gap-3 hover:bg-[var(--accent-blue-hover)] active:bg-[var(--accent-blue-active)] disabled:opacity-30 disabled:cursor-not-allowed transition-all duration-fast ease-standard shadow-soft">
                <I.Check size={20}/>
                {labelConferma}
              </button>
            </>
          )}
        </div>
      </div>
    </div>
  );
};

// ══════════════════════════════════════════════════════════════════════
//  DocumentDetail — vista dettaglio sola lettura
//
//  Props:
//    labelTipo?        — etichetta sopra il numero documento (es. "Ordine cliente")
//    labelTorna        — testo back button
//    onBack            — callback
//    doc               — oggetto documento (serve almeno doc.id, doc.status)
//    statusTone?       — (status) => tone: mappi status → tone Pill
//
//    headerFields: [{ label, value, mono? }]
//      — visualizzati in griglia KeyVal (max 4 colonne per riga)
//    renderExtraTestata? — JSX aggiunto sotto la griglia di campi
//
//    linee: array
//    colonneLinee?: [{ key, label, width?, headerClassName?, className?, render? }]
//      — se omesso usa layout predefinito: prodotto / qty / prezzo / totale
//    lineeLabel?       — etichetta card righe (default 'Prodotti')
//    totaleLabel?      — (default 'Totale')
//    totale            — valore numerico totale
//
//    azioni?           — JSX — pulsanti di azione sotto la card righe
// ══════════════════════════════════════════════════════════════════════
const DocumentDetail = ({
  labelTipo,
  labelTorna = 'Torna',
  onBack,
  doc,
  statusTone,
  headerFields = [],
  renderExtraTestata,
  linee = [],
  colonneLinee,
  lineeLabel = 'Prodotti',
  totaleLabel = 'Totale',
  totale,
  azioni,
}) => {
  const colsForGrid = colonneLinee
    ? colonneLinee.map(c => c.width || '1fr').join(' ')
    : '1fr 100px 140px 140px';

  const headerCols = Math.min(Math.max(headerFields.length, 1), 4);

  // Export PDF mirato: genera l'HTML del SOLO documento (intestazione + righe + totale).
  const exportPdf = () => {
    const esc = (s) => String(s == null ? '' : s).replace(/[&<>]/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' }[c]));
    const meta = headerFields
      .filter(f => typeof f.value !== 'object')
      .map(f => `<div><span class="l">${esc(f.label)}</span><span>${esc(f.value)}</span></div>`).join('');
    const rows = (linee || []).map(l => {
      const price = l.unitPrice != null ? l.unitPrice : (l.price != null ? l.price : 0);
      const qty = l.qty != null ? l.qty : (l.returnQty != null ? l.returnQty : (l.receivedQty != null ? l.receivedQty : 0));
      const tot = price * qty * (1 - ((l.discount || 0) / 100));
      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(tot))}</td></tr>`;
    }).join('');
    const html =
      `<div class="row"><h1>${esc(labelTipo || 'Documento')}</h1>` +
      `<div style="text-align:right"><div class="brand">EASY2SELL</div><div class="muted">${esc(doc?.id || '')}</div>` +
      (doc?.status ? `<div class="muted">${esc(doc.status)}</div>` : '') + `</div></div>` +
      (meta ? `<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>` +
      (totale != null ? `<div class="tot"><span class="muted">${esc(totaleLabel)}</span><span>${esc(fmtEur(totale))}</span></div>` : '');
    if (window.__printDoc) window.__printDoc(`${labelTipo || 'Documento'} ${doc?.id || ''}`, html);
  };

  return (
    <div className="px-7 py-6 max-w-[1400px]">
      <DocBackButton label={labelTorna} onClick={onBack}/>

      <div className="flex items-start justify-between gap-4 mt-3 mb-5">
        <div>
          {labelTipo && (
            <div className="text-[11px] uppercase tracking-[0.08em] text-muted font-medium">{labelTipo}</div>
          )}
          <div className="text-[22px] font-semibold tracking-tight text-ink mt-0.5">{doc?.id || '—'}</div>
        </div>
        <div className="flex items-center gap-3">
          <Btn variant="outline" size="md" leading={<I.ArrowD size={16}/>} onClick={exportPdf}>Esporta PDF</Btn>
          {doc?.status && (
            <Pill tone={statusTone ? statusTone(doc.status) : 'neutral'}>{doc.status}</Pill>
          )}
        </div>
      </div>

      {headerFields.length > 0 && (
        <Card className="mb-4">
          <div className="grid gap-5" style={{ gridTemplateColumns: `repeat(${headerCols}, 1fr)` }}>
            {headerFields.map((f, i) => <KeyVal key={i} label={f.label} value={f.value} mono={f.mono}/>)}
          </div>
          {renderExtraTestata && (
            <div className="mt-4 pt-4 border-t border-line">{renderExtraTestata}</div>
          )}
        </Card>
      )}

      <Card title={`${lineeLabel} — ${linee.length} righe`} padded={false}>
        {/* Intestazione colonne */}
        {colonneLinee ? (
          <div className="grid px-5 h-11 items-center text-[11px] uppercase tracking-[0.08em] text-muted font-medium hairline"
            style={{ gridTemplateColumns: colsForGrid }}>
            {colonneLinee.map(col => (
              <div key={col.key} className={col.headerClassName || ''}>{col.label}</div>
            ))}
          </div>
        ) : (
          <div className="grid grid-cols-[1fr_100px_140px_140px] px-5 h-11 items-center text-[11px] uppercase tracking-[0.08em] text-muted font-medium hairline">
            <div>Prodotto</div>
            <div className="text-right">Quantità</div>
            <div className="text-right">Prezzo unit.</div>
            <div className="text-right">Totale riga</div>
          </div>
        )}

        {/* Righe */}
        <div className="divide-y divide-line2">
          {linee.map((l, i) => (
            <div key={i} className="row-h grid px-5 items-center"
              style={{ gridTemplateColumns: colsForGrid }}>
              {colonneLinee
                ? colonneLinee.map(col => (
                    <div key={col.key} className={col.className || ''}>
                      {col.render ? col.render(l, i) : (l[col.key] ?? '—')}
                    </div>
                  ))
                : (
                  <>
                    <DocProductCell name={l.name} sku={l.sku} tmpSku={l.tmpSku} isNew={l.isNew}/>
                    <div className="num text-[15px] text-ink text-right">
                      {l.qty ?? l.receivedQty ?? '—'}
                    </div>
                    <div className="num text-[15px] text-ink text-right">
                      {l.unitPrice != null ? fmtEur(l.unitPrice) : '—'}
                    </div>
                    <div className="num text-[15px] font-semibold text-ink text-right">
                      {l.unitPrice != null
                        ? fmtEur((l.qty ?? l.receivedQty ?? 0) * l.unitPrice)
                        : '—'}
                    </div>
                  </>
                )
              }
            </div>
          ))}
          {linee.length === 0 && (
            <div className="py-10 text-center text-muted text-[13.5px]">Nessuna riga.</div>
          )}
        </div>

        {/* Totale */}
        <div className="px-5 py-4 border-t border-line flex justify-end items-center gap-6">
          <span className="text-[13px] text-muted">{totaleLabel}</span>
          <span className="num text-[22px] font-semibold text-ink">
            {totale !== undefined ? fmtEur(totale) : '—'}
          </span>
        </div>
      </Card>

      {azioni && <div className="mt-4">{azioni}</div>}
    </div>
  );
};

Object.assign(window, {
  DocBackButton,
  DocKpiTile,
  DocProductCell,
  DocToggle,
  DocumentList,
  DocumentWizard,
  DocumentDetail,
});
