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

Dinero.globalRoundingMode = "HALF_EVEN";
const { generateJobTier, generateOwnerTier, generateSourceTier } = QbXmlUtils;

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

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

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

    const result = await client
      .setHeaders({ Authorization: BearerToken })
      .request(queries.QUERY_JOBS_FOR_RECEIVABLES_EXPORT, { ids: jobIds });
    const { jobs, bodyshops } = result;
    const QbXmlToExecute = [];

    const bodyshop = bodyshops[0];

    jobs.map((jobs_by_pk) => {
      //Is this a two tier, or 3 tier setup?
      const isThreeTier = bodyshop.accountingconfig.tiers === 3;
      const twoTierPref = bodyshop.accountingconfig.twotierpref;

      //This is the Insurance Company tier IF 3 tier is selected.
      if (isThreeTier) {
        QbXmlToExecute.push({
          id: jobs_by_pk.id,
          okStatusCodes: ["0", "3100"],
          qbxml: generateSourceCustomerQbxml(jobs_by_pk, bodyshop) // Create the source customer.
        });
      }

      //If 3 tier, this should be the customer.
      //If 2 tier, this should be based on the pref.
      QbXmlToExecute.push({
        id: jobs_by_pk.id,
        okStatusCodes: ["0", "3100"],
        qbxml: generateJobQbxml(jobs_by_pk, bodyshop, isThreeTier, 2, twoTierPref)
      });

      //This is always going to be the job.
      QbXmlToExecute.push({
        id: jobs_by_pk.id,
        okStatusCodes: ["0", "3100"],
        qbxml: generateJobQbxml(jobs_by_pk, bodyshop, isThreeTier, 3, twoTierPref)
      });

      if (!req.body.custDataOnly) {
        //Generate the actual invoice.
        QbXmlToExecute.push({
          id: jobs_by_pk.id,
          okStatusCodes: ["0"],
          qbxml: generateInvoiceQbxml(jobs_by_pk, bodyshop, isThreeTier, twoTierPref)
        });
      }
    });

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

const generateSourceCustomerQbxml = (jobs_by_pk, bodyshop) => {
  const customerQbxmlObj = {
    QBXML: {
      QBXMLMsgsRq: {
        "@onError": "continueOnError",
        CustomerAddRq: {
          CustomerAdd: {
            Name: jobs_by_pk.ins_co_nm.trim()
            // BillAddress: {
            //   Addr1: jobs_by_pk.ownr_addr1,
            //   Addr2: jobs_by_pk.ownr_addr2,
            //   City: jobs_by_pk.ownr_city,
            //   State: jobs_by_pk.ownr_st,
            //   PostalCode: jobs_by_pk.ownr_zip,
            // },
          }
        }
      }
    }
  };

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

  const customerQbxml_Full = QbXmlUtils.addQbxmlHeader(customerQbxml_partial);

  return customerQbxml_Full;
};
exports.generateSourceCustomerQbxml = generateSourceCustomerQbxml;
const generateJobQbxml = (jobs_by_pk, bodyshop, isThreeTier, tierLevel, twoTierPref) => {
  let Name;
  let ParentRefName;

  if (tierLevel === 2) {
    Name = generateOwnerTier(jobs_by_pk, isThreeTier, twoTierPref);
    ParentRefName = isThreeTier ? generateSourceTier(jobs_by_pk) : null;
  } else if (tierLevel === 3) {
    Name = generateJobTier(jobs_by_pk);
    ParentRefName = isThreeTier
      ? `${generateSourceTier(jobs_by_pk)}:${generateOwnerTier(jobs_by_pk)}`
      : generateOwnerTier(jobs_by_pk, isThreeTier, twoTierPref);
  }

  const jobQbxmlObj = {
    QBXML: {
      QBXMLMsgsRq: {
        "@onError": "continueOnError",

        CustomerAddRq: {
          CustomerAdd: {
            Name: Name,
            ParentRef: ParentRefName
              ? {
                  FullName: ParentRefName
                }
              : null,
            ...(tierLevel === 3
              ? {
                  BillAddress: {
                    Addr1: jobs_by_pk.ownr_addr1,
                    Addr2: jobs_by_pk.ownr_addr2,
                    City: jobs_by_pk.ownr_city,
                    State: jobs_by_pk.ownr_st,
                    PostalCode: jobs_by_pk.ownr_zip
                  },
                  ShipAddress: {
                    Addr1: jobs_by_pk.ownr_addr1,
                    Addr2: jobs_by_pk.ownr_addr2,
                    City: jobs_by_pk.ownr_city,
                    State: jobs_by_pk.ownr_st,
                    PostalCode: jobs_by_pk.ownr_zip
                  },
                  Email: jobs_by_pk.ownr_ea
                }
              : {})
          }
        }
      }
    }
  };

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

  const jobQbxml_Full = QbXmlUtils.addQbxmlHeader(jobQbxml_partial);

  return jobQbxml_Full;
};

