const Rpaf = require("../models/Rpaf");
const errorHandler = require("../util/errorHandler");
const { formatDate } = require("../util/date");
const emailBuilder = require("../helpers/transporter");
const { buildCreditApplicationAcknowledgement } = require("../helpers/email-templates/html-bodys");
const fs = require("fs");
const whispir = require("../helpers/whispir");
const OtpCode = require("../models/OtpCode");
const { Op } = require("sequelize");
const { generateSecureRandomSixDigit } = require("../helpers/common");
const { getCurrentDateTimeInGMT8 } = require("../helpers/common");

exports.sendOtp = async (req, res, next) => {
  const { mobileNumber } = req.body;
  const { customerId } = req;

  const oneMinuteAgo = new Date(Date.now() - 60000);

  OtpCode.findOne({
    where: {
      user_id: customerId,
      createdAt: {
        [Op.gt]: oneMinuteAgo,
      },
    },
    order: [["createdAt", "DESC"]],
  })
    .then((response) => {
      if (response) {
        const timeDifference = Date.now() - response.createdAt.getTime();
        const secondsRemaining = Math.ceil((60000 - timeDifference) / 1000);
        throw new Error(`Too many request! Please wait ${secondsRemaining} seconds.`);
      } else {
        const referenceNo = generateSecureRandomSixDigit();
        const otpCode = generateSecureRandomSixDigit();
        return OtpCode.create({
          otp_code: otpCode,
          mobile_number: mobileNumber,
          type: "OTP",
          description: "BuildCredit Application OTP",
          reference_no: referenceNo,
          user_id: customerId,
        });
      }
    })
    .then(async (createdRecord) => {
      const whispirReqBody = {
        recipientNumber: createdRecord.mobile_number,
        otp: createdRecord.otp_code,
        otp_reference_no: createdRecord.reference_no,
      };

      const whispirResponse = await whispir.messaging.singleMessage(whispirReqBody, "otp-sender");
      res.status(200).json({
        success: true,
        msg: "OTP has been sent successfully.",
        reference_no: createdRecord.referenceNo,
      });
    })
    .catch((err) => {
      next(err);
    });
};

exports.verifyOtp = (req, res, next) => {
  const { otp } = req.body;
  const { customerId } = req;

  let _otpRecord;
  OtpCode.findOne({
    where: {
      user_id: customerId,
      otp_code: otp,
      used: false,
      createdAt: {
        [Op.gt]: new Date(new Date() - 5 * 60 * 1000),
      },
    },
  })
    .then((otpRecord) => {
      if (!otpRecord) throw new Error("Invalid OTP Code");

      otpRecord.used = true;
      _otpRecord = otpRecord;
      return otpRecord.save();
    })
    .then(() => {
      res.status(200).json({ success: true, otp: _otpRecord });
    })
    .catch((err) => {
      next(err);
    });
};

exports.createBuildCreditApplicationFirst = async (req, res, next) => {
  const { customerId } = req.params;
  const {
    status,
    creditLimit,
    creditTerms,
    companyName,
    contactPerson,
    companyEmail,
    phoneNo,
    altPhoneNo,
    landline,
    area,
    address,
    city,
    barangay,
    address_line_1,
    address_line_2,
    additionalInfo,
    owner_name = "",
    owner_mobile_number = "",
  } = req.body;

  try {
    const verifiedPhone = await OtpCode.findOne({
      where: {
        mobile_number: phoneNo,
        user_id: customerId,
        used: true,
      },
      limit: 1,
    });

    const currentDateTime = await getCurrentDateTimeInGMT8();

    // if (!verifiedPhone) throw new Error("Phone number not verified!");
    Rpaf.findOne({
      where: {
        customer_id: customerId,
      },
    })
      .then((credit) => {
        if (credit) {
          return errorHandler("Rpaf Credit Application already exists!", 401);
        }

        return Rpaf.create({
          customer_id: customerId,
          status: status,
          credit_limit: creditLimit,
          credit_date_limit: creditTerms,
          company_name: companyName,
          contact_person: contactPerson,
          company_email: companyEmail,
          phone: phoneNo,
          addtl_phone: altPhoneNo,
          landline: landline,
          area: area,
          address: address,
          city,
          barangay,
          address_line_1,
          address_line_2,
          addi_information: additionalInfo,
          date_drafted: currentDateTime,
          owner_name: owner_name,
          owner_mobile_number: owner_mobile_number,
        });
      })
      .then(() => {
        res.status(201).json({ success: true });
      })
      .catch((err) => {
        next(err);
      });
  } catch (err) {
    next(err);
  }
};

