import Env from "@ioc:Adonis/Core/Env";
import axios from "axios";
import { addLogFunction } from "./addLogFunction";
import moment from "moment";

type OutputItem = {
  PID: string;
  VID: string;
  SN: string;
  line: number[];
  fileName: string;
  warehouse: "US" | "AU";
};

export const checkIndexSN = async (
  content: string[],
  beginLine: number,
  nameF: string
): Promise<void> => {
  try {
    const arrayLine = content;
    const output: OutputItem[] = [];

    if (!arrayLine) return;

    for (let i = 0; i < arrayLine.length; i++) {
      const line = arrayLine[i];
      const SN = line
        ?.split("SN:")[1]
        ?.trim()
        .replace(/[!@#$%^&*()_+{}\[\]:;<>,.?~\\/]/g, "");

      // Pattern: PID + SN
      if (
        line.includes("PID:") &&
        line.includes("SN:") &&
        !line.includes("%") &&
        SN &&
        SN !== "N/A" &&
        SN.length > 4 &&
        i >= beginLine
      ) {
        const existingIndex = output.findIndex((u) => u.SN === SN);
        const PID = line?.split("VID:")[0]
          ?.slice(line?.split("VID:")[0]?.search("PID"))
          ?.split(":")[1]
          ?.split(",")[0]
          ?.trim() ?? "";

        const VID = line?.split("SN:")[0]
          ?.split("VID:")[1]
          ?.split(",")[0]
          ?.trim() ?? "";

        if (existingIndex !== -1) {
          output[existingIndex].PID = PID;
          output[existingIndex].VID = VID;
          output[existingIndex].line.push(i + 1);
        } else {
          output.push({
            PID,
            VID,
            SN: SN.includes(" ") ? SN.split(" ")[0] : SN,
            line: [i + 1],
            fileName: nameF,
            warehouse:
              (nameF.includes("-US") ||
                nameF.includes(".US") ||
                nameF.includes("US-")) &&
              !nameF.includes("AUS")
                ? "US"
                : "AU",
          });
        }
      }

      // Pattern: "Serial Number"
      if (line.includes("Serial Number") && i >= beginLine) {
        const rawSN = line.split("Serial Number")[1]?.split(":")[1]
          ?.replace("\r", "")
          ?.trim()
          ?.replace(/[!@#$%^&*()_+{}\[\]:;<>,.?~\\/]/g, "");

        if (!rawSN) continue;

        const SN = rawSN.includes(" ") ? rawSN.split(" ")[0] : rawSN;

        const existing = output.find((u) => u.SN === SN);
        if (existing) {
          existing.line.push(i + 1);
        } else {
          output.push({
            PID: "",
            VID: "",
            SN,
            line: [i + 1],
            fileName: nameF,
            warehouse:
              (nameF.includes("-US") ||
                nameF.includes(".US") ||
                nameF.includes("US-")) &&
              !nameF.includes("AUS")
                ? "US"
                : "AU",
          });
        }
      }

      //Vendor Serial (SN)
      if (line.includes("Vendor Serial (SN)") && i >= beginLine) {
        const rawSN = line.split("Vendor Serial (SN)")[1]?.split(":")[1]
          ?.replace("\r", "")
          ?.trim()
          ?.replace(/[!@#$%^&*()_+{}\[\]:;<>,.?~\\/]/g, "");

        if (!rawSN) continue;

        const SN = rawSN.includes(" ") ? rawSN.split(" ")[0] : rawSN;

        const existing = output.find((u) => u.SN === SN);
        if (existing) {
          existing.line.push(i + 1);
        } else {
          output.push({
            PID: "",
            VID: "",
            SN,
            line: [i + 1],
            fileName: nameF,
            warehouse:
              (nameF.includes("-US") ||
                nameF.includes(".US") ||
                nameF.includes("US-")) &&
              !nameF.includes("AUS")
                ? "US"
                : "AU",
          });
        }
      }

      //System serial num
      if (line.includes("System serial num") && i >= beginLine) {
        const rawSN = line.split("System serial num")[1]?.split(":")[1]
          ?.replace("\r", "")
          ?.trim()
          ?.replace(/[!@#$%^&*()_+{}\[\]:;<>,.?~\\/]/g, "");

        if (!rawSN) continue;

        const SN = rawSN.includes(" ") ? rawSN.split(" ")[0] : rawSN;

        const existing = output.find((u) => u.SN === SN);
        if (existing) {
          existing.line.push(i + 1);
        } else {
          output.push({
            PID: "",
            VID: "",
            SN,
            line: [i + 1],
            fileName: nameF,
            warehouse:
              (nameF.includes("-US") ||
                nameF.includes(".US") ||
                nameF.includes("US-")) &&
              !nameF.includes("AUS")
                ? "US"
                : "AU",
          });
        }
      }

      // Pattern: "Processor board ID"
      if ((line.includes("Processor board ID") || line.includes("Processor Board ID")) && i >= beginLine ) {
        const parts = line.split(" ");
        const PBID = parts[parts.length - 1]
          ?.replace("\r", "")
          ?.trim()
          ?.replace(/[!@#$%^&*()_+{}\[\]:;<>,.?~\\/]/g, "");

        if (!PBID || PBID.length < 8) continue;

        const SN = PBID.includes(" ") ? PBID.split(" ")[0] : PBID;

        const existing = output.find((u) => u.SN === SN);
        if (existing) {
          existing.line.push(i + 1);
        } else {
          output.push({
            PID: "",
            VID: "",
            SN,
            line: [i + 1],
            fileName: nameF,
            warehouse:
              (nameF.includes("-US") ||
                nameF.includes(".US") ||
                nameF.includes("US-")) &&
              !nameF.includes("AUS")
                ? "US"
                : "AU",
          });
        }
      }
    }

    const pattern = /[\x00-\x20\x7F]/g;
    const invalidPIDItems = output.filter(
      (i) => !i.PID.match(pattern)
    );


    const fileName =
    "./app/store/logsAPI/" +
    moment().format("DD_MM_YYYY") +
    ".log";

    if (invalidPIDItems.length > 0) {
      const tokenStage = Env.get("STAGE_TOKEN_REQUEST");
      const tokenProd = Env.get("INT_TOKEN_REQUEST");
      const data = {
        data: invalidPIDItems,
        urlAPI: "/api/test-log-serial-number/save-data",
      };

      // Try stage first
      try {
        const response_stage = await axios.post(
          "https://stage.nswteam.net/api/transferPostData",
          data,
          {
            headers: { Authorization: "Bearer " + tokenStage },
          }
        );

        addLogFunction(
          fileName,
          "URL: https://stage.nswteam.net/api/transferPostData\n" +
            JSON.stringify(response_stage?.data, null, 2),
          "Update SN index to stage.nswteam.net"
        );
      } catch (e) {
        console.error("Error sending to stage.nswteam.net:", JSON.stringify(e));
      }

      // If prod, send to int.ipsupply.com.au too
      if (Env.get("RUN_ENV") === "prod") {
        try {
          const response_int = await axios.post(
            "https://int.ipsupply.com.au/api/transferPostData",
            data,
            {
              headers: { Authorization: "Bearer " + tokenProd },
            }
          );

          console.log(nameF + " response\n", response_int.data);
          addLogFunction(
            fileName,
            "URL: https://int.ipsupply.com.au/api/transferPostData\n" +
              JSON.stringify(response_int.data, null, 2),
            "Update SN index to int.ipsupply.com.au"
          );
        } catch (e) {
          console.error("Error sending to int.ipsupply.com.au:", JSON.stringify(e));
        }
      }
    }
  } catch (error) {
    console.error("Can't connect to log server:", JSON.stringify(error));
  }
};
