import { Response } from "express";
import { CustomRequest } from "../interfaces/auth";
import { STATUS_CODES } from "../constants/statusCodes";
import { NOTIFICATION_CONSTANTS } from "../constants/messages";
import ResponseUtil from "../utils/Response/responseUtils";
import {
  notificationIdParamSchema,
  notificationListSchema,
} from "../validators/notificationValidator";
import {
  listNotifications,
  markAllNotificationsRead,
  markNotificationRead,
} from "../services/notificationService";

/**
 * GET /api/v1/notifications
 */
export const getNotifications = async (req: CustomRequest, res: Response) => {
  try {
    const { page, limit } = await notificationListSchema.parseAsync(req.query);
    const result = await listNotifications(req.userId!, page, limit);
    ResponseUtil.successResponse(
      res,
      STATUS_CODES.SUCCESS,
      result,
      NOTIFICATION_CONSTANTS.LIST_FETCHED,
    );
  } catch (err) {
    ResponseUtil.handleError(res, err);
  }
};

/**
 * PATCH /api/v1/notifications/:id/read
 */
export const readNotification = async (req: CustomRequest, res: Response) => {
  try {
    const { id } = await notificationIdParamSchema.parseAsync(req.params);
    const result = await markNotificationRead(req.userId!, id);
    ResponseUtil.successResponse(
      res,
      STATUS_CODES.SUCCESS,
      result,
      NOTIFICATION_CONSTANTS.MARKED_READ,
    );
  } catch (err) {
    if (err instanceof Error && err.message === "NOT_FOUND") {
      ResponseUtil.errorResponse(
        res,
        STATUS_CODES.NOT_FOUND,
        NOTIFICATION_CONSTANTS.NOT_FOUND,
      );
      return;
    }
    ResponseUtil.handleError(res, err);
  }
};

/**
 * PATCH /api/v1/notifications/read-all
 */
export const readAllNotifications = async (
  req: CustomRequest,
  res: Response,
) => {
  try {
    const result = await markAllNotificationsRead(req.userId!);
    ResponseUtil.successResponse(
      res,
      STATUS_CODES.SUCCESS,
      result,
      NOTIFICATION_CONSTANTS.MARKED_ALL_READ,
    );
  } catch (err) {
    ResponseUtil.handleError(res, err);
  }
};
