import httpStatus from 'http-status';
import ApiError from '@/shared/utils/errors/ApiError.js';

import * as countryService from './country/country.service.js';
import * as stateService from './state/state.service.js';
import * as cityService from './city/city.service.js';
import * as areaService from './area/area.service.js';

const services = {
  country: countryService,
  state: stateService,
  city: cityService,
  area: areaService,
};

type LocationType = keyof typeof services;
type ServiceMethods = {
  create: (data: Record<string, unknown>) => Promise<unknown>;
  getById: (id: string) => Promise<unknown>;
  update: (id: string, data: Record<string, unknown>) => Promise<unknown>;
  remove: (id: string) => Promise<boolean>;
  list: (query: Record<string, unknown>) => Promise<unknown>;
};

const getService = (type: string): ServiceMethods => {
  const key = type.toLowerCase() as LocationType;
  const service = services[key];
  if (!service) 
    throw new ApiError(httpStatus.BAD_REQUEST, `Invalid location type: ${type}`);
  
  return service as ServiceMethods;
};

export const create = async (
  type: string,
  data: Record<string, unknown>,
): Promise<unknown> => getService(type).create(data);

export const getById = async (
  type: string,
  id: string,
): Promise<unknown> => {
  const result = await getService(type).getById(id);
  if (!result) 
    throw new ApiError(httpStatus.NOT_FOUND, `${type} not found`);
  
  return result;
};

export const update = async (
  type: string,
  id: string,
  data: Record<string, unknown>,
): Promise<unknown> => {
  const result = await getService(type).update(id, data);
  if (!result) 
    throw new ApiError(httpStatus.NOT_FOUND, `${type} not found for update`);
  
  return result;
};

export const remove = async (
  type: string,
  id: string,
): Promise<void> => {
  const success = await getService(type).remove(id);
  if (!success) 
    throw new ApiError(httpStatus.NOT_FOUND, `${type} not found for deletion`);
  
};

export const list = async (
  type: string,
  query: Record<string, unknown>,
): Promise<unknown> => getService(type).list(query);
