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

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

function unwrapList(raw: unknown): CompanyRecord[] {
  if (isPaginatedResponse(raw, isCompanyRecord)) {
    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(isCompanyRecord)) {
      return data;
    }
  }
  return [];
}

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

export async function listCompanies(search?: string): Promise<CompanyRecord[]> {
  const query = search ? `?search=${encodeURIComponent(search)}` : '';
  const raw: unknown = await api.get(`${API_ENDPOINTS.COMPANIES.LIST}${query}`);
  return unwrapList(raw);
}

export async function createCompany(payload: {
  name: string;
  code: string;
  email_domain?: string;
  is_active?: boolean;
}): Promise<CompanyRecord> {
  const raw: unknown = await api.post(API_ENDPOINTS.COMPANIES.CREATE, payload);
  return unwrapOne(raw);
}

export async function updateCompany(
  id: string,
  payload: Partial<CompanyRecord>,
): Promise<CompanyRecord> {
  const raw: unknown = await api.patch(API_ENDPOINTS.COMPANIES.UPDATE(id), payload);
  return unwrapOne(raw);
}

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