const Sequelize = require("sequelize");
const schedule = require("node-schedule");
const OrderForms = require("../models/OrderForm");
const BuildCredit = require("../models/Rpaf");
const BuildCreditPayments = require("../models/RpafPayment");
const Customers = require("../models/Customers");
const BuildCreditAutomatedTextCustomerExclusions = require("../models/BuildcreditAutomatedTextCustomerExclusions");
const { filterAndFormatPhones, formatDateWithoutTime } = require("../helpers/common");
const { Op } = require("sequelize");
const whispir = require("../helpers/whispir");
const MessagesLogs = require("../models/MessagesLogs");
const AutomationServicesLogs = require("../models/AutomationServicesLogs");

async function sevenDaysDue() {
  try {
    const today = new Date();

    const receiverResources = [];

    const buildCreditCustomersPromise = BuildCredit.findAll({
      where: {
        status: {
          [Op.notIn]: ["Draft", "Pending", "Pending - Waiting for other requirements"],
        },
      },
      attributes: ["customer_id", "credit_date_limit"],
    });

    const excludedCustomersPromise = BuildCreditAutomatedTextCustomerExclusions.findAll();

    const promises = await Promise.all([buildCreditCustomersPromise, excludedCustomersPromise]);
    const buildCreditCustomers = promises[0];
    const excludedCustomers = promises[1];

    const excludedCustomerIds = excludedCustomers.map((exclusion) => exclusion.customer_id);

    const customerIdsAndDueDates = [];

    buildCreditCustomers.forEach((customer) => {
      const dueDateValue = customer.credit_date_limit;
      const sanitizedDueDate = dueDateValue.replace(/\s+/g, "");

      const matches = sanitizedDueDate.match(/(\d+)days/i);

      if (matches) {
        const days = parseInt(matches[1], 10);
        if (!excludedCustomerIds.includes(customer.customer_id)) {
          customerIdsAndDueDates.push({
            customer_id: customer.customer_id,
            dueInDays: days,
          });
        }
      }
    });
    const receiverPhoneNumbers = [];
    for (const customer of customerIdsAndDueDates) {
      const customerOrders = await OrderForms.findAll({
        where: {
          customer_id: customer.customer_id,
          status: {
            [Op.notIn]: ["Pending", "Denied", "Cancelled"],
          },
          payment_method: {
            [Op.notIn]: ["Online Payment", "Bank Transfer", "Split"],
          },
        },
        attributes: ["total_amount", "reference_no", "date_created"],
      });

      let totalRemainingBalance = 0;
      const dueOrderReferences = [];

      let _orderDue = "";

      for (const order of customerOrders) {
        const orderDate = new Date(order.date_created);
        const orderDueDate = new Date(orderDate);
        _orderDue = orderDueDate;
        orderDueDate.setDate(orderDueDate.getDate() + customer.dueInDays);

        const dueDateSevenDays = new Date(orderDueDate);
        dueDateSevenDays.setDate(orderDueDate.getDate() + 7);

        const dueDateFifteenDays = new Date(orderDueDate);
        dueDateFifteenDays.setDate(orderDueDate.getDate() + 15);

        const dueDateThirtyDays = new Date(orderDueDate);
        dueDateThirtyDays.setDate(orderDueDate.getDate() + 30);

        const additionalDueDates = [];

        let additionalDueDate = new Date(dueDateThirtyDays);
        while (additionalDueDate <= today) {
          additionalDueDate.setDate(additionalDueDate.getDate() + 30);
          additionalDueDates.push(new Date(additionalDueDate));
        }
        if (
          orderDueDate.toDateString() === today.toDateString() ||
          dueDateSevenDays.toDateString() === today.toDateString() ||
          dueDateFifteenDays.toDateString() === today.toDateString() ||
          dueDateThirtyDays.toDateString() === today.toDateString() ||
          additionalDueDates.some((dueDate) => dueDate.toDateString() === today.toDateString())
        ) {
          const payments = await BuildCreditPayments.findAll({
            attributes: [[Sequelize.fn("SUM", Sequelize.col("amount_paid")), "total_amount_paid"]],
            where: {
              customer_id: customer.customer_id,
              status: "Verified",
            },
            raw: true,
          });

          const totalAmountPaid = payments[0].total_amount_paid || 0;
          const remainingBalance = order.total_amount - totalAmountPaid;
          if (remainingBalance > 0) {
            dueOrderReferences.push(order.reference_no);
            totalRemainingBalance += remainingBalance;
          }
        }
      }

      if (dueOrderReferences.length > 0) {
        const customerDetail = await Customers.findByPk(customer.customer_id);
        receiverResources.push({
          customer_name: `${customerDetail.first_name} ${customerDetail.last_name}`,
          hardware_name: customerDetail.hardware_name,
          reference_numbers: `${dueOrderReferences.join(",")}`,
          phone_number: filterAndFormatPhones([customerDetail.phone]).join(","),
          remaining_balance: totalRemainingBalance,
          due_date: formatDateWithoutTime(_orderDue),
        });
        receiverPhoneNumbers.push(customerDetail?.phone);
      }
    }
    console.log(receiverResources);
    const resource = await whispir.resource.createResource(receiverResources);
    let bulkMessage = null;
    if (resource) {
      const resourceId = resource?.data?.id;

      bulkMessage = await whispir.messaging.bulkMessaging(
        { resourceId, mobile_mapping_field: "phone_number" },
        "D3C23DA8AB5F61AE",
        "BuilCredit SMS"
      );
    }

    await MessagesLogs.create({
      customer_id: 0,
      type: "Bulk Message",
      receiver: receiverPhoneNumbers.join(","),
      content: "Build Credit Due Date Text",
      is_sent: bulkMessage ? true : false,
    });

    await AutomationServicesLogs.create({
      automation_type: "BuildCredit Due Dates",
      is_success: bulkMessage ? true : false,
    });
  } catch (err) {
    console.error(err);
  }
}

const dueDateReminder = schedule.scheduleJob("0 14 * * *", async function () {
  const now = new Date();
  const currentHour = now.getHours();
  const currentMinutes = now.getMinutes();
  if (currentHour === 14 && currentMinutes === 0) {
    await sevenDaysDue();
  }
});

module.exports = dueDateReminder;
