import httpStatus from 'http-status';
import { FilterQuery } from 'mongoose';

import Amenities from './amenities.model';
import ApiError from '@/shared/utils/errors/ApiError';
import { IAmenities, IConstructionFilter } from '../constructionStatus.interfaces';
import { PaginateOptions } from '@/shared/utils/plugins/paginate/paginate';
import responseCodes from '@/shared/utils/responseCode/responseCode';
import { defaultStatus } from '@/shared/utils/responseCode/httpStatusAlias';
import { safeDeleteById } from '@/shared/utils/guard/ref-guard';

const { AmenitiesResponseCodes } = responseCodes;

export const create = async (body: IAmenities): Promise<IAmenities> => {
  const { name } = body;

  const existing = await Amenities.findOne({
    name: name,
  });

  if (existing)
    throw new ApiError(
      defaultStatus.BAD_REQUEST,
      'Amenity with this name already exists.',
      true,
      '',
      AmenitiesResponseCodes.AMENITIES_ALREADY_EXISTS,
    );

  return await Amenities.create(body);
};

export const getById = async (id: string): Promise<IAmenities> => {
  const data = await Amenities.findById(id);
  if (!data) throw new ApiError(httpStatus.NOT_FOUND, 'Amenity not found');
  return data;
};

export const update = async (
  id: string,
  body: Partial<IAmenities>,
): Promise<IAmenities> => {
  const data = await Amenities.findByIdAndUpdate(id, body, {
    new: true,
    runValidators: true,
  });
  if (!data) throw new ApiError(httpStatus.NOT_FOUND, 'Amenity not found');
  return data;
};

export const remove = async (id: string): Promise<boolean> => {
  await safeDeleteById(Amenities, id, AmenitiesResponseCodes.AMENITIES_IN_USE);
  return true;
};

export const list = (query: Record<string, unknown>): Promise<IAmenities[]> => Amenities.find(query);

export const queryAmenities = async (
  filter: IConstructionFilter = {},
  options: PaginateOptions = {},
) => {
  const { search, ...restFilter } = filter;

  const queryFilter: FilterQuery<IAmenities> = {
    ...restFilter,
  };

  if (search) 
    queryFilter.$or = [{ name: { $regex: search, $options: 'i' } }];
  

  return await Amenities.paginate(queryFilter, options);
};
