import { ApiError } from '@/shared/utils/errors';
import { defaultStatus } from '@/shared/utils/responseCode/httpStatusAlias';
import responseCodes from '@/shared/utils/responseCode/responseCode';
import {
  NewCreatedPropertyFile,
  UpdatePropertyFileBody,
  IPropertyFileFilter,
} from './files.interface';
import { getObjectId } from '@/shared/utils/commonHelper';
import PropertyFile from './files.model';

const { PropertyFileResponseCodes } = responseCodes;

export const createPropertyFile = async (
  data: NewCreatedPropertyFile,
): Promise<boolean> => {
  const file = await PropertyFile.create(data);

  if (!file)
    throw new ApiError(
      defaultStatus.NOT_FOUND,
      'Failed to create property file',
      true,
      '',
      PropertyFileResponseCodes.PROPERTYFILE_ERROR,
    );

  return true;
};

export const getPropertyFileById = async (id: string) => {
  const file = await PropertyFile.findById(id);
  if (!file)
    throw new ApiError(
      defaultStatus.OK,
      'Property file not found',
      true,
      '',
      PropertyFileResponseCodes.PROPERTYFILE_NOT_FOUND,
    );

  return file;
};

export const updatePropertyFile = async (
  id: string,
  updateData: UpdatePropertyFileBody,
): Promise<boolean | null> => {
  try {
    const result = await PropertyFile.findByIdAndUpdate(id, updateData, {
      new: true,
    });

    if (!result)
      throw new ApiError(
        defaultStatus.OK,
        'Property file not found',
        false,
        '',
        PropertyFileResponseCodes.PROPERTYFILE_NOT_FOUND,
      );

    return true;
  } catch (err: unknown) {
    if (err instanceof ApiError) throw err;
    throw new ApiError(
      defaultStatus.OK,
      'Failed to update property file',
      true,
      '',
      PropertyFileResponseCodes.PROPERTYFILE_ERROR,
    );
  }
};

export const deletePropertyFile = async (id: string): Promise<void> => {
  try {
    const deleted = await PropertyFile.findByIdAndDelete(getObjectId(id));

    if (!deleted)
      throw new ApiError(
        defaultStatus.NOT_FOUND,
        'Property file not found',
        false,
        '',
        PropertyFileResponseCodes.PROPERTYFILE_NOT_FOUND,
      );
  } catch (err: unknown) {
    if (err instanceof ApiError) throw err;

    throw new ApiError(
      defaultStatus.INTERNAL_SERVER_ERROR,
      'Failed to delete property file',
      true,
      '',
      PropertyFileResponseCodes.PROPERTYFILE_ERROR,
    );
  }
};

export const queryPropertyFiles = async (
  filter: IPropertyFileFilter = {},
  options = {},
) => {
  const { search, propertyId, category, size, createdBy, status, ...rest } =
    filter;

  const query: Record<string, unknown> = {
    ...rest,

    ...(search && {
      $or: [
        { name: { $regex: search, $options: 'i' } },
        { category: { $regex: search, $options: 'i' } },
        { size: { $regex: search, $options: 'i' } },
      ],
    }),
    ...(propertyId && {
      propertyId: getObjectId(propertyId),
    }),
    ...(category && {
      category,
    }),
    ...(size && {
      size,
    }),
    ...(createdBy && {
      createdBy: getObjectId(createdBy),
    }),
    ...(status && {
      status,
    }),
  };

  return PropertyFile.paginate(query, options);
};
