import {
  INotification,
  INotificationDoc,
  NewCreatedNotification,
  NotificationAppRedirect,
  UpdateNotificationBody,
} from './notification.interface';
import { Notification } from './notification.model';
import responseCodes from '@/shared/utils/responseCode/responseCode';
import { ApiError } from '@/shared/utils/errors';
import { defaultStatus } from '@/shared/utils/responseCode/httpStatusAlias';
import { FilterQuery } from 'mongoose';
import { PaginateOptions } from '@/shared/utils/plugins/paginate/paginate';
import { getObjectId } from '@/shared/utils/commonHelper';
import { sendNotificationToUsers } from './sendNotificationToUsers';
import { UserType } from './notification.constant';

const { NotificationResponseCodes } = responseCodes;

export const createNotification = async (
  payload: NewCreatedNotification & { notificationType?: string },
  appRedirect?: NotificationAppRedirect,
): Promise<boolean> => {
  const { notificationType, ...data } = payload;
  const notification = await Notification.create(data);

  if (!notification)
    throw new ApiError(
      defaultStatus.OK,
      'Failed to create notification',
      true,
      '',
      NotificationResponseCodes.NOTIFICATION_ERROR,
    );

  if (payload.status === 'send')
    await sendNotificationToUsers(payload, appRedirect);

  return true;
};

export const getNotificationById = async (
  id: string,
): Promise<INotificationDoc | null> => {
  const notification = await Notification.findById(id);

  if (!notification)
    throw new ApiError(
      defaultStatus.OK,
      'Notification not found',
      true,
      '',
      NotificationResponseCodes.NOTIFICATION_NOT_FOUND,
    );

  return notification;
};

export const updateNotification = async (
  id: string,
  updateData: UpdateNotificationBody,
): Promise<void> => {
  const result = await Notification.updateOne(
    { _id: getObjectId(id) },
    { $set: updateData },
  );

  if (result.matchedCount === 0)
    throw new ApiError(
      defaultStatus.OK,
      'Notification not found',
      false,
      '',
      NotificationResponseCodes.NOTIFICATION_NOT_FOUND,
    );

  if (updateData.status === 'send') await sendNotificationToUsers(updateData);
};

export const queryNotifications = async (
  rawFilter: Record<string, unknown>,
  options: PaginateOptions,
) => {
  const { search, ...rest } = rawFilter;

  const filter: FilterQuery<INotification> = {
    ...rest,
    userType: {
      $ne: UserType.SELF,
    },
  };

  if (typeof search === 'string' && search.trim() !== '')
    filter.$or = [
      { title: { $regex: search, $options: 'i' } },
      { description: { $regex: search, $options: 'i' } },
    ];

  console.log('🚀 ~ queryNotifications ~ filter:', filter);
  return Notification.paginate(filter, options);
};
export const deleteNotification = async (id: string): Promise<void> => {
  const result = await Notification.findByIdAndDelete(getObjectId(id));

  if (!result)
    throw new ApiError(
      defaultStatus.NOT_FOUND,
      'Notification not found',
      false,
      '',
      NotificationResponseCodes.NOTIFICATION_NOT_FOUND,
    );
};
