import { API_ENDPOINTS } from '@/shared/constants/apiEndpoints';
import { api } from '@/shared/utils/api';

export interface RoleRecord {
  id: number;
  name: string;
  scope: string;
  description?: string | null;
  permissions?: { id: number; name: string; description?: string | null }[];
}

export interface PermissionRecord {
  id: number;
  name: string;
  scope: string;
  description?: string | null;
}

function unwrapArray<T>(raw: unknown, guard: (v: unknown) => v is T): T[] {
  if (Array.isArray(raw) && raw.every(guard)) {
    return raw;
  }
  if (typeof raw === 'object' && raw !== null && 'data' in raw) {
    const data = (raw as { data: unknown }).data;
    if (Array.isArray(data) && data.every(guard)) {
      return data;
    }
  }
  return [];
}

function isRoleRecord(v: unknown): v is RoleRecord {
  return typeof v === 'object' && v !== null && typeof (v as RoleRecord).name === 'string';
}

function isPermissionRecord(v: unknown): v is PermissionRecord {
  return typeof v === 'object' && v !== null && typeof (v as PermissionRecord).name === 'string';
}

export async function listRoles(): Promise<RoleRecord[]> {
  const raw: unknown = await api.get(API_ENDPOINTS.ROLES.LIST);
  return unwrapArray(raw, isRoleRecord);
}

export async function listPermissions(): Promise<PermissionRecord[]> {
  const raw: unknown = await api.get(API_ENDPOINTS.PERMISSIONS.LIST);
  return unwrapArray(raw, isPermissionRecord);
}

export async function getRole(id: number): Promise<RoleRecord> {
  const raw: unknown = await api.get(API_ENDPOINTS.ROLES.SHOW(id));
  if (isRoleRecord(raw)) {
    return raw;
  }
  if (typeof raw === 'object' && raw !== null && 'data' in raw) {
    const data = (raw as { data: unknown }).data;
    if (isRoleRecord(data)) {
      return data;
    }
  }
  throw new Error('Invalid role response');
}

export async function syncRolePermissions(roleId: number, permissions: string[]): Promise<RoleRecord> {
  const raw: unknown = await api.put(API_ENDPOINTS.ROLES.PERMISSIONS(roleId), { permissions });
  if (isRoleRecord(raw)) {
    return raw;
  }
  if (typeof raw === 'object' && raw !== null && 'data' in raw) {
    const data = (raw as { data: unknown }).data;
    if (isRoleRecord(data)) {
      return data;
    }
  }
  throw new Error('Invalid role response');
}
