import fs from "fs";
import type { HttpContextContract } from "@ioc:Adonis/Core/HttpContext";
import axios from "axios";

export default class ErpsController {
  /**
   * Controller do tim cac serial number trong cac log trong khoang thoi gian xac dinh
   * @param {Integer} from thoi gian bat dau YYYYMMDD (vd: 20230130)
   * @param {Integer} to thoi gian ket thuc YYYYMMDD (vd: 20230230)
   */
  public async getIndexSerialNumber({
    request,
    response,
  }: HttpContextContract) {
    const { from, to } = request.all();
    const getListLog = async (from, to) => {
      try {
        // console.log("check!")
        const listLog: string[] = [];
        const response = await axios.get("http://192.168.5.7:8080/");
        const responseAUTO = await axios.get(
          "http://192.168.5.7:8080/AUTOlog/"
        );

        let data1 = response.data
          .split("\n")
          .filter((i) => i.search("<a href") !== -1 && i.search(".log") !== -1);
        let data2 = responseAUTO.data
          .split("\n")
          .filter((i) => i.search("<a href") !== -1 && i.search(".log") !== -1);

        const arrayLine = data1.concat(data2);

        // const arrayLineAUTO = data
        //   .split("\n")
        //   .filter((i) => i.search("<a href") !== -1 && i.search(".log") !== -1);

        arrayLine.map((u) => {
          let temp = u
            .slice(u.search("<a ") + 9, u.search("</a>"))
            .split(">")[1];

          if (
            parseInt(temp?.split("-")[0]) >= from &&
            parseInt(temp?.split("-")[0]) <= to
          ) {
            listLog.push(
              (u
                .slice(u.search("<a ") + 9, u.search("</a>"))
                .split(">")[1]
                .includes("AUTO")
                ? "http://192.168.5.7:8080/AUTOlog/"
                : "http://192.168.5.7:8080/") +
                u.slice(u.search("<a ") + 9, u.search("</a>")).split(">")[1] +
                " "
            );
          }
        });

        return listLog;
      } catch (error) {
        console.log(error);
      }
    };

    const fetchFiles = async (from, to) => {
      try {
        const urls = await getListLog(from, to);
        let report = [];
        const fileContents = await Promise.all(
          urls.map(async (url) => {
            const maxRetries = 10;
            let retries = 0;
            while (retries < maxRetries) {
              try {
                const response = await axios.get(url?.split(" ")[0]);
                return response.data;
              } catch (error) {
                if (error.code !== "") {
                  //=== "ETIMEDOUT" || error.code === "ECONNRESET"
                  // console.log("Connection timed out. Retrying...");
                  retries++;
                } else {
                  console.error("Error fetching file:", error);
                  return;
                }
              }
            }
          })
        );

        // Handle the file contents
        fileContents.forEach((content, index) => {
          console.log(`Content of file ${index + 1}:`);
          const arrayLine = content?.split("\n");
          let output = [];
          if (arrayLine !== undefined) {
            for (let i = 0; i < arrayLine.length; i++) {
              let SN = arrayLine[i]
                ?.split("SN:")[1]
                ?.trim()
                .replace(/[!@#$%^&*()_+{}\[\]:;<>,.?~\\/]/g, "");
              if (
                arrayLine[i].search("PID:") !== -1 &&
                arrayLine[i].search("SN:") !== -1 &&
                arrayLine[i].search("%") === -1 &&
                arrayLine[i]
                  ?.split(",")[2]
                  ?.split(":")[1]
                  ?.replace("\r", "")
                  .trim() !== "" &&
                SN !== "N/A" && SN.length>4
              ) {
                if (output.some((u) => u.SN === SN)) {
                  output.map((u, index) => {
                    if (u.SN === SN) {
                      output[index].PID =
                        arrayLine[i]?.split("VID:")[0] !== undefined
                          ? arrayLine[i]
                              ?.split("VID:")[0]
                              ?.slice(
                                arrayLine[i]?.split("VID:")[0]?.search("PID")
                              )
                              ?.split(":")[1]
                              ?.split(",")[0]
                              ?.trim()
                          : "";
                      (output[index].VID =
                        arrayLine[i]?.split("SN:")[0] !== undefined
                          ? arrayLine[i]
                              ?.split("SN:")[0]
                              ?.split("VID:")[1]
                              ?.split(",")[0]
                              ?.trim()
                          : ""),
                        (output[index].line = output[index].line.concat([
                          i + 1,
                        ]));
                    }
                  });
                } else {
                  let fName = urls[index]
                    ?.split("/")
                    [urls[index]?.split("/")?.length - 1]?.trim();
                  output.push({
                    PID:
                      arrayLine[i]?.split("VID:")[0] !== undefined
                        ? arrayLine[i]
                            ?.split("VID:")[0]
                            ?.slice(
                              arrayLine[i]?.split("VID:")[0]?.search("PID")
                            )
                            ?.split(":")[1]
                            ?.split(",")[0]
                            ?.trim()
                        : "",
                    VID:
                      arrayLine[i]?.split("SN:")[0] !== undefined
                        ? arrayLine[i]
                            ?.split("SN:")[0]
                            ?.split("VID:")[1]
                            ?.split(",")[0]
                            ?.trim()
                        : "",
                    SN:
                      arrayLine[i].split("SN:")[1] !== undefined
                        ? SN.search(" ") !== -1
                          ? SN?.split(" ")[0]
                          : SN
                        : "",
                    line: [i + 1],
                    fileName: fName,
                    warehouse:
                      (fName.search("-US") !== -1 ||
                        fName.search(".US") !== -1 ||
                        fName.search("US-") !== -1) &&
                      fName.search("AUS") === -1
                        ? "US"
                        : "AU",
                  });
                }
              }

              if (arrayLine[i].search("Serial Number") !== -1) {
                let PCB_SN = arrayLine[i]
                  ?.split("Serial Number")[1]
                  .split(":")[1]
                  ?.replace("\r", "")
                  .trim()
                  .replace(/[!@#$%^&*()_+{}\[\]:;<>,.?~\\/]/g, "");
                if (
                  //Neu SN da nam trong output
                  output.some((u) => u.SN === PCB_SN)
                ) {
                  output.map((u, index) => {
                    if (u.SN === PCB_SN) {
                      output[index].line = output[index].line.concat([i + 1]);
                    }
                  });
                } else {
                  // if (
                  //   /^[A-Z0-9-]{5,}$/.test(
                  //     PCB_SN
                  //   )
                  // ) {
                  let fName = urls[index]
                    ?.split("/")
                    [urls[index]?.split("/")?.length - 1]?.trim();
                  output.push({
                    PID: "",
                    VID: "",
                    SN:
                      PCB_SN?.search(" ") !== -1
                        ? PCB_SN?.split(" ")[0]
                        : PCB_SN,
                    line: [i + 1],
                    fileName: fName,
                    warehouse:
                      (fName.search("-US") !== -1 ||
                        fName.search(".US") !== -1 ||
                        fName.search("US-") !== -1) &&
                      fName.search("AUS") === -1
                        ? "US"
                        : "AU",
                  });
                  // }
                }
              }

              if (arrayLine[i].search("Processor board ID") !== -1) {
                let PBID = arrayLine[i]
                  ?.split(" ")
                  [arrayLine[i]?.split(" ").length - 1]?.replace("\r", "")
                  .trim()
                  .replace(/[!@#$%^&*()_+{}\[\]:;<>,.?~\\/]/g, "");
                if (
                  //Neu SN da nam trong output
                  output.some((u) => u.SN === PBID)
                ) {
                  output.map((u, index) => {
                    if (u.SN === PBID) {
                      output[index].line = output[index].line.concat([i + 1]);
                    }
                  });
                } else {
                  if (PBID?.length >= 8) {
                    let fName = urls[index]
                      ?.split("/")
                      [urls[index]?.split("/")?.length - 1]?.trim();
                    output.push({
                      PID: "",
                      VID: "",
                      SN: PBID?.search(" ") !== -1 ? PBID?.split(" ")[0] : PBID,
                      line: [i + 1],
                      fileName: fName,
                      warehouse:
                        (fName.search("-US") !== -1 ||
                          fName.search(".US") !== -1 ||
                          fName.search("US-") !== -1) &&
                        fName.search("AUS") === -1
                          ? "US"
                          : "AU",
                    });
                  }
                }
              }
            }
            report = report.concat(output);
          }
        });

        fs.writeFile(
          "./app/utils/indexSN.txt",
          JSON.stringify(report)
            .replace(/,{/g, "\n,{")
            .replace(/\\u0000/g, ""),
          function (err) {
            if (err) {
              return console.error(err);
            }
            console.log("Write loggg !");
          }
        );
        // console.log(report);
        return report.filter(
          (i) => i.SN !== "" && /^[A-Z0-9-]{5,}$/.test(i.SN) === true && i.PID !==""
        );
        // }, 15000);
      } catch (error) {
        response
          .status(500)
          .send({ mess: "GET INFORMATION FAIL", error: error });
      }
    };
    const result = await fetchFiles(from, to);
    response.status(200).json(result);
  }

  /**
   * Controller lay noi dung file log theo so dong
   * @param {String} fileName url file log tren server log
   * @param {Integer} line dong chua serial number trong log
   * @param {Integer} range khoang dong truoc/sau line
   * @author {Token} req.headers.authorization //token xac thuc
   */
  public async getParagraph({ request, response }: HttpContextContract) {
    const { fileName, line, range } = request.all();

    try {
      let fName =
        fileName.search("AUTO") !== -1 ? "AUTOlog/" + fileName : fileName;
      const res = await axios.get("http://192.168.5.7:8080/" + fName);
      const arrayLine = res?.data?.split("\n");

      if (range >= line) {
        response.status(200).json({
          content: arrayLine?.slice(0, line + range)?.join("\n"),
        });
      } else {
        response.status(200).json({
          content: arrayLine?.slice(line - range - 1, line + range)?.join("\n"),
        });
      }
    } catch (error) {
      console.log(error);
      response
        .status(202)
        .send({ mess: "FILE NOT FOUND", error: error });
    }
  }

  public async store({ request, response }: HttpContextContract) {}

  public async show({}: HttpContextContract) {}

  public async edit({}: HttpContextContract) {}

  public async update({}: HttpContextContract) {}

  public async destroy({}: HttpContextContract) {}
}