exports.BuildCreditApplicationSecond = (req, res, next) => {
  const { customerId } = req.params;
  const { data } = req.body;
  const {
    bankName,
    bankBranchName,
    bankAccountName,
    bankAccountNo,
    bankManagerName,
    bankManagerPhone,
    bankEmail,
    companyNameTR,
    addressTR,
    companyPhone,
    dateAccountOpenedTR = null,
    customerPhone,
  } = data;

  const {
    storeFile,
    birFile,
    businessPermitFile,
    dtiSecRegistrationFile,
    bankStatementPassbookFile,
    bankAuthorizationFile,
    otherFile,
    creditApprovalFile,
    govIdFile,
    tinFile,
  } = req.files;


  // March 12, 2025
  // if (!req.files || !req.files.storeFile) {
  //   return errorHandler("Store/Hardware is missing from the request.", 500);
  // }
  // if (!req.files || !req.files.birFile) {
  //   return errorHandler("BIR Form/Certificate of Registration is missing from the request.", 500);
  // }
  // if (!req.files || !req.files.businessPermitFile) {
  //   return errorHandler("Business Permit is missing from the request.", 500);
  // }
  // if (!req.files || !req.files.govIdFile) {
  //   return errorHandler("Government Id is missing from the request.", 500);
  // }
  // if (!req.files || !req.files.dtiSecRegistrationFile) {
  //   return errorHandler("DTI/SEC Registration is missing from the request.", 500);
  // }



  // if (!req.files || !req.files.bankStatementPassbookFile) {
  //     return errorHandler("Bank Statement/Passbook is missing from the request.", 500);
  // }
  // if (!req.files || !req.files.bankAuthorizationFile) {
  //     return errorHandler("Bank Authorization Letter is missing from the request.", 500);
  // }
  // if (!req.files || !req.files.otherFile) {
  //     return errorHandler("Other Relevant Documents is missing from the request.", 500);
  // }
  // if (!req.files || !req.files.creditApprovalFile) {
  //     return errorHandler("Credit Approval Form is missing from the request.", 500);
  // }
  // if (!req.files || !req.files.tinFile) {
  //     return errorHandler("TIN ID is missing from the request.", 500);
  // }

  Rpaf.findOne({
    where: {
      customer_id: customerId,
    },
  })
    .then((credit) => {
      if (!credit) {
        return errorHandler("Rpaf Credit Application does not exists!", 401);
      }

      if (credit.status !== "Draft") {
        return errorHandler("Credit application cannot be edited.");
      }

      credit.storeFileName = storeFile && storeFile.length > 0 ? storeFile[0].filename : null;
      credit.birFile = birFile && birFile.length > 0 ? birFile[0].filename : null;
      credit.mayorFileName =
        businessPermitFile && businessPermitFile.length > 0 ? businessPermitFile[0].filename : null;
      credit.dtiFileName =
        dtiSecRegistrationFile && dtiSecRegistrationFile.length > 0 ? dtiSecRegistrationFile[0].filename : null;
      credit.bankFileName =
        bankStatementPassbookFile && bankStatementPassbookFile.length > 0
          ? bankStatementPassbookFile[0].filename
          : null;
      credit.bankAuthorizationFile =
        bankAuthorizationFile && bankAuthorizationFile.length > 0 ? bankAuthorizationFile[0].filename : null;
      credit.otherFileName = otherFile && otherFile.length > 0 ? otherFile[0].filename : null;
      credit.approvalFileName =
        creditApprovalFile && creditApprovalFile.length > 0 ? creditApprovalFile[0].filename : null;
      credit.govFileName = govIdFile && govIdFile.length > 0 ? govIdFile[0].filename : null;
      credit.tinFileName = tinFile && tinFile.length > 0 ? tinFile[0].filename : null;

      (credit.bankName = bankName),
        (credit.bankBranchName = bankBranchName),
        (credit.bankAccountName = bankAccountName),
        (credit.bankAccNum = bankAccountNo),
        (credit.bankManagerName = bankManagerName),
        (credit.bankManagerPhone = bankManagerPhone),
        (credit.bankEmail = bankEmail),
        (credit.company__name = companyNameTR),
        (credit.address2 = addressTR),
        (credit.phone2 = companyPhone),
        (credit.account_opened = dateAccountOpenedTR ? formatDate(dateAccountOpenedTR) : null),
        (credit.phone3 = customerPhone);

      return credit.save();
    })
    .then(() => {
      res.status(200).json({ success: true });
    })
    .catch((err) => {
      next(err);
    });
};

