export const SECTIONS = ['dashboard', 'orders', 'reservations', 'menu', 'customers', 'conversations', 'staff', 'analytics', 'settings'] as const;
export type Section = typeof SECTIONS[number];

export interface CrudPerms {
  create: boolean;
  read: boolean;
  update: boolean;
  delete: boolean;
}

export type PermissionsMap = Record<Section, CrudPerms>;

export interface Role {
  id: string;
  restaurantId: string;
  name: string;
  description: string | null;
  permissions: PermissionsMap;
  isSystem: boolean;
  createdAt: string;
  updatedAt: string;
}

function normalizeRole(row: Record<string, unknown>): Role {
  return {
    id: row.id as string,
    restaurantId: row.restaurant_id as string,
    name: row.name as string,
    description: (row.description as string) ?? null,
    permissions: (row.permissions as PermissionsMap) ?? {},
    isSystem: Boolean(row.is_system),
    createdAt: row.created_at as string,
    updatedAt: row.updated_at as string,
  };
}

async function apiFetch<T>(url: string, options?: RequestInit): Promise<T> {
  const res = await fetch(url, { credentials: 'include', ...options });
  const json = (await res.json().catch(() => ({}))) as Record<string, unknown>;
  if (!res.ok) throw new Error((json.error as string) || `Request failed: ${res.status}`);
  return json as T;
}

export async function listRoles(): Promise<Role[]> {
  const data = await apiFetch<{ roles: Record<string, unknown>[] }>('/api/roles');
  return (data.roles ?? []).map(normalizeRole);
}

export async function getRole(id: string): Promise<Role> {
  const data = await apiFetch<{ role: Record<string, unknown> }>(`/api/roles/${id}`);
  return normalizeRole(data.role);
}

export async function createRole(body: { name: string; description?: string; permissions: PermissionsMap }): Promise<Role> {
  const data = await apiFetch<{ role: Record<string, unknown> }>('/api/roles', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
  return normalizeRole(data.role);
}

export async function updateRole(id: string, body: { name?: string; description?: string; permissions?: PermissionsMap }): Promise<Role> {
  const data = await apiFetch<{ role: Record<string, unknown> }>(`/api/roles/${id}`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
  return normalizeRole(data.role);
}

export async function deleteRole(id: string): Promise<void> {
  await apiFetch<{ success: boolean }>(`/api/roles/${id}`, { method: 'DELETE' });
}

export function defaultPermissionsMap(all = false): PermissionsMap {
  return Object.fromEntries(
    SECTIONS.map(s => [s, { create: all, read: all, update: all, delete: all }])
  ) as PermissionsMap;
}

const SECTION_ABBR: Record<string, string> = {
  dashboard: 'Dash',
  orders: 'Orders',
  reservations: 'Rsvn',
  menu: 'Menu',
  customers: 'Cust',
  conversations: 'Conv',
  staff: 'Staff',
  analytics: 'Anlyt',
  settings: 'Sett',
};

export function permsSummary(permissions: PermissionsMap): string {
  const active = Object.entries(permissions)
    .filter(([, p]) => p.read || p.create || p.update || p.delete)
    .map(([section, p]) => {
      const letters = [p.create && 'C', p.read && 'R', p.update && 'U', p.delete && 'D'].filter(Boolean).join('');
      return `${SECTION_ABBR[section] ?? section}: ${letters}`;
    });
  return active.slice(0, 4).join(' · ') + (active.length > 4 ? ` +${active.length - 4}` : '');
}

export function permissionsMatchRole(staffPerms: PermissionsMap, rolePerms: PermissionsMap): boolean {
  for (const section of SECTIONS) {
    const sp = staffPerms[section];
    const rp = rolePerms[section];
    if (!sp || !rp) return false;
    if (sp.create !== rp.create || sp.read !== rp.read || sp.update !== rp.update || sp.delete !== rp.delete) return false;
  }
  return true;
}
