// ============================================================
// ui.jsx — reusable UI pieces
// ============================================================

function Chip({ kind = 'default', children, dot = false }) {
  return (
    <span className={`chip ${kind !== 'default' ? kind : ''}`}>
      {dot && <span className="dot" />}
      {children}
    </span>
  );
}

function Btn(props) {
  const variant = props.variant || '';
  const size = props.size || '';
  const icon = props.icon || false;
  const cls = ['btn', variant, size, icon ? 'icon' : ''].filter(Boolean).join(' ');
  // NB: niente destructuring `...rest` né spread JSX `{...rest}`. Il Babel
  // in-browser (Babel-standalone, vedi warning "precompile for production")
  // compila in modo corrotto gli helper _extends/_objectWithoutProperties su
  // payload grandi, scartando props critiche come onClick/disabled → bottoni
  // morti. Qui costruiamo le props del button con un loop nativo + oggetto
  // piano: zero helper, robusto. Preserva onClick, disabled, title, type,
  // style, data-* e qualunque altra prop.
  const out = { className: cls };
  for (const k in props) {
    if (k === 'variant' || k === 'size' || k === 'icon' || k === 'children') continue;
    out[k] = props[k];
  }
  return React.createElement('button', out, props.children);
}

function Stat({ label, value, unit, delta, tone, spark }) {
  return (
    <div className="stat">
      <div className="label">{label}</div>
      <div className="value">{value}{unit && <span className="unit">{unit}</span>}</div>
      {delta != null && <div className={`delta ${tone || ''}`}>{delta}</div>}
      {spark && <div className="spark">{spark}</div>}
    </div>
  );
}

// simple svg sparkline from array of numbers
function Spark({ data, width = 110, height = 30, tone }) {
  if (!data || data.length < 2) return null;
  const min = Math.min(...data);
  const max = Math.max(...data);
  const range = max - min || 1;
  const step = width / (data.length - 1);
  const points = data.map((v, i) => [i * step, height - ((v - min) / range) * (height - 4) - 2]);
  const line = points.map((p, i) => (i === 0 ? 'M' : 'L') + p[0].toFixed(1) + ' ' + p[1].toFixed(1)).join(' ');
  const area = line + ` L ${width} ${height} L 0 ${height} Z`;
  return (
    <svg className={`spark ${tone || ''}`} width={width} height={height}>
      <path className="area" d={area} />
      <path className="line" d={line} />
    </svg>
  );
}

// Barchart minimal
function MiniBars({ data, width = 260, height = 60, tone = '' }) {
  const max = Math.max(...data.map((d) => Math.max(d.p, d.a)));
  const bw = width / data.length;
  return (
    <svg width={width} height={height} style={{ display: 'block' }}>
      {data.map((d, i) => {
        const hp = (d.p / max) * (height - 10);
        const ha = (d.a / max) * (height - 10);
        const x = i * bw;
        return (
          <g key={i}>
            <rect x={x + bw * 0.18} y={height - hp} width={bw * 0.3} height={hp} fill="var(--bg-4)" />
            <rect x={x + bw * 0.52} y={height - ha} width={bw * 0.3} height={ha} fill="var(--accent)" />
          </g>
        );
      })}
    </svg>
  );
}

function Health({ h }) {
  const m = { ok: ['ok', 'In linea'], warn: ['warn', 'Attenzione'], err: ['err', 'Critico'] };
  const [kind, label] = m[h] || ['default', h];
  return <Chip kind={kind} dot>{label}</Chip>;
}

function PhaseChip({ phase }) {
  return <Chip kind="info">{phaseLabel(phase)}</Chip>;
}

function Meter({ value, tone = '', thick = false }) {
  return (
    <div className={`meter ${tone} ${thick ? 'thick' : ''}`}>
      <span style={{ width: Math.max(0, Math.min(100, value)) + '%' }} />
    </div>
  );
}

function Avatar({ name, size = 24 }) {
  const initials = name ? name.split(' ').map((s) => s[0]).slice(0, 2).join('') : '?';
  return (
    <span style={{
      width: size, height: size, borderRadius: '50%',
      background: 'var(--bg-4)',
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      color: 'var(--text-0)', fontWeight: 600, fontSize: Math.round(size * 0.42),
    }}>{initials}</span>
  );
}

function EmptyState({ icon, title, desc, action }) {
  return (
    <div style={{ textAlign: 'center', padding: '48px 20px', color: 'var(--text-2)' }}>
      {icon && <div style={{ marginBottom: 10, color: 'var(--text-3)' }}>{icon}</div>}
      <div style={{ fontFamily: 'var(--font-display)', fontSize: 20, color: 'var(--text-0)', fontWeight: 500, letterSpacing: '-0.01em' }}>{title}</div>
      {desc && <div style={{ marginTop: 6, fontSize: 12.5, maxWidth: 420, marginLeft: 'auto', marginRight: 'auto', lineHeight: 1.5 }}>{desc}</div>}
      {action && <div style={{ marginTop: 14 }}>{action}</div>}
    </div>
  );
}