exports.BuildCreditApplicationThird = async (req, res, next) => {
  const { customerId } = req.params;
  const { data } = req.body;
  const { agentEmail, agentCode } = data;

  const { applicantSignature } = req.files;

  if (!req.files || !req.files.applicantSignature) {
    return errorHandler("Signature is missing from the request.", 500);
  }

  try {
    const currentDateTime = await getCurrentDateTimeInGMT8();

    Rpaf.findOne({
      where: {
        customer_id: customerId,
      },
    })
      .then((credit) => {
        if (!credit) {
          return errorHandler("Customer ID does not exists!", 401);
        }

        if (credit.status !== "Draft") {
          return errorHandler("Credit application cannot be edited.");
        }

        signature_applicant =
          applicantSignature && applicantSignature.length > 0 ? applicantSignature[0].filename : null;

        credit.applicant_signature = signature_applicant;

        credit.agent_email = agentEmail;
        credit.agent_code = agentCode;
        credit.date_drafted = currentDateTime;

        return credit.save();
      })
      .then(() => {
        res.status(200).json({
          success: true,
          signature_filename: signature_applicant,
        });
      })
      .catch((err) => {
        next(err);
      });
  } catch (err) {
    next(err);
  }
};

exports.updateBuildCreditApplication = async (req, res, next) => {
  const { customerId } = req.params;
  const {
    status,
    creditLimit,
    creditTerms,
    companyName,
    contactPerson,
    companyEmail,
    phoneNo,
    altPhoneNo,
    landline,
    area,
    address,
    city,
    barangay,
    address_line_1,
    address_line_2,
    additionalInfo,
    owner_name = "",
    owner_mobile_number = "",
  } = req.body;

  let buildCreditRecords;
  try {
    const currentDateTime = await getCurrentDateTimeInGMT8();

    Rpaf.findOne({
      where: {
        customer_id: customerId,
      },
    })
      .then((credit) => {
        if (!credit) {
          return errorHandler("Customer ID does not exists!", 401);
        }

        buildCreditRecords = credit;

        if (credit.status !== "Draft") {
          return errorHandler("Credit application cannot be edited.");
        }

        (credit.status = status),
          (credit.date_submitted = status === "Pending" ? currentDateTime : null),
          (credit.date_drafted = currentDateTime),
          (credit.credit_limit = creditLimit),
          (credit.credit_date_limit = creditTerms),
          (credit.company_name = companyName),
          (credit.contact_person = contactPerson),
          (credit.company_email = companyEmail),
          (credit.phone = phoneNo),
          (credit.addtl_phone = altPhoneNo),
          (credit.landline = landline),
          (credit.area = area),
          (credit.address = address),
          (credit.city = city),
          (credit.barangay = barangay),
          (credit.address_line_1 = address_line_1),
          (credit.address_line_2 = address_line_2),
          (credit.addi_info = additionalInfo);

        if (owner_name !== "" && owner_name !== null) {
          credit.owner_name = owner_name;
        }

        if (owner_mobile_number !== "" && owner_mobile_number !== null) {
          credit.owner_mobile_number = owner_mobile_number;
        }

        return credit.save();
      })
      .then(async () => {
        let emailResponse;
        if (status === "Pending") {
          const receivers = [buildCreditRecords.company_email];
          emailResponse = await emailBuilder(
            receivers,
            [],
            "Buildhub - Buildcredit Application",
            true,
            await buildCreditApplicationAcknowledgement(buildCreditRecords.contact_person),
            []
          );
        }

        res.status(200).json({ success: true, email_details: emailResponse });
      })
      .catch((err) => {
        next(err);
      });
  } catch (err) {
    next(err);
  }
};

exports.deleteBuildCreditApplication = (req, res, next) => {
  const { creditAppId } = req.params;

  Rpaf.findOne({
    where: {
      id: creditAppId,
    },
  })
    .then((credit) => {
      if (!credit) {
        return errorHandler("Rpaf Credit Application does not exists!", 401);
      }
      return credit.destroy();
    })
    .then(() => {
      res.status(204).send();
    })
    .catch((err) => {
      next(err);
    });
};

