import { Response } from "express";
import CONSTANTS from "../config/constants";
import log from "../config/log";
import clientDB from "../models/client.model";
import notificationDB from "../models/notification.model";
import tenantDB from "../models/tenant.model";
import CustomRequest from "../types/requestType";
import staffDB from "../models/staff.model";
import notificationPrefDB from "../models/notificationPref.model";
import { isUserPartner } from "../utils/isUserPartner";

const notification: any = {};

notification.ListForClient = async (req: CustomRequest, res: Response) => {
  const C = "Notification Controller";
  const F = "ListForClient";

  try {
    let { pageNum } = req.query;
    const userType = req.userType;

    if (!pageNum) pageNum = "1";
    let limit = 10;
    let notifications: any = [];

    let {isPartner, clientId} = await isUserPartner (Number(userType), Number(req.id));

    if (userType === CONSTANTS.USER_TYPE.CLIENT || isPartner) {
      // const clientId = req.id;
      const client = await clientDB.getById({ id: clientId });

      if (!client) {
        log.info(
          `[${C}], [${F}], Client Id [${clientId}], Page Num [${pageNum}], No Client Found`
        );
        return res
          .status(400)
          .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
      }

      log.info(
        `[${C}], [${F}], ${isPartner ? `Partner Id [${req.id}]` : `Client Id [${clientId}]`}, Page Num [${pageNum}], ${isPartner ? "Partner Requesting" : "Client Requesting"}...`
      );

      notifications = await notificationDB.getByUserId({
        userId: clientId,
        userType: CONSTANTS.USER_TYPE.CLIENT,
        pageNum,
        limit,
      });

      notificationDB.updateStatus({
        userId: clientId,
        userType: CONSTANTS.USER_TYPE.CLIENT,
        status: CONSTANTS.NOTIFICATION_STATUS.READ,
        statusToUpdate: CONSTANTS.NOTIFICATION_STATUS.PENDING,
      });

      log.info(
        `[${C}], [${F}], Client Id [${clientId}], Page Num [${pageNum}], Notifications has been sent successfully `
      );
    } else {
      const staffId = req.id;
      const staff = await staffDB.getById({ id: staffId });
      if (!staff) {
        log.info(
          `[${C}], [${F}], Page Num [${pageNum}], Staff Id [${staffId}], No Staff Found`
        );
        return res
          .status(400)
          .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
      }

      log.info(
        `[${C}], [${F}], Staff Id [${staffId}], Page Num [${pageNum}], Staff Requesting....`
      );

      notifications = await notificationDB.getByUserId({
        userId: staffId,
        userType: CONSTANTS.USER_TYPE.STAFF,
        pageNum,
        limit,
      });

      notificationDB.updateStatus({
        userId: staffId,
        userType: CONSTANTS.USER_TYPE.STAFF,
        status: CONSTANTS.NOTIFICATION_STATUS.READ,
        statusToUpdate: CONSTANTS.NOTIFICATION_STATUS.PENDING,
      });

      log.info(
        `[${C}], [${F}], Staff Id [${staffId}], Page Num [${pageNum}], Notifications has been sent successfully `
      );
    }

    return res.status(200).json({
      msg: "Notifications has been sent successfully",
      data: notifications || [],
      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,
    });
  }
};

