const DineroQbFormat = require("../accounting-constants").DineroQbFormat;
const queries = require("../../graphql-client/queries");
const Dinero = require("dinero.js");
const builder = require("xmlbuilder2");
const moment = require("moment-timezone");
const QbXmlUtils = require("./qbxml-utils");
const QbxmlReceivables = require("./qbxml-receivables");
const logger = require("../../utils/logger");

const { generateJobTier, generateOwnerTier, generateSourceTier } = QbXmlUtils;

exports.default = async (req, res) => {
  const { payments: paymentsToQuery } = req.body;

  const BearerToken = req.BearerToken;
  const client = req.userGraphQLClient;

  try {
    logger.log("qbxml-payments-create", "DEBUG", req?.user?.email, null, {
      paymentsToQuery: req.body?.paymentsToQuery
    });

    const result = await client.setHeaders({ Authorization: BearerToken }).request(queries.QUERY_PAYMENTS_FOR_EXPORT, {
      payments: paymentsToQuery
    });
    const { payments, bodyshops } = result;
    const bodyshop = bodyshops[0];
    const isThreeTier = bodyshop.accountingconfig.tiers === 3;
    const twoTierPref = bodyshop.accountingconfig.twotierpref;

    const QbXmlToExecute = [];
    payments.map((i) => {
      if (isThreeTier) {
        QbXmlToExecute.push({
          id: i.id,
          okStatusCodes: ["0", "3100"],
          qbxml: QbxmlReceivables.generateSourceCustomerQbxml(i.job, bodyshop) // Create the source customer.
        });
      }

      QbXmlToExecute.push({
        id: i.id,
        okStatusCodes: ["0", "3100"],
        qbxml: QbxmlReceivables.generateJobQbxml(i.job, bodyshop, isThreeTier, 2, twoTierPref)
      });

      QbXmlToExecute.push({
        id: i.id,
        okStatusCodes: ["0", "3100"],
        qbxml: QbxmlReceivables.generateJobQbxml(i.job, bodyshop, isThreeTier, 3, twoTierPref)
      });

      QbXmlToExecute.push({
        id: i.id,
        okStatusCodes: ["0"],
        qbxml: generatePayment(i, isThreeTier, twoTierPref, bodyshop)
      });
    });

    res.status(200).json(QbXmlToExecute);
  } catch (error) {
    logger.log("qbxml-payments-error", "error", req?.user?.email, null, {
      paymentsToQuery: req.body?.paymentsToQuery,
      error: error.message,
      stack: error.stack
    });
    res.status(400).send(JSON.stringify(error));
  }
};

const generatePayment = (payment, isThreeTier, twoTierPref, bodyshop) => {
  let paymentQbxmlObj;
  if (payment.amount > 0) {
    paymentQbxmlObj = {
      QBXML: {
        QBXMLMsgsRq: {
          "@onError": "continueOnError",
          ReceivePaymentAddRq: {
            ReceivePaymentAdd: {
              CustomerRef: {
                FullName: (payment.job.bodyshop.accountingconfig.tiers === 3
                  ? `${generateSourceTier(payment.job)}:${generateOwnerTier(
                      payment.job,
                      isThreeTier,
                      twoTierPref
                    )}:${generateJobTier(payment.job)}`
                  : `${generateOwnerTier(payment.job, isThreeTier, twoTierPref)}:${generateJobTier(payment.job)}`
                ).trim()
              },
              ARAccountRef: {
                FullName: payment.job.bodyshop.md_responsibility_centers.ar.accountname
              },
              TxnDate: moment(payment.date)
                // .tz(bodyshop.timezone)
                .format("YYYY-MM-DD"), //Trim String
              RefNumber: payment.paymentnum || payment.transactionid,
              TotalAmount: Dinero({
                amount: Math.round(payment.amount * 100)
              }).toFormat(DineroQbFormat),
              PaymentMethodRef: {
                FullName: payment.type
              },
              Memo: `RO ${payment.job.ro_number || ""} OWNER ${
                payment.job.ownr_fn || ""
              } ${payment.job.ownr_ln || ""} ${payment.job.ownr_co_nm || ""} ${
                payment.stripeid || ""
              } ${payment.payer ? ` PAID BY ${payment.payer}` : ""}`,
              IsAutoApply: true
            }
          }
        }
      }
    };
  } else {
    paymentQbxmlObj = {
      QBXML: {
        QBXMLMsgsRq: {
          "@onError": "continueOnError",
          CreditMemoAddRq: {
            CreditMemoAdd: {
              CustomerRef: {
                FullName: (payment.job.bodyshop.accountingconfig.tiers === 3
                  ? `${generateSourceTier(payment.job)}:${generateOwnerTier(
                      payment.job,
                      isThreeTier,
                      twoTierPref
                    )}:${generateJobTier(payment.job)}`
                  : `${generateOwnerTier(payment.job, isThreeTier, twoTierPref)}:${generateJobTier(payment.job)}`
                ).trim()
              },
              ARAccountRef: {
                FullName: payment.job.bodyshop.md_responsibility_centers.ar.accountname
              },
              TxnDate: moment(payment.date)
                //.tz(bodyshop.timezone)
                .format("YYYY-MM-DD"), //Trim String
              RefNumber: payment.paymentnum || payment.stripeid || payment.transactionid,

              CreditMemoLineAdd: [
                {
                  ItemRef: {
                    FullName: payment.job.bodyshop.md_responsibility_centers.refund.accountitem
                  },
                  Desc: payment.memo,
                  Amount: Dinero({
                    amount: Math.round(payment.amount * 100 * -1)
                  }).toFormat(DineroQbFormat),
                  SalesTaxCodeRef: { FullName: "E" }
                }
              ]
            }
          }
        }
      }
    };
  }

  var paymentQbxmlPartial = builder
    .create(paymentQbxmlObj, {
      version: "1.30",
      encoding: "UTF-8",
      headless: true
    })
    .end({ pretty: true });

  const paymentQbxmlFull = QbXmlUtils.addQbxmlHeader(paymentQbxmlPartial);

  return paymentQbxmlFull;
};
