import { API_ENDPOINTS } from '@/shared/constants/apiEndpoints';
import { api } from '@/shared/utils/api';
import { isPaginatedResponse } from '@/shared/types/pagination.types';
import type { DepartmentRecord } from '@/features/admin/types/admin.types';

function isDepartmentRecord(value: unknown): value is DepartmentRecord {
  if (typeof value !== 'object' || value === null) {
    return false;
  }
  const d = value as Record<string, unknown>;
  return typeof d.id === 'string' && typeof d.name === 'string' && typeof d.code === 'string';
}

function unwrapList(raw: unknown): DepartmentRecord[] {
  if (isPaginatedResponse(raw, isDepartmentRecord)) {
    return raw.data;
  }
  if (typeof raw === 'object' && raw !== null && 'data' in raw) {
    const data = (raw as { data: unknown }).data;
    if (Array.isArray(data) && data.every(isDepartmentRecord)) {
      return data;
    }
  }
  if (Array.isArray(raw) && raw.every(isDepartmentRecord)) {
    return raw;
  }
  return [];
}

function unwrapOne(raw: unknown): DepartmentRecord {
  if (isDepartmentRecord(raw)) {
    return raw;
  }
  if (typeof raw === 'object' && raw !== null && 'data' in raw) {
    const data = (raw as { data: unknown }).data;
    if (isDepartmentRecord(data)) {
      return data;
    }
  }
  throw new Error('Invalid department response');
}

export async function listDepartments(params?: {
  company_id?: string;
  search?: string;
}): Promise<DepartmentRecord[]> {
  const query = new URLSearchParams();
  if (params?.company_id) {
    query.set('company_id', params.company_id);
  }
  if (params?.search) {
    query.set('search', params.search);
  }
  const suffix = query.toString() ? `?${query.toString()}` : '';
  const raw: unknown = await api.get(`${API_ENDPOINTS.DEPARTMENTS_ADMIN.LIST}${suffix}`);
  return unwrapList(raw);
}

export type DepartmentAdminPayload = {
  company_id?: string;
  name?: string;
  code?: string;
  slug?: string;
  description?: string | null;
  is_active?: boolean;
  portal_enabled?: boolean;
  portal_description_en?: string | null;
  portal_description_ar?: string | null;
  portal_requires_membership?: boolean;
  portal_theme?: Record<string, unknown> | null;
};

export async function createDepartment(payload: {
  company_id: string;
  name: string;
  code: string;
} & DepartmentAdminPayload): Promise<DepartmentRecord> {
  const raw: unknown = await api.post(API_ENDPOINTS.DEPARTMENTS_ADMIN.CREATE, payload);
  return unwrapOne(raw);
}

export async function updateDepartment(
  id: string,
  payload: DepartmentAdminPayload,
): Promise<DepartmentRecord> {
  const raw: unknown = await api.patch(API_ENDPOINTS.DEPARTMENTS_ADMIN.UPDATE(id), payload);
  return unwrapOne(raw);
}

export async function getDepartment(id: string): Promise<DepartmentRecord> {
  const raw: unknown = await api.get(API_ENDPOINTS.DEPARTMENTS_ADMIN.SHOW(id));
  return unwrapOne(raw);
}

export type DepartmentPortalSettingsPayload = {
  portal_enabled?: boolean;
  portal_description_en?: string | null;
  portal_description_ar?: string | null;
  portal_requires_membership?: boolean;
  portal_theme?: Record<string, unknown> | null;
  slug?: string;
};

export async function updateDepartmentPortalSettings(
  id: string,
  payload: DepartmentPortalSettingsPayload,
): Promise<DepartmentRecord> {
  const raw: unknown = await api.patch(API_ENDPOINTS.DEPARTMENTS_ADMIN.PORTAL_SETTINGS(id), payload);
  return unwrapOne(raw);
}

export async function deleteDepartment(id: string): Promise<void> {
  await api.delete(API_ENDPOINTS.DEPARTMENTS_ADMIN.DELETE(id));
}

export type DepartmentHeadRecord = {
  id: string;
  department_id: string;
  user_id: string;
  is_department_head: boolean;
  user?: { id: string; name: string; email: string };
};

function unwrapHeadList(raw: unknown): DepartmentHeadRecord[] {
  if (typeof raw === 'object' && raw !== null && 'data' in raw) {
    const data = (raw as { data: unknown }).data;
    if (Array.isArray(data)) {
      return data as DepartmentHeadRecord[];
    }
  }
  if (Array.isArray(raw)) {
    return raw as DepartmentHeadRecord[];
  }
  return [];
}

export async function listDepartmentHeads(departmentId: string): Promise<DepartmentHeadRecord[]> {
  const raw: unknown = await api.get(API_ENDPOINTS.DEPARTMENTS_ADMIN.HEADS(departmentId));
  return unwrapHeadList(raw);
}