notification.ListForTenant = async (req: CustomRequest, res: Response) => {
  const C = "Notification Controller";
  const F = "ListForTenant";

  try {
    const tenantId = req.id;
    let { pageNum } = req.query;
    if (!pageNum) pageNum = "1";

    log.info(`[${C}], [${F}], Tenant Id [${tenantId}], Page Num [${pageNum}]`);

    const tenant = await tenantDB.getById({ id: tenantId });

    if (!tenant) {
      log.info(
        `[${C}], [${F}], Tenant Id [${tenantId}], Page Num [${pageNum}], No Tenant Found`
      );
      return res
        .status(400)
        .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
    }

    let limit = 10;

    const notifications = await notificationDB.getByUserId({
      userId: tenantId,
      userType: CONSTANTS.USER_TYPE.TENANT,
      pageNum,
      limit,
    });

    await notificationDB.updateStatus({
      userId: tenantId,
      userType: CONSTANTS.USER_TYPE.TENANT,
      status: CONSTANTS.NOTIFICATION_STATUS.READ,
      statusToUpdate: CONSTANTS.NOTIFICATION_STATUS.PENDING,
    });

    log.info(
      `[${C}], [${F}], Tenant Id [${tenantId}], Page Num [${pageNum}], Notifications has been sent successfully `
    );

    return res.status(200).json({
      msg: "Notifications has been sent successfully",
      data: notifications || [],
      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,
    });
  }
};

notification.Settings = async (req: CustomRequest, res: Response) => {
  const C = "Notification Controller";
  const F = "Settings";

  try{
    const {
      notificationType,
      isEnabled,
    } = req.body;

    const userType = req.userType;
    let clientId = req.id;

    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      const staff = await staffDB.getById({ id: req.id });
      if (!staff) {
        log.info(
          `[${C}], [${F}], Client Id [${clientId}], Notification Type [${notificationType}], Is Enabled [${isEnabled}], Staff Id [${req.id}], No Staff Found`
        );
        return res
          .status(400)
          .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
      }

      clientId = staff?.clientId;

      log.info(
        `[${C}], [${F}], Client Id [${clientId}], Notification Type [${notificationType}], Is Enabled [${isEnabled}], Staff Id [${req.id}], Staff Requested.....`
      );
    } else {
      log.info(
        `[${C}], [${F}], Client Id [${clientId}], Notification Type [${notificationType}], Is Enabled [${isEnabled}], Client Requested.....`
      );
    }

    await notificationPrefDB.enableDisableNotification({
      clientId,
      notificationType,
      isEnabled,
    });

    log.info(
      `[${C}], [${F}], Client Id [${clientId}], Notification Type [${notificationType}], Is Enabled [${isEnabled}], Notification Preferences has been updated successfully`
    );

    return res.status(200).json({
      msg: "Notification Preferences has been updated 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,
    });
  }
};

notification.GetNotificationSettings = async (req: CustomRequest, res: Response) => {
  const C = "Notification Controller";
  const F = "GetNotificationSettings";

  try{

    const userType = req.userType;
    let clientId = req.id;

    if (userType === CONSTANTS.USER_TYPE.STAFF) {
      const staff = await staffDB.getById({ id: req.id });
      if (!staff) {
        log.info(
          `[${C}], [${F}], Client Id [${clientId}], Staff Id [${req.id}], No Staff Found`
        );
        return res
          .status(400)
          .json({ msg: CONSTANTS.MSG.INVALID_REQUEST, isSuccess: false });
      }

      clientId = staff?.clientId;

      log.info(
        `[${C}], [${F}], Client Id [${clientId}], Staff Id [${req.id}], Staff Requested.....`
      );
    } else {
      log.info(
        `[${C}], [${F}], Client Id [${clientId}], Client Requested.....`
      );
    }

    const smsSettings = await notificationPrefDB.getById ({id:clientId, notificationType: CONSTANTS.NOTIFICATION_TYPE.SMS});
    const whatsAppSettings = await notificationPrefDB.getById ({id:clientId, notificationType: CONSTANTS.NOTIFICATION_TYPE.WHATSAPP});

    log.info(
      `[${C}], [${F}], Client Id [${clientId}], Notification Preferences settings has been shared successfully`
    );

    let notiSettings = {
      sms: smsSettings.isEnabled || 0,
      whatsapp: whatsAppSettings.isEnabled || 0
    };

    return res.status(200).json({
      msg: "Notification Preferences settings has been shared successfully.",
      notiSettings,
      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 notification;