exports.findBuildCreditApplication = (req, res, next) => {
  const { customerId } = req.params;

  Rpaf.findOne({
    where: {
      customer_id: customerId,
    },
  })
    .then((credit) => {
      if (!credit) {
        return res.status(404).json({ success: false, message: "Credit application not found." });
      }

      const creditApplication = {
        id: credit.id,
        customerId: credit.customer_id,
        status: credit.status,
        creditLimit: credit.credit_limit,
        companyName: credit.company_name,
        contactPerson: credit.contact_person,
        companyEmail: credit.company_email,
        phoneNo: credit.phone,
        altPhoneNo: credit.addtl_phone,
        landline: credit.landline,
        area: credit.area,
        address: credit.address,
        city: credit.city,
        barangay: credit.barangay,
        address_line_1: credit.address_line_1,
        address_line_2: credit.address_line_2,
        additionalInfo: credit.addi_info,

        bankName: credit.bankName,
        bankBranchName: credit.bankBranchName,
        bankAccountName: credit.bankAccountName,
        bankAccountNo: credit.bankAccNum,
        bankManagerName: credit.bankManagerName,
        bankManagerPhone: credit.bankManagerPhone,
        bankEmail: credit.bankEmail,
        companyNameTR: credit.company__name,
        contactNameTR: credit.contact__name,
        addressTR: credit.address2,
        companyPhone: credit.phone2,
        dateAccountOpenedTR: credit.account_opened,
        creditLimitTR: credit.credit_date_limit,
        customerPhone: credit.phone3,
        storeFile: credit.storeFileName,
        birFile: credit.birFile,
        businessPermitFile: credit.mayorFileName,
        dtiSecRegistrationFile: credit.dtiFileName,
        bankStatementPassbookFile: credit.bankFileName,
        bankAuthorizationFile: credit.bankAuthorizationFile,
        otherFile: credit.otherFileName,
        creditApprovalFile: credit.approvalFileName,
        govIdFile: credit.govFileName,
        tinFile: credit.tinFileName,

        agentEmail: credit.agent_email,
        agentCode: credit.agent_code,

        owner_name: credit.owner_name,
        owner_mobile_number: credit.owner_mobile_number,
      };

      res.status(200).json({ success: true, creditApplication });
    })
    .catch((err) => {
      next(err);
    });
};

exports.findAllBuildCreditApplication = (req, res, next) => {
  Rpaf.findAll()
    .then((credit) => {
      const creditApplication = credit.map((credit) => ({
        id: credit.id,
        customerId: credit.customer_id,
        status: credit.status,
        creditLimit: credit.credit_limit,
        companyName: credit.company_name,
        contactPerson: credit.contact_person,
        companyEmail: credit.company_email,
        phoneNo: credit.phone,
        altPhoneNo: credit.addtl_phone,
        landline: credit.landline,
        area: credit.area,
        address: credit.address,
        city: credit.city,
        barangay: credit.barangay,
        address_line_1: credit.address_line_1,
        address_line_2: credit.address_line_2,
        additionalInfo: credit.addi_info,

        bankName: credit.bankName,
        bankBranchName: credit.bankBranchName,
        bankAccountName: credit.bankAccountName,
        bankAccountNo: credit.bankAccNum,
        bankManagerName: credit.bankManagerName,
        bankManagerPhone: credit.bankManagerPhone,
        bankEmail: credit.bankEmail,
        companyNameTR: credit.company__name,
        contactNameTR: credit.contact__name,
        addressTR: credit.address2,
        companyPhone: credit.phone2,
        dateAccountOpenedTR: credit.account_opened,
        creditLimitTR: credit.credit_date_limit,
        customerPhone: credit.phone3,
        storeFile: credit.storeFileName,
        birFile: credit.birFile,
        businessPermitFile: credit.mayorFileName,
        dtiSecRegistrationFile: credit.dtiFileName,
        bankStatementPassbookFile: credit.bankFileName,
        bankAuthorizationFile: credit.bankAuthorizationFile,
        otherFile: credit.otherFileName,
        creditApprovalFile: credit.approvalFileName,
        govIdFile: credit.govFileName,
        tinFile: credit.tinFileName,

        agentEmail: credit.agent_email,
        agentCode: credit.agent_code,

        owner_name: credit.owner_name,
        owner_mobile_number: credit.owner_mobile_number,
      }));
      res.status(200).json({ success: true, creditApplication });
    })
    .catch((err) => {
      next(err);
    });
};
