import { Response } from "express";
import log from "../config/log";
import CONSTANTS from "../config/constants";
import CustomRequest from "../types/requestType";
import staffDB from "../models/staff.model";
import { isUserPartner } from "../utils/isUserPartner";
import wifiCredentialsDB from "../models/wifiCredential.model";

const wifiCredentials: any = {};

wifiCredentials.Add = async (req: CustomRequest, res: Response) => {
  const C = "Wifi Credential Controller";
  const F = "Add";

  try {
    let { creds, tenantId } = req.body;

    log.info(
      `[${C}], [${F}], Credentials [${JSON.stringify(creds)}], Tenant Id [${tenantId}]`,
    );

    const userType = req.userType;

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

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

    if (creds && creds.length > 0) {
      for (let cred of creds) {
        await wifiCredentialsDB.add({
          clientId,
          tenantId,
          title: cred.title,
          device: cred.device,
          password: cred.password,
        });
      }
    }

    log.info(
      `[${C}], [${F}], Client Id [${clientId}], Credentails [${JSON.stringify(creds)}], Tenant Id [${tenantId}], Wifi Credentials Added Successfully`,
    );

    return res.status(200).json({
      msg: "Wifi credentials 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,
    });
  }
};

wifiCredentials.Edit = async (req: CustomRequest, res: Response) => {
  const C = "Wifi Credential Controller";
  const F = "Edit";

  try {
    //let { id, title, password, device } = req.body;
    let { creds, tenantId } = req.body;

    // log.info(
    //   `[${C}], [${F}], Record Id [${id}], Title [${title}], Password [${password}], Device [${device}]`,
    // );

    log.info(
      `[${C}], [${F}], Credentials [${JSON.stringify(creds)}], Tenant Id [${tenantId}]`,
    );

    const userType = req.userType;

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

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

    if (creds && creds.length > 0) {
      for (let cred of creds) {
        if(cred?.id) {
          const record = await wifiCredentialsDB.getById({
            id: cred?.id,
          });
          if (!record) {
            log.info(
              `[${C}], [${F}], Client Id [${clientId}], Record Id [${cred?.id}], No Record Found With Id`,
            );
            continue;
          }
          await wifiCredentialsDB.edit({
            id: cred?.id,
            title: cred?.title,
            password: cred?.password,
            device: cred?.device,
          });
        } else {
          await wifiCredentialsDB.add({
            clientId,
            tenantId,
            title: cred.title,
            device: cred.device,
            password: cred.password,
          });
        }
      }
    }

    log.info(
      `[${C}], [${F}], Client Id [${clientId}], Credentails [${JSON.stringify(creds)}], Tenant Id [${tenantId}], Wifi credentials updated successfully`,
    );

    return res.status(200).json({
      msg: "Wifi credentials 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,
    });
  }
};

wifiCredentials.Delete = async (req: CustomRequest, res: Response) => {
  const C = "Wifi Credential Controller";
  const F = "Delete";

  try {
    let { id } = req.body;

    log.info(
      `[${C}], [${F}], Record Id [${id}]`,
    );

    const userType = req.userType;

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

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

    const record = await wifiCredentialsDB.getById({
      id,
    });
    if (!record) {
      log.info(
        `[${C}], [${F}], Client Id [${clientId}], Record Id [${id}], No Record Found With Id`,
      );

      return res.status(400).json({
        msg: "No wifi credential exist",
        isSucess: false,
      });
    }

    await wifiCredentialsDB.delete({
      id,
    });

    log.info(
      `[${C}], [${F}], Client Id [${clientId}], Record Id [${id}], Wifi Credentials Deleted Successfully`,
    );

    return res.status(200).json({
      msg: "Wifi credential deleted",
      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,
    });
  }
};

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

  try {
    let { tenantId } = req.query;

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

    const userType = req.userType;

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

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

    const wifiCreds = await wifiCredentialsDB.getByTenantIdAndClientId({
      tenantId,
      clientId,
    });

    log.info(
      `[${C}], [${F}], Client Id [${clientId}], Tenant Id [${tenantId}], Wifi Credentials Sent Successfully`,
    );

    return res.status(200).json({
      msg: "Wifi credentials fetched",
      isSuccess: true,
      wifiCreds: wifiCreds || [],
    });
  } catch (error: any) {
    log.info(`[${C}], [${F}], Error: ${error?.message || error}`);
    return res.status(500).json({
      msg: CONSTANTS.MSG.ERROR_MESSAGE,
      isSuccess: false,
    });
  }
};

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

  try {
    const tenantId = req.id;
    const clientId = req.clientId;

    log.info(
      `[${C}], [${F}], Client Id [${clientId}], Tenant Id [${tenantId}], Tenant Requesting`,
    );

    const wifiCreds = await wifiCredentialsDB.getByTenantIdAndClientId({
      tenantId,
      clientId,
    });

    log.info(
      `[${C}], [${F}], Client Id [${clientId}], Tenant Id [${tenantId}], Wifi Credentials Sent Successfully`,
    );

    return res.status(200).json({
      msg: "Wifi credentials fetched",
      isSuccess: true,
      wifiCreds: wifiCreds || [],
    });
  } 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 wifiCredentials;
