import { ApiError } from '@/shared/utils/errors';
import { defaultStatus } from '@/shared/utils/responseCode/httpStatusAlias';
import responseCodes from '@/shared/utils/responseCode/responseCode';
import {
  NewCreatedPaymentTerm,
  UpdatePaymentTermBody,
} from '@/modules/project/paymentTerms/paymetTerms.interface';
import { getObjectId } from '@/shared/utils/commonHelper';
import { PaymentTerm } from './paymentTerms.model';

const { PaymentTermResponseCodes } = responseCodes;

export const createPaymentTerm = async (
  data: NewCreatedPaymentTerm,
): Promise<boolean> => {
  const paymentTerm = await PaymentTerm.create(data);

  if (!paymentTerm)
    throw new ApiError(
      defaultStatus.OK,
      'Failed to create paymentTerm',
      true,
      '',
      PaymentTermResponseCodes.PAYMENTTERM_ERROR,
    );

  return true;
};

export const getPaymentTermById = async (id: string) => {
  const paymentTerm = await PaymentTerm.findById(id);
  if (!paymentTerm)
    throw new ApiError(
      defaultStatus.OK,
      'PaymentTerm not found',
      true,
      '',
      PaymentTermResponseCodes.PAYMENTTERM_NOT_FOUND,
    );

  return paymentTerm;
};

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

    if (!result)
      throw new ApiError(
        defaultStatus.OK,
        'PaymentTerm not found',
        false,
        '',
        PaymentTermResponseCodes.PAYMENTTERM_NOT_FOUND,
      );

    return true;
  } catch (err: unknown) {
    if (err instanceof ApiError) throw err;
    throw new ApiError(
      defaultStatus.OK,
      'Failed to update paymentTerm',
      true,
      '',
      PaymentTermResponseCodes.PAYMENTTERM_ERROR,
    );
  }
};

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

    if (!deleted)
      throw new ApiError(
        defaultStatus.NOT_FOUND,
        'PaymentTerm not found',
        false,
        '',
        PaymentTermResponseCodes.PAYMENTTERM_NOT_FOUND,
      );
  } catch (err: unknown) {
    if (err instanceof ApiError) throw err;

    throw new ApiError(
      defaultStatus.INTERNAL_SERVER_ERROR,
      'Failed to delete paymentTerm',
      true,
      '',
      PaymentTermResponseCodes.PAYMENTTERM_ERROR,
    );
  }
};

export const queryPaymentTerms = async (
  filter: Record<string, string> = {},
  options = {},
) => {
  const { search, project, status, ...rest } = filter;

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

    ...(search && {
      name: { $regex: search, $options: 'i' },
    }),
    ...(project && {
      project: getObjectId(project),
    }),
    ...(status && {
      status,
    }),
  };

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