exports.generateJobQbxml = generateJobQbxml;
const generateInvoiceQbxml = (jobs_by_pk, bodyshop, isThreeTier, twoTierPref) => {
  //Build the Invoice XML file.

  const InvoiceLineAdd = CreateInvoiceLines({ bodyshop, jobs_by_pk });

  const invoiceQbxmlObj = {
    QBXML: {
      QBXMLMsgsRq: {
        "@onError": "stopOnError",
        InvoiceAddRq: {
          InvoiceAdd: {
            CustomerRef: {
              FullName: (bodyshop.accountingconfig.tiers === 3
                ? `${generateSourceTier(jobs_by_pk)}:${generateOwnerTier(jobs_by_pk)}:${generateJobTier(jobs_by_pk)}`
                : `${generateOwnerTier(jobs_by_pk, isThreeTier, twoTierPref)}:${generateJobTier(jobs_by_pk)}`
              ).trim()
            },
            ...(jobs_by_pk.class ? { ClassRef: { FullName: jobs_by_pk.class } } : {}),

            ARAccountRef: {
              FullName: bodyshop.md_responsibility_centers.ar.accountname
            },
            TxnDate: moment(jobs_by_pk.date_invoiced).tz(bodyshop.timezone).format("YYYY-MM-DD"),
            RefNumber: jobs_by_pk.ro_number,
            BillAddress: {
              Addr1: jobs_by_pk.ownr_co_nm
                ? jobs_by_pk.ownr_co_nm.substring(0, 30).trim()
                : `${`${jobs_by_pk.ownr_ln || ""} ${jobs_by_pk.ownr_fn || ""}`.substring(0, 30).trim()}`,
              Addr2: jobs_by_pk.ownr_addr1,
              Addr3: jobs_by_pk.ownr_addr2,
              City: jobs_by_pk.ownr_city,
              State: jobs_by_pk.ownr_st,
              PostalCode: jobs_by_pk.ownr_zip
            },
            ShipAddress: {
              Addr1: jobs_by_pk.ownr_co_nm
                ? jobs_by_pk.ownr_co_nm.substring(0, 30).trim()
                : `${`${jobs_by_pk.ownr_ln || ""} ${jobs_by_pk.ownr_fn || ""}`.substring(0, 30).trim()}`,
              Addr2: jobs_by_pk.ownr_addr1,
              Addr3: jobs_by_pk.ownr_addr2,
              City: jobs_by_pk.ownr_city,
              State: jobs_by_pk.ownr_st,
              PostalCode: jobs_by_pk.ownr_zip
            },
            PONumber: jobs_by_pk.clm_no,
            ...InstanceManager({
              rome: {
                ItemSalesTaxRef: {
                  FullName: bodyshop.md_responsibility_centers.taxes.invoiceexemptcode
                }
              }
            }),
            IsToBePrinted: bodyshop.accountingconfig.printlater,
            ...(jobs_by_pk.ownr_ea ? { IsToBeEmailed: bodyshop.accountingconfig.emaillater } : {}),

            InvoiceLineAdd: InvoiceLineAdd
          }
        }
      }
    }
  };

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

  const invoiceQbxml_Full = QbXmlUtils.addQbxmlHeader(invoiceQbxml_partial);

  return invoiceQbxml_Full;
};

// const generateInvoiceLine = (job, allocation, responsibilityCenters) => {
//   const { amount, center } = allocation;
//   const DineroAmount = Dinero(amount);
//   const account = responsibilityCenters.profits.find(
//     (i) => i.name.toLowerCase() === center.toLowerCase()
//   );

//   if (!!!account) {
//     throw new Error(
//       `A matching account does not exist for the allocation. Center: ${center}`
//     );
//   }

//   return {
//     ItemRef: { FullName: account.accountitem },
//     Desc: account.accountdesc,
//     Quantity: 1,
//     //Rate: 100,
//     Amount: DineroAmount.toFormat(DineroQbFormat),
//     SalesTaxCodeRef: {
//       FullName: "E",
//     },
//   };
// };
