function DataTable({ columns, rows, emptyTitle = 'Sin resultados', emptyHint = 'Ajusta los filtros o registra el primer elemento.', keyField = 'id', onRowDoubleClick }) {
  if (!rows || rows.length === 0) {
    return (
      <div className="table-empty">
        <div className="table-empty__title">{emptyTitle}</div>
        <div>{emptyHint}</div>
      </div>
    );
  }
  return (
    <div className="table-wrap">
      <table className="data-table">
        <thead>
          <tr>{columns.map((c) => <th key={c.key}>{c.header}</th>)}</tr>
        </thead>
        <tbody>
          {rows.map((row) => (
            <tr
              key={row[keyField]}
              onDoubleClick={onRowDoubleClick ? () => onRowDoubleClick(row) : undefined}
              style={onRowDoubleClick ? { cursor: 'pointer' } : undefined}
            >
              {columns.map((c) => (
                <td key={c.key} className={c.mono ? 'mono' : ''}>
                  {c.render ? c.render(row) : (row[c.key] ?? '—')}
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function Pagination({ total, limit, offset, onChange }) {
  const page = Math.floor(offset / limit) + 1;
  const totalPages = Math.max(1, Math.ceil(total / limit));
  return (
    <div className="pagination">
      <span>{total} resultado{total === 1 ? '' : 's'} · página {page} de {totalPages}</span>
      <div style={{ display: 'flex', gap: 8 }}>
        <button className="btn btn-ghost btn-sm" disabled={offset <= 0} onClick={() => onChange(Math.max(0, offset - limit))}>Anterior</button>
        <button className="btn btn-ghost btn-sm" disabled={offset + limit >= total} onClick={() => onChange(offset + limit)}>Siguiente</button>
      </div>
    </div>
  );
}
