import { captureCaught } from '@/lib/observability';

export type TableDensity = 'compact' | 'comfortable';

export interface AdminTablePrefs {
  hiddenKeys: string[];
  columnOrder: string[];
  density: TableDensity;
}

const PREFIX = 'md:admin-table';

function storageKey(tableId: string, suffix: string): string {
  return `${PREFIX}:${tableId}:${suffix}`;
}

export function loadTablePrefs(tableId: string): AdminTablePrefs | null {
  if (typeof window === 'undefined') return null;
  try {
    const hiddenKeys = JSON.parse(
      localStorage.getItem(storageKey(tableId, 'hidden')) ?? '[]',
    ) as string[];
    const columnOrder = JSON.parse(
      localStorage.getItem(storageKey(tableId, 'order')) ?? '[]',
    ) as string[];
    const densityRaw = localStorage.getItem(storageKey(tableId, 'density'));
    const density: TableDensity =
      densityRaw === 'compact' || densityRaw === 'comfortable' ? densityRaw : 'comfortable';
    return { hiddenKeys, columnOrder, density };
  } catch (err) {
    captureCaught(err, { scope: 'lib.admin.tablePrefs.load', severity: 'info' });
    return null;
  }
}

export function saveTablePrefs(tableId: string, partial: Partial<AdminTablePrefs>): void {
  if (typeof window === 'undefined') return;
  const current = loadTablePrefs(tableId) ?? {
    hiddenKeys: [],
    columnOrder: [],
    density: 'comfortable' as TableDensity,
  };
  const next = { ...current, ...partial };
  localStorage.setItem(storageKey(tableId, 'hidden'), JSON.stringify(next.hiddenKeys));
  localStorage.setItem(storageKey(tableId, 'order'), JSON.stringify(next.columnOrder));
  localStorage.setItem(storageKey(tableId, 'density'), next.density);
}

export function resetTablePrefs(tableId: string): void {
  if (typeof window === 'undefined') return;
  localStorage.removeItem(storageKey(tableId, 'hidden'));
  localStorage.removeItem(storageKey(tableId, 'order'));
  localStorage.removeItem(storageKey(tableId, 'density'));
}

export function mergeColumnOrder(savedOrder: string[], allKeys: string[]): string[] {
  const valid = new Set(allKeys);
  const ordered: string[] = [];
  for (const key of savedOrder) {
    if (valid.has(key) && !ordered.includes(key)) ordered.push(key);
  }
  for (const key of allKeys) {
    if (!ordered.includes(key)) ordered.push(key);
  }
  return ordered;
}

export function resolveVisibleColumns<T extends { key: string; hideable?: boolean }>(
  columns: T[],
  hiddenKeys: string[],
): T[] {
  const hidden = new Set(hiddenKeys);
  const visible = columns.filter((c) => c.hideable === false || !hidden.has(c.key));
  if (visible.length > 0) return visible;
  return columns.slice(0, 1);
}