function Section({ title, desc, actions, children }) {
  return (
    <section style={{ marginBottom: 20 }}>
      <header style={{ display: 'flex', alignItems: 'flex-end', gap: 12, marginBottom: 10 }}>
        <div>
          <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--text-0)' }}>{title}</div>
          {desc && <div style={{ fontSize: 11.5, color: 'var(--text-2)', marginTop: 2 }}>{desc}</div>}
        </div>
        <div style={{ flex: 1 }} />
        {actions}
      </header>
      {children}
    </section>
  );
}

function Modal({ open, onClose, title, children, footer, size = 'md' }) {
  if (!open) return null;
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className={`modal ${size === 'lg' ? 'lg' : ''}`} onClick={(e) => e.stopPropagation()}>
        <div className="modal-header">
          <div className="title">{title}</div>
          <div style={{ flex: 1 }} />
          <button className="btn ghost icon" onClick={onClose}><Icon name="x" /></button>
        </div>
        <div className="modal-body">{children}</div>
        {footer && <div className="modal-footer">{footer}</div>}
      </div>
    </div>
  );
}

function Toasts() {
  const { toasts } = useStore();
  return (
    <div className="toast-wrap">
      {toasts.map((t) => (
        <div key={t.id} className={`toast ${t.tone || ''} fade-in`}>
          <div className="t">{t.title}</div>
          {t.desc && <div className="d">{t.desc}</div>}
        </div>
      ))}
    </div>
  );
}

// ============================================================
// Pagination — hook + UI
// ============================================================
function usePaginated(items, initialPageSize = 10) {
  const [page, setPage] = React.useState(1);
  const [pageSize, setPageSize] = React.useState(initialPageSize);
  const total = items.length;
  const pages = Math.max(1, Math.ceil(total / pageSize));
  React.useEffect(() => { if (page > pages) setPage(pages); }, [pages]);
  const start = (page - 1) * pageSize;
  const slice = items.slice(start, start + pageSize);
  return { page, setPage, pageSize, setPageSize, pages, total, start, slice };
}

function Pagination({ page, pages, total, pageSize, setPage, setPageSize, sizes = [10, 25, 50, 100], compact = false }) {
  const from = total === 0 ? 0 : (page - 1) * pageSize + 1;
  const to = Math.min(total, page * pageSize);
  // visible page buttons
  const buttons = [];
  const push = (p) => buttons.push(p);
  if (pages <= 7) {
    for (let i = 1; i <= pages; i++) push(i);
  } else {
    push(1);
    if (page > 3) push('…');
    const s = Math.max(2, page - 1), e = Math.min(pages - 1, page + 1);
    for (let i = s; i <= e; i++) push(i);
    if (page < pages - 2) push('…');
    push(pages);
  }
  return (
    <div className="row" style={{
      justifyContent: 'space-between', alignItems: 'center', padding: '8px 12px',
      borderTop: '1px solid var(--line)', fontSize: 11.5, color: 'var(--text-2)', gap: 10, flexWrap: 'wrap'
    }}>
      <div className="row" style={{ gap: 8, alignItems: 'center' }}>
        <span className="mono">{from}-{to}</span> di <span className="mono">{total}</span>
        {!compact && setPageSize && (
          <>
            <span style={{ color: 'var(--text-3)', marginLeft: 6 }}>·</span>
            <span>righe per pagina</span>
            <select value={pageSize} onChange={(e) => { setPageSize(Number(e.target.value)); setPage(1); }}
              style={{ background: 'var(--bg-2)', border: '1px solid var(--line)', color: 'var(--text-1)', padding: '3px 6px', fontSize: 11, borderRadius: 4 }}>
              {sizes.map(s => <option key={s} value={s}>{s}</option>)}
            </select>
          </>
        )}
      </div>
      <div className="row" style={{ gap: 2 }}>
        <button className="btn ghost sm icon" disabled={page <= 1} onClick={() => setPage(1)} title="Prima"><Icon name="chev_l" size={12}/><Icon name="chev_l" size={12}/></button>
        <button className="btn ghost sm icon" disabled={page <= 1} onClick={() => setPage(page - 1)} title="Precedente"><Icon name="chev_l" size={12}/></button>
        {buttons.map((b, i) => b === '…'
          ? <span key={'d'+i} style={{ padding: '0 6px', color: 'var(--text-3)' }}>…</span>
          : <button key={b} className={`btn sm ${b === page ? 'primary' : 'ghost'}`} onClick={() => setPage(b)} style={{ minWidth: 26, padding: '4px 8px' }}>{b}</button>)}
        <button className="btn ghost sm icon" disabled={page >= pages} onClick={() => setPage(page + 1)} title="Successiva"><Icon name="chev_r" size={12}/></button>
        <button className="btn ghost sm icon" disabled={page >= pages} onClick={() => setPage(pages)} title="Ultima"><Icon name="chev_r" size={12}/><Icon name="chev_r" size={12}/></button>
      </div>
    </div>
  );
}

Object.assign(window, { Chip, Btn, Stat, Spark, MiniBars, Health, PhaseChip, Meter, Avatar, EmptyState, Section, Modal, Toasts, usePaginated, Pagination });
