import mongoose from "mongoose";
import asyncErrorHandler from "../Utils/asyncErrorHandler.js";
import constants from "../Utils/constants.js";
import { WebContentValidator } from "../Utils/Validator/UserValidator.js";
import CustomError from "../Utils/ResponseHandler/CustomError.js";
import WebContent from "../DB/Model/webContent.model.js";

/**
 * Fetch All Web Content
 *
 * @private
 * @param {Request} req
 * @param {Response} res
 * @param {next} next
 */
const index = asyncErrorHandler(async (req, res, next) => {
  const { type } = req.query;
  if (
    type &&
    !["privacy-policy", "terms-and-condition", "faqs", "about-us"].includes(
      type
    )
  ) {
    return next(CustomError.createError("Invalid Type", constants.BAD_REQUEST));
  }
  const query = type ? { type } : {};
  const webContent = await WebContent.findOne(query);

  return res.status(constants.OK).json({
    data: webContent,
    message: "Web Content List Fetch Successfully!",
    success: true,
  });
});

/**
 * Fetch Single Web Content
 *
 * @private
 * @param {Request} req
 * @param {Response} res
 * @param {next} next
 */
const show = asyncErrorHandler(async (req, res, next) => {
  const { id } = req.params;
  if (!mongoose.isValidObjectId(id)) {
    return next(CustomError.createError("Invalid ID", constants.BAD_REQUEST));
  }
  const webContent = await WebContent.findById(id);

  if (!webContent) {
    return res
      .status(constants.NOT_FOUND)
      .json({ message: constants.NO_RECORD_FOUND, success: false });
  }

  return res.status(constants.OK).json({
    data: webContent,
    message: "Web Content Fetch Successfully!",
    success: true,
  });
});

/**
 * Create Web Content
 *
 * @private
 * @param {Request} req
 * @param {Response} res
 * @param {next} next
 */
const store = asyncErrorHandler(async (req, res, next) => {
  const { error } = WebContentValidator.validate(req.body);
  if (error)
    return next({
      statusCode: constants.UNPROCESSABLE_ENTITY,
      message: error.details[0].message,
    });

  const findContentByType = await WebContent.findOne({ type: req.body.type });
  if (findContentByType) {
    return next(
      CustomError.badRequest("Web Content already created with this type!")
    );
  }

  const { user } = req;

  req.body.created_by = user._id;
  const newWebContent = await WebContent.create(req.body);

  return res.status(constants.CREATED).json({
    data: newWebContent,
    message: "Web Content Uploaded Successfully!",
    success: true,
  });
});

/**
 * Update Single Web Content by ID
 *
 * @private
 * @param {Request} req
 * @param {Response} res
 * @param {next} next
 */
const update = asyncErrorHandler(async (req, res, next) => {
  const { error } = WebContentValidator.validate(req.body);
  if (error)
    return next({
      statusCode: constants.UNPROCESSABLE_ENTITY,
      message: error.details[0].message,
    });
  const { content, type } = req.body;
  const { id } = req.params;
  if (!mongoose.isValidObjectId(id)) {
    return next(CustomError.createError("Invalid ID", constants.BAD_REQUEST));
  }
  const webContent = await WebContent.findById(id);
  console.log("🚀 ~ update ~ webContent:", webContent);
  if (!webContent) {
    return next(
      CustomError.createError(constants.NO_RECORD_FOUND, constants.NOT_FOUND)
    );
  }
  const updatedBody = {
    content: content ? content : webContent.content,
    type: type ? type : webContent.type,
  };
  const updateWebContent = await WebContent.updateOne(
    { _id: new mongoose.Types.ObjectId(id) },
    { $set: updatedBody },
    { new: true }
  );
  if (!updateWebContent) {
    return next(
      CustomError.createError("Failed to update Additional Service", 500)
    );
  }
  return res.status(constants.OK).json({
    data: updateWebContent,
    message: "Web Content Updated Successfully!",
    success: true,
  });
});

/**
 * Delete Web Content
 *
 * @private
 * @param {Request} req
 * @param {Response} res
 * @param {next} next
 */
const destroy = asyncErrorHandler(async (req, res, next) => {
  const { id } = req.params;

  if (!mongoose.isValidObjectId(id)) {
    return next(CustomError.createError("Invalid ID", 400));
  }
  // Proceed with updating the user
  const webContent = await WebContent.findById(id);

  if (!webContent) {
    return next(
      CustomError.createError(constants.NO_RECORD_FOUND, constants.NOT_FOUND)
    );
  }

  await WebContent.findByIdAndDelete(id);
  return res.status(constants.NO_CONTENT).json({
    message: `Web Content Deleted Successfully!`,
    success: true,
  });
});

const WebContentController = {
  index,
  show,
  store,
  update,
  destroy,
};

export default WebContentController;
