import log from "electron-log/main";

import { UUID } from "crypto";
import { Request, Response } from "express";
import _ from "lodash";
import errorTypeCheck from "../../util/errorTypeCheck";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
let Winax: any; // Declare Winax as any to avoid TypeScript errors on non-Windows platforms

if (process.platform === "win32") {
  // eslint-disable-next-line @typescript-eslint/no-require-imports
  Winax = require("winax");
}

export async function handleQuickBookRequest(
  req: Request,
  res: Response,
): Promise<void> {
  if (process.platform !== "win32") {
    res.status(500).json({
      error: "QuickBooks Desktop integration is only available on Windows",
    });
    return;
  }

  const QbFilePath: string = `C:\\Users\\PatrickFic\\Development\\FRODO COLLISION.QBW`;
  // ||
  // (store.get("settings.qbFilePath") as string) F

  if (_.isEmpty(QbFilePath)) {
    res.status(400).json({ error: "Quickbooks file path not set" });
    return;
  }

  const qbxmlRequestList = req.body as Array<{
    id: UUID;
    okStatusCodes: Array<string>;
    qbxml: string;
  }>;

  const returnResponse: Array<{
    Id: UUID;
    Success: boolean;
    ErrorMessage: string;
  }> = [];

  //Connect to the QuickBooks File
  let requestProcessor;
  try {
    requestProcessor = new Winax.Object("QBXMLRP2.RequestProcessor.2");
    requestProcessor.OpenConnection(QbFilePath, "ShopPartnerActualRequest");
  } catch (error) {
    log.error(
      "Error instnatiating QuickBooks Request Processor",
      QbFilePath,
      errorTypeCheck(error),
    );
    res.status(500).json({ error: "Error connecting to QuickBooks" });
    return;
  }

  const ticket = requestProcessor.BeginSession(QbFilePath, 2); //2 indicated qbFileOpenModeDoNotCare
  log.info("Quickbooks Ticket", ticket);
  for (const qbxmlRequest of qbxmlRequestList) {
    try {
      //TODO: Refactor to not create a new connection every time.
      const QuickBooksResponse = requestProcessor.ProcessRequest(
        ticket,
        qbxmlRequest.qbxml,
      );
      log.info("QuickBooks Raw Response: ", QuickBooksResponse);
      returnResponse.push({
        Id: qbxmlRequest.id,
        Success:
          QuickBooksResponse.StatusCode === "0" ||
          qbxmlRequest.okStatusCodes.includes(QuickBooksResponse.StatusCode),
        ErrorMessage: QuickBooksResponse,
      });
    } catch (error) {
      log.error(
        "Error running transaction",
        ticket,
        qbxmlRequest,
        errorTypeCheck(error),
      );
    }
  }
  requestProcessor.EndSession(ticket);
  requestProcessor.CloseConnection();
  res.json(qbxmlRequestList);
}

//This set of functions works.
export function TestQB(): void {
  if (process.platform !== "win32") {
    log.warn("TestQB is only available on Windows");
    return;
  }
  let requestProcessor, ticket;
  try {
    requestProcessor = new Winax.Object("QBXMLRP.RequestProcessor.1");
    requestProcessor.OpenConnection("", "ShopPartnerOneoFf");

    ticket = requestProcessor.BeginSession("", 2); //2 indicated qbFileOOpenModeDoNotCare

    requestProcessor.ProcessRequest(
      ticket,
      `<?qbxml version="16.0"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<AccountQueryRq requestID="1"> </AccountQueryRq>
</QBXMLMsgsRq>
</QBXML>`,
    );
  } catch (error) {
    log.error(
      "Error instnatiating QuickBooks Request Processor",

      errorTypeCheck(error),
    );

    return;
  }

  log.log("Ticket", ticket);
  requestProcessor.EndSession(ticket);
  requestProcessor.CloseConnection();
  return;
}
