// Shared table primitives
const tableStyles = {
  // 원본 admin.html (line 86~87): th { text-align: center }, td { text-align: center, vertical-align: middle }
  headerCell: {
    padding: '11px 14px', fontSize: 12, fontWeight: 600,
    color: 'var(--ink-3)', textAlign: 'center',
    background: '#fafbfc', borderBottom: '1px solid var(--line)',
    whiteSpace: 'nowrap', userSelect: 'none',
  },
  cell: { padding: '12px 14px', fontSize: 13, color: 'var(--ink-2)', verticalAlign: 'middle', textAlign: 'center' },
  mono: { fontFamily: 'var(--mono)', fontSize: 12.5 },
  num:  { fontVariantNumeric: 'tabular-nums' },
};

const SortHeader = ({ label, col, sort, onSort, align = 'center', width }) => {
  const active = sort?.col === col;
  const dir = active ? sort.dir : null;
  return (
    <th
      onClick={() => onSort && onSort(col)}
      style={{
        ...tableStyles.headerCell,
        textAlign: align, width,
        cursor: onSort ? 'pointer' : 'default',
        color: active ? 'var(--ink)' : 'var(--ink-3)',
      }}
    >
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4,
        justifyContent: align === 'right' ? 'flex-end' : (align === 'center' ? 'center' : 'flex-start'),
        width: '100%',
      }}>
        {label}
        {onSort && (
          <span style={{
            display: 'inline-flex', flexDirection: 'column',
            fontSize: 7.5, lineHeight: 0.95,
            color: active ? 'var(--accent)' : 'var(--ink-4)',
          }}>
            <span style={{ opacity: dir === 'asc' ? 1 : 0.45 }}>▲</span>
            <span style={{ opacity: dir === 'desc' ? 1 : 0.45 }}>▼</span>
          </span>
        )}
      </span>
    </th>
  );
};

const TableShell = ({ minWidth = 960, headers, children, footer, dense }) => (
  <div style={{
    background: '#fff', border: '1px solid var(--line)', borderRadius: 12,
    overflow: 'hidden',
  }}>
    <div style={{ overflowX: 'auto' }}>
      <table style={{ width: '100%', borderCollapse: 'collapse', minWidth }}>
        <thead><tr>{headers}</tr></thead>
        <tbody>{children}</tbody>
      </table>
    </div>
    {footer}
  </div>
);

const useSort = (initialCol, initialDir = 'desc') => {
  const [sort, setSort] = React.useState({ col: initialCol, dir: initialDir });
  const onSort = (col) => {
    setSort(s => s.col === col ? { col, dir: s.dir === 'asc' ? 'desc' : 'asc' } : { col, dir: 'desc' });
  };
  return [sort, onSort];
};

const sortRows = (rows, sort, getters) => {
  if (!sort || !getters[sort.col]) return rows;
  const get = getters[sort.col];
  const sorted = [...rows].sort((a, b) => {
    const va = get(a), vb = get(b);
    if (va == null) return 1;
    if (vb == null) return -1;
    if (typeof va === 'number' && typeof vb === 'number') return va - vb;
    return String(va).localeCompare(String(vb), 'ko');
  });
  return sort.dir === 'desc' ? sorted.reverse() : sorted;
};

const Pagination = ({ total, page, pageSize, onPage, onPageSize }) => {
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
  const start = (page - 1) * pageSize + 1;
  const end = Math.min(total, page * pageSize);
  const btn = (key, disabled, active, children, onClick) => (
    <button key={key} disabled={disabled} onClick={onClick} style={{
      height: 28, minWidth: 28, padding: '0 8px', borderRadius: 6,
      border: `1px solid ${active ? 'var(--accent)' : 'var(--line-strong)'}`,
      background: active ? 'var(--accent-soft)' : '#fff',
      color: active ? 'var(--accent-ink)' : (disabled ? 'var(--ink-4)' : 'var(--ink-2)'),
      fontSize: 12, fontWeight: active ? 700 : 500,
      cursor: disabled ? 'not-allowed' : 'pointer',
      fontFamily: 'inherit', fontVariantNumeric: 'tabular-nums',
    }}>{children}</button>
  );
  const pages = [];
  const maxShown = 5;
  let from = Math.max(1, page - 2);
  let to = Math.min(totalPages, from + maxShown - 1);
  from = Math.max(1, to - maxShown + 1);
  for (let i = from; i <= to; i++) pages.push(i);
  return (
    <div style={{
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      padding: '10px 16px', borderTop: '1px solid var(--line)',
      background: '#fafbfc', fontSize: 12, color: 'var(--ink-3)', gap: 12, flexWrap: 'wrap',
    }}>
      <div>
        {total === 0 ? '데이터 없음' : <>
          <b style={{ color: 'var(--ink-2)' }}>{start}</b>–<b style={{ color: 'var(--ink-2)' }}>{end}</b>
          <span style={{ margin: '0 6px' }}>·</span>
          전체 <b style={{ color: 'var(--ink-2)' }}>{total}</b>건
        </>}
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        {onPageSize && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
            <span style={{ fontSize: 11.5, color: 'var(--ink-3)' }}>페이지당</span>
            <select value={pageSize} onChange={e => onPageSize(Number(e.target.value))} style={{
              height: 28, border: '1px solid var(--line-strong)', borderRadius: 6,
              fontSize: 12, padding: '0 6px', background: '#fff', fontFamily: 'inherit',
            }}>
              {[10, 20, 50].map(n => <option key={n} value={n}>{n}</option>)}
            </select>
          </div>
        )}
        <div style={{ display: 'flex', gap: 4 }}>
          {btn('prev', page === 1, false, <Icon name="chevronL" size={12} />, () => onPage(page - 1))}
          {from > 1 && btn('first', false, page === 1, '1', () => onPage(1))}
          {from > 2 && <span key="gap-l" style={{ alignSelf: 'center', color: 'var(--ink-4)' }}>…</span>}
          {pages.map(p => btn(`p-${p}`, false, page === p, p, () => onPage(p)))}
          {to < totalPages - 1 && <span key="gap-r" style={{ alignSelf: 'center', color: 'var(--ink-4)' }}>…</span>}
          {to < totalPages && btn('last', false, page === totalPages, totalPages, () => onPage(totalPages))}
          {btn('next', page === totalPages, false, <Icon name="chevronR" size={12} />, () => onPage(page + 1))}
        </div>
      </div>
    </div>
  );
};

// Zebra row hover
const Row = ({ children, last, onClick, style: xs = {} }) => {
  const baseBg = xs.background || '#fff';
  return (
    <tr
      onClick={onClick}
      style={{
        borderBottom: last ? 'none' : '1px solid var(--line)',
        transition: 'background 0.1s',
        cursor: onClick ? 'pointer' : 'default',
        background: baseBg,
        ...xs,
      }}
      onMouseEnter={e => e.currentTarget.style.background = '#f7f9fb'}
      onMouseLeave={e => e.currentTarget.style.background = baseBg}
    >{children}</tr>
  );
};

Object.assign(window, { tableStyles, SortHeader, TableShell, useSort, sortRows, Pagination, Row });
