import { Response } from "express";
import { Types } from "mongoose";
import FeedbackModel from "../../models/FeedbackModel";
import ResponseUtil from "../../utils/Response/responseUtils";
import { STATUS_CODES } from "../../constants/statusCodes";
import { CustomRequest } from "../../interfaces/auth";
import {
  feedbackCreateSchema,
  feedbackStatusSchema,
} from "../../validators/adminValidators";

export const submitFeedbackPublic = async (
  req: CustomRequest,
  res: Response
) => {
  try {
    const body = await feedbackCreateSchema.parseAsync(req.body);
    const feedback = await FeedbackModel.create({
      userId: req.userId ? new Types.ObjectId(req.userId) : undefined,
      email: body.email,
      name: body.name,
      subject: body.subject,
      message: body.message,
      status: "open",
    });
    return ResponseUtil.successResponse(
      res,
      STATUS_CODES.SUCCESS,
      { id: feedback._id },
      "Feedback received"
    );
  } catch (e) {
    ResponseUtil.handleError(res, e);
  }
};

export const listFeedbackAdmin = async (req: CustomRequest, res: Response) => {
  try {
    const page = Math.max(parseInt((req.query.page as string) || "1", 10), 1);
    const limit = Math.min(
      Math.max(parseInt((req.query.limit as string) || "20", 10), 1),
      100
    );
    const skip = (page - 1) * limit;
    const status = req.query.status as string | undefined;
    const filter: Record<string, unknown> = {};
    if (status) filter.status = status;

    const [items, total] = await Promise.all([
      FeedbackModel.find(filter)
        .sort({ createdAt: -1 })
        .skip(skip)
        .limit(limit)
        .populate("userId", "email fullName")
        .lean(),
      FeedbackModel.countDocuments(filter),
    ]);

    return ResponseUtil.successResponse(
      res,
      STATUS_CODES.SUCCESS,
      {
        total,
        page,
        limit,
        totalPages: Math.ceil(total / limit),
        items,
      },
      "Feedback list"
    );
  } catch (e) {
    ResponseUtil.handleError(res, e);
  }
};

export const updateFeedbackAdmin = async (
  req: CustomRequest,
  res: Response
) => {
  try {
    const { id } = req.params;
    if (!Types.ObjectId.isValid(id)) {
      return ResponseUtil.errorResponse(
        res,
        STATUS_CODES.BAD_REQUEST,
        "Invalid id"
      );
    }
    const body = await feedbackStatusSchema.parseAsync(req.body);
    const item = await FeedbackModel.findByIdAndUpdate(
      id,
      { status: body.status, adminNotes: body.adminNotes ?? "" },
      { new: true }
    ).lean();
    if (!item) {
      return ResponseUtil.errorResponse(
        res,
        STATUS_CODES.NOT_FOUND,
        "Not found"
      );
    }
    return ResponseUtil.successResponse(
      res,
      STATUS_CODES.SUCCESS,
      { item },
      "Feedback updated"
    );
  } catch (e) {
    ResponseUtil.handleError(res, e);
  }
};
