// VxTable: tabela padrão do Vértice OS. Mesmo comportamento da tabela de Prospects:
// ordenação por coluna (vazios sempre no fim), redimensionar (arrastar a borda; duplo clique restaura),
// mover colunas (arrastar o cabeçalho ou Alt + setas) e preferências guardadas por tabela neste navegador.
// Uso: <VxTable id="usuarios" ...mesmas props da Table do design system />.
// Por coluna (opcional): sort={row=>valor} para ordenar por um valor derivado; sortable={false} para desligar;
// fixed para não mover. Colunas com rótulo que não é texto (ex.: checkbox) ficam fixas e sem ordenação.
const VT_PREFIX = 'vx-tbl-';
const vtLS = (k, d) => { try { const v = JSON.parse(localStorage.getItem(VT_PREFIX + k)); return v == null ? d : v; } catch (e) { return d; } };
const vtLSet = (k, v) => { try { localStorage.setItem(VT_PREFIX + k, JSON.stringify(v)); } catch (e) {} };
const vtEmpty = v => v == null || v === '' || (typeof v === 'string' && !v.trim());
const vtPx = w => { const m = /^(\d+(?:\.\d+)?)px$/.exec(String(w || '')) || /minmax\((\d+(?:\.\d+)?)px/.exec(String(w || '')); return m ? Number(m[1]) : 120; };
const vtMove = (order, from, to) => { const a = order.filter(k => k !== from), i = a.indexOf(to); if (i < 0) return order; a.splice(i, 0, from); return a; };
const vtShift = (order, k, dir) => { const i = order.indexOf(k), j = i + dir; if (i < 0 || j < 0 || j >= order.length) return order; const a = [...order]; [a[i], a[j]] = [a[j], a[i]]; return a; };

function vtSortRows(list, col, dir) {
  const g = typeof col.sort === 'function' ? col.sort : r => r[col.key];
  const d = dir === 'asc' ? 1 : -1;
  return [...list].sort((a, b) => {
    const x = g(a), y = g(b), ex = vtEmpty(x), ey = vtEmpty(y);
    if (ex || ey) return ex && ey ? 0 : ex ? 1 : -1;
    const nx = typeof x === 'number' || x instanceof Date, ny = typeof y === 'number' || y instanceof Date;
    return d * (nx && ny ? x - y : String(x).localeCompare(String(y), 'pt-BR', { numeric: true, sensitivity: 'base' }));
  });
}

function VtHead({ k, label, w, def, sortable, sortState, onSort, onResize, dragK, overK, onDragK, onOverK, onMove, onShift, movable }) {
  const raf = React.useRef(0);
  const on = sortState && sortState.k === k;
  const start = e => {
    e.preventDefault(); e.stopPropagation();
    const x0 = e.clientX, w0 = w, el = e.currentTarget;
    try { el.setPointerCapture(e.pointerId); } catch (_) {}
    const mv = ev => { cancelAnimationFrame(raf.current); const nx = Math.max(70, Math.min(700, Math.round(w0 + ev.clientX - x0))); raf.current = requestAnimationFrame(() => onResize(k, nx)); };
    const up = () => { el.removeEventListener('pointermove', mv); el.removeEventListener('pointerup', up); el.removeEventListener('pointercancel', up); };
    el.addEventListener('pointermove', mv); el.addEventListener('pointerup', up); el.addEventListener('pointercancel', up);
  };
  const handleKey = e => { if (e.altKey && (e.key === 'ArrowLeft' || e.key === 'ArrowRight')) { e.preventDefault(); onShift(k, e.key === 'ArrowLeft' ? -1 : 1); } };
  const hl = overK === k && dragK && dragK !== k;
  const text = sortable
    ? <button type="button" aria-label={'Ordenar por ' + label + (on ? (sortState.d === 'asc' ? ' (crescente)' : ' (decrescente)') : '')} onClick={e => { e.stopPropagation(); onSort(k); }}
        style={{ all: 'unset', cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 5, font: 'inherit', letterSpacing: 'inherit', textTransform: 'inherit', color: on ? 'var(--text-primary)' : 'inherit', whiteSpace: 'normal', textAlign: 'left', lineHeight: 1.3, maxWidth: '100%' }}>
        {label}<i className={'ph ' + (on ? (sortState.d === 'asc' ? 'ph-arrow-up' : 'ph-arrow-down') : 'ph-arrows-down-up')} style={{ fontSize: 12, opacity: on ? 1 : .45 }} /></button>
    : label;
  return <div role="presentation" draggable={movable}
    onDragStart={e => { e.dataTransfer.effectAllowed = 'move'; try { e.dataTransfer.setData('text/plain', k); } catch (_) {} onDragK(k); }}
    onDragEnd={() => { onDragK(null); onOverK(null); }}
    onDragOver={e => { if (dragK) { e.preventDefault(); onOverK(k); } }}
    onDrop={e => { e.preventDefault(); if (dragK && dragK !== k) onMove(dragK, k); onDragK(null); onOverK(null); }}
    onKeyDown={handleKey}
    style={{ position: 'relative', display: 'flex', alignItems: 'center', minWidth: 0, cursor: movable ? 'grab' : undefined, boxShadow: hl ? '-3px 0 0 var(--text-accent)' : undefined, opacity: dragK === k ? .45 : 1 }}
    title={movable ? 'Arraste para reordenar (ou Alt + setas)' : undefined}>
    {text}
    <span role="separator" aria-orientation="vertical" aria-label="Ajustar largura da coluna" onPointerDown={start}
      onDoubleClick={e => { e.stopPropagation(); onResize(k, def); }} onClick={e => e.stopPropagation()}
      style={{ position: 'absolute', right: -12, top: -8, bottom: -8, width: 12, cursor: 'col-resize', touchAction: 'none', display: 'flex', justifyContent: 'center' }}>
      <span style={{ width: 2, height: '100%', background: 'var(--border-subtle)', borderRadius: 1 }} />
    </span>
  </div>;
}

function VxTable({ id, columns = [], rows = [], minWidth = 680, cellX = 24, ...rest }) {
  const { Table } = window.VRticeDesignSystem_d763eb;
  const [sort, setSortS] = React.useState(() => vtLS(id + '-sort', null));
  const [colW, setColW] = React.useState(() => vtLS(id + '-w', {}));
  const [order, setOrder] = React.useState(() => vtLS(id + '-order', []));
  const [dragK, setDragK] = React.useState(null), [overK, setOverK] = React.useState(null);
  const setSort = s => { setSortS(s); vtLSet(id + '-sort', s); };
  const setW = (k, w) => setColW(o => { const n = { ...o, [k]: w }; vtLSet(id + '-w', n); return n; });
  const textual = c => typeof c.label === 'string';
  const fixed = c => !textual(c) || c.fixed;
  // Ordem salva só vale para colunas móveis; as fixas mantêm a posição original.
  const movableKeys = columns.filter(c => !fixed(c)).map(c => c.key);
  const ordered = [...order.filter(k => movableKeys.includes(k)), ...movableKeys.filter(k => !order.includes(k))];
  let mi = 0;
  const finalCols = columns.map(c => { if (fixed(c)) return c; const k = ordered[mi++]; return columns.find(x => x.key === k); });
  const sortable = c => textual(c) && c.sortable !== false && (typeof c.sort === 'function' || rows.some(r => r && !vtEmpty(r[c.key]) && typeof r[c.key] !== 'object'));
  const moveCol = (from, to) => { const n = vtMove(ordered, from, to); setOrder(n); vtLSet(id + '-order', n); };
  const shiftCol = (k, dir) => { const n = vtShift(ordered, k, dir); setOrder(n); vtLSet(id + '-order', n); };
  const onSort = k => setSort(sort && sort.k === k ? { k, d: sort.d === 'asc' ? 'desc' : 'asc' } : { k, d: 'asc' });
  const sc = sort && finalCols.find(c => c.key === sort.k && sortable(c));
  const data = sc ? vtSortRows(rows, sc, sort.d) : rows;
  const outCols = finalCols.map(c => {
    if (!textual(c)) return c;
    const defW = vtPx(c.width), w = colW[c.key];
    return {
      ...c,
      width: w ? w + 'px' : c.width,
      label: <VtHead k={c.key} label={c.label} w={w || defW} def={defW} sortable={sortable(c)} sortState={sort} onSort={onSort} onResize={setW}
        dragK={dragK} overK={overK} onDragK={setDragK} onOverK={setOverK} onMove={moveCol} onShift={shiftCol} movable={!c.fixed} />
    };
  });
  const total = outCols.reduce((s, c) => s + vtPx(c.width), 0) + 16 * Math.max(0, outCols.length - 1) + 2 * cellX;
  return <div>
    {(sort || Object.keys(colW).length > 0 || order.length > 0) && <div style={{ display: 'flex', justifyContent: 'flex-end', padding: '0 ' + cellX + 'px 6px' }}>
      <button type="button" onClick={() => { setSort(null); setColW({}); setOrder([]); vtLSet(id + '-w', {}); vtLSet(id + '-order', []); }}
        style={{ all: 'unset', cursor: 'pointer', fontSize: 12, color: 'var(--text-subtle)', textDecoration: 'underline' }}>Restaurar colunas</button>
    </div>}
    <Table {...rest} cellX={cellX} columns={outCols} rows={data} minWidth={Math.max(minWidth, total)} />
  </div>;
}
