import { Response } from "express";
import CONSTANTS from "../config/constants";
import log from "../config/log";
import CustomRequest from "../types/requestType";
import feedbackDB from "../models/feedback.model";
import propertyDB from "../models/property.model";

const feedbacks: any = {};

feedbacks.GetFeedback = async (req: CustomRequest, res: Response) => {
  const C = "Feedback Controller";
  const F = "GetFeedback";
  try {
    const userType = req.userType;
    let feedbacks: any = [];
    if (userType === CONSTANTS.USER_TYPE.TENANT) {
      const tenantId = req.id;
      log.info(`[${C}], [${F}], Tenant Id [${tenantId}], Tenant Requesting...`);
      feedbacks = await feedbackDB.getByTenantId({ tenantId });
    } else {
      if (userType === CONSTANTS.USER_TYPE.CLIENT)
        log.info(`[${C}], [${F}], Client Id [${req.id}], Client not allowed`);
      else log.info(`[${C}], [${F}], Staff Id [${req.id}], Staff not allowed`);

      return res
        .status(400)
        .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
    }
    log.info(`[${C}], [${F}], Feedback Sent Successfully`);
    return res.status(200).json({
      msg: `Feedback sent successfully`,
      data: feedbacks,
      isSuccess: true,
    });
  } catch (error: any) {
    log.info(`[${C}], [${F}], Error: ${error?.message || error}`);
    return res.status(500).json({
      msg: CONSTANTS.MSG.ERROR_MESSAGE,
      isSuccess: false,
    });
  }
};

feedbacks.AddFeedback = async (req: CustomRequest, res: Response) => {
  const C = "Feedback Controller";
  const F = "AddFeedback";
  try {
    let { propId, propRemarks, propRating, staffRemarks, staffRating } =
      req.body;
    let tenantId = req.id;
    log.info(
      `[${C}], [${F}], Tenant Id [${tenantId}], Property Remarks [${propRemarks}], Property Rating [${propRating}], Staff Remarks [${staffRemarks}], Staff Rating [${staffRating}], Tenant adding feedback...`
    );
    let property = await propertyDB.getById({
      id: propId,
    });
    if (!property) {
      log.info(`[${C}], [${F}], Tenant Id [${tenantId}], No Property Found`);
      return res
        .status(400)
        .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
    }
    const clientId = property.clientId;
    const feedbackData = await feedbackDB.getByTenantId({ tenantId });
    if (feedbackData) {
      await feedbackDB.update({
        id: feedbackData.id,
        propRemarks,
        propRating,
        staffRemarks,
        staffRating,
      });
      log.info(
        `[${C}], [${F}], Tenant Id [${tenantId}], Feedback Updated Successfully`
      );
      return res.status(200).json({
        msg: "Feedback updated successfully",
        isSuccess: true,
      });
    }
    await feedbackDB.add({
      tenantId,
      clientId: property.clientId,
      propId: property.id,
      propRemarks,
      propRating,
      staffRemarks,
      staffRating,
    });
    log.info(
      `[${C}], [${F}], Tenant Id [${tenantId}], Client Id [${clientId}], Property Id [${property.id}], Feedback Added Successfully`
    );
    return res.status(200).json({
      msg: "Feedback added successfully",
      isSuccess: true,
    });
  } catch (error: any) {
    log.info(`[${C}], [${F}], Error: ${error?.message || error}`);

    return res.status(500).json({
      msg: CONSTANTS.MSG.ERROR_MESSAGE,
      isSuccess: false,
    });
  }
};

feedbacks.ListForClient = async (req: CustomRequest, res: Response) => {
  const C = "Feedback Controller";
  const F = "ListForClient";
  try {
    const { propId } = req.params;
    log.info(
      `[${C}], [${F}], Prop Id [${propId}], Property Feedback Requested...`
    );
    const feedbacks = await feedbackDB.getFeedback({
      propId,
    });
    if (!feedbacks) {
      log.info(`[${C}], [${F}], Prop Id [${propId}], No Feedback Found`);
      return res
        .status(400)
        .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
    }
    const averageRating = await feedbackDB.getAvgRatings({ propId });
    log.info(
      `[${C}], [${F}], Prop Id [${propId}], Property Feedbacks Sent Successfully`
    );
    let propertyFeedbacks = [];
    let staffFeedbacks = [];
    for (let feedback of feedbacks) {
      propertyFeedbacks.push({
        name: feedback.tenantName,
        propId: feedback.propId,
        id: feedback.id,
        number: feedback.tenantNumber,
        rating: feedback.propRating,
        comment: feedback.propRemarks,
        date: feedback.updatedAt,
      });
      staffFeedbacks.push({
        id: feedback.id,
        name: feedback.tenantName,
        propId: feedback.propId,
        number: feedback.tenantNumber,
        rating: feedback.staffRating,
        comment: feedback.staffRemarks,
        date: feedback.updatedAt,
      });
    }

    return res.status(200).json({
      msg: "Tenant feedbacks sent successfully",
      data: {
        avgPropertyRating: averageRating?.avgPropRating?.toFixed(2) || 0,
        avgStaffRating: averageRating?.avgStaffRating?.toFixed(2) || 0,
        totalReviews: feedbacks.length,
        propertyFeedbacks,
        staffFeedbacks,
      },
      isSuccess: true,
    });
  } catch (error: any) {
    log.info(`[${C}], [${F}], Error: ${error?.message || error}`);
    return res.status(500).json({
      msg: CONSTANTS.MSG.ERROR_MESSAGE,
      isSuccess: false,
    });
  }
};

export default feedbacks;
