import { ref } from "vue";
import { defineStore } from "pinia";
import { useCounterMixin } from "./mixin";

const { messageErrorLinkage, success, hideLoader } = useCounterMixin();

export const useLinkageStore = defineStore("linkageData", () => {
  const apiURL = ref<string>("http://127.0.0.1:51548"); // API URL From Agent

  const devices = ref<string>(""); // ค่าเครื่องอ่านบัตรที่เลือก
  const devicesData = ref<string[]>([]); // รายการเครื่องอ่านบัตรจากการดึงครั้งแรก
  const devicesOp = ref<string[]>([]); // รายการเครื่องอ่านบัตรสำหรับ options
  const step = ref<number>(1); // ขั้นตอนการทำงาน login linkage
  const CID = ref<string>(""); // id ของ card (16 char)
  const xKey = ref<string>("");
  const envelopGMXs = ref<string>("");

  /** ยิง API เพื่อดึงรายการข้อมูลเครื่องอ่านบัตร
   * @param {any} q ค่า this ของ quasar
   */
  async function fetchDeviceLists(q: any) {
    console.log("[0] START fetchDeviceLists");

    await fetch(`${apiURL.value}/smart-card/device`, {
      method: "GET",
    })
      .then((response) => {
        if (response.ok) {
          return response.json();
        }
        throw new Error("Something went wrong");
      })
      .then(async (data) => {
        console.log("fetchDeviceLists===>", data);

        devicesOp.value = await data.devices;
        devicesData.value = await data.devices;
        step.value = 2;
      })
      .catch(async (error) => {
        messageErrorLinkage(q, error);
      });
  }

  /** connect device ที่เลือก
   * @param {any} q ค่า this ของ quasar
   */
  async function readDevice(q: any) {
    console.log("[1] อ่านบัตร");

    await fetch(
      `${apiURL.value}/smart-card/connect/?deviceName=${devices.value}`,
      {
        method: "GET",
      }
    )
      .then((response) => {
        if (response.ok) {
          return response.json();
        }
        throw new Error("Something went wrong");
      })
      .then((data) => {
        console.log("readDevice===>", data);
        getInfo(q);
      })
      .catch((error) => {
        messageErrorLinkage(q, error);
      });
  }

  /** ดึงข้อมูล CID จากเครื่องอ่านบัตร
   * @param {any} q ค่า this ของ quasar
   */
  async function getInfo(q: any) {
    console.log("START getInfo");

    await fetch(`${apiURL.value}/smart-card/info`, {
      method: "GET",
    })
      .then(function (response) {
        if (response.ok) {
          return response.json();
        }
        throw new Error("Something went wrong");
      })
      .then(async (data) => {
        console.log("getInfo===>", data);
        CID.value = await data.cid;

        console.log("cid===>", CID.value);

        postReadIdCard(q);
      })
      .catch((error) => {
        messageErrorLinkage(q, error);
      });
  }

  const PID = ref<string>("");
  /** ดึงข้อมูล personalID/ id card จากเครื่องอ่านบัตร
   * @param {any} q ค่า this ของ quasar
   */
  async function postReadIdCard(q: any) {
    console.log("START postReadIdCard");

    await fetch(`${apiURL.value}/smart-card/read/`, {
      method: "POST",
      body: JSON.stringify({
        fields: ["personalID", "engName", "expireDate"],
      }),
      headers: {
        "Content-Type": "application/json",
      },
    })
      .then((response) => {
        if (response.ok) {
          return response.json();
        }
        throw new Error("Something went wrong");
      })
      .then(async (data) => {
        console.log("postReadIdCard===>", data);
        PID.value = await data.personalID;
        console.log("personalID===>", PID.value);
        await amiEnvironment(q);
        await amiConnect(q);
      })
      .catch((error) => {
        messageErrorLinkage(q, error);
      });
  }

  /** setting ami environment
   * @param {any} q ค่า this ของ quasar
   */
  async function amiEnvironment(q: any) {
    await fetch(`${apiURL.value}/ami/environment`, {
      method: "POST",
      body: JSON.stringify({
        host: "lkbmabk.bma.go.th",
        port: "20000",
      }),
      headers: {
        "Content-Type": "application/json",
      },
    })
      .then((response) => {
        if (response.ok) {
          return response.json();
        }
        throw new Error("Something went wrong");
      })
      .then((data) => {
        console.log("amiEnvironment===>", data);
        return;
      })
      .catch((error) => {
        messageErrorLinkage(q, error);
      });
  }

  /**
   * connect ami
   * @param q ค่า this ของ quasar
   */
  async function amiConnect(q: any) {
    await fetch(`${apiURL.value}/ami/connect`, {
      method: "GET",
    })
      .then((response) => {
        if (response.ok) {
          return response.json();
        }
        throw new Error("Something went wrong");
      })
      .then((data) => {
        console.log("amiConnect===>", data);
        return;
      })
      .catch((error) => {
        messageErrorLinkage(q, error);
      });
  }

  /**
   * card authentication
   * @param q ค่า this ของ quasar
   */
  async function authentication(q: any) {
    console.log("[4] START authentication");
    await fetch(`${apiURL.value}/smart-card/authentication`, {
      method: "GET",
    })
      .then((response) => {
        if (response.ok) {
          return response.json();
        }
        throw new Error("Something went wrong");
      })
      .then(function (data) {
        console.log("authentication===>", data);
        return;
      })
      .catch((error) => {
        messageErrorLinkage(q, error);
      });
  }

  /**
   * verify pin
   * @param q ค่า this ของ quasar
   */
  async function verifyPin(q: any) {
    console.log("START verifyPin");

    const requestOptions = {
      method: "POST",
      body: JSON.stringify({
        crossAuthen: {
          random: ascii_to_hexa(xKey.value),
        },
        privateAccess: true,
      }),
      headers: {
        "Content-Type": "application/json",
      },
    };
    await fetch(`${apiURL.value}/smart-card/verify`, requestOptions)
      .then((response) => {
        if (response.ok) {
          return response.json();
        }
        throw new Error("Something went wrong");
      })
      .then(async (data) => {
        console.log("verifyPin===>", data);

        envelopGMXs.value = await data.crossAuthen.envelope;

        console.log("envelopGMXs===>", envelopGMXs.value);

        await amiRequest(q, 9081);
      })
      .catch((error) => {
        messageErrorLinkage(q, error);
      });
  }

  const officeid = ref<string>("00301"); // office id เป็นรหัสของ กทม (00301)
  const tKey = ref<string>("");
  const officeCode = ref<string>("00023");
  const versionCode = ref<string>("00001");
  /**
   * ส่งขอข้อมูล
   * @param {any} q ค่า this ของ quasar
   * @param {number} code รหัสที่ต้องการขอข้อมูล (9080)
   * @param {string} serviceCode รหัส service code ที่ต้องการขอข้อมูล (001)
   * @param {string} idcard รหัสบัตรประชาชนของผู้ที่ต้องการดึงข้อมูล
   */
  async function amiRequest(
    q: any,
    code: number,
    idcard?: string,
    serviceCode?: string
  ) {
    let message = "";
    console.log("code===>", code);

    if (code === 9080) {
      console.log("[3] START amiRequest");

      console.log("PID===>", PID.value);
      console.log("CID===>", CID.value);
      console.log("officeid===>", officeid.value);

      message = `${code}${PID.value}${CID.value}${officeid.value}`;

      console.log("message===>", message);
    } else if (code === 9081) {
      const x = await xKey.value;
      const y = await envelopGMXs.value;
      console.log("PID===>", PID.value);
      console.log("CID===>", CID.value);
      console.log("x===>", x);
      console.log("y===>", y);

      message = `${code}${PID.value}${CID.value}${x}${y}`;

      console.log("message===>", message);
    } else if (code === 5000) {
      const T = await tKey.value;

      console.log("T===>", T);
      console.log("officeCode===>", officeCode.value);
      console.log("versionCode===>", versionCode.value);
      console.log("serviceCode===>", serviceCode);
      console.log("idcard===>", idcard);

      message = `${code}${T}${officeCode.value}${versionCode.value}${serviceCode}${idcard}`;

      console.log("message===>", message);
    }

    await fetch(`${apiURL.value}/ami/request`, {
      method: "POST",
      headers: { "Content-type": "application/json; charset=UTF-8" },
      body: JSON.stringify({
        message: message,
      }),
    })
      .then(async (response) => {
        if (response.ok) {
          return response.json();
        }
        throw new Error("Something went wrong");
      })
      .then(async (data) => {
        const convertData = bin2String(await data);
        let removeText = await convertData.substr(9); // ตัด CODEREQ[4] + Status[5]

        if (code === 9080) {
          xKey.value = await removeText;

          console.log("xKey===>", xKey.value);

          step.value = 3;
        } else if (code === 9081) {
          tKey.value = removeText;

          console.log("tKey===>", tKey.value);

          step.value = 4;
        } else if (code === 5000) {
          return removeText;
        }
      })
      .catch(async (error) => {
        messageErrorLinkage(q, error);
        hideLoader();
      });
  }

  async function disconnect(q: any) {
    await fetch(`${apiURL.value}/smart-card/disconnect`, {
      method: "GET",
    })
      .then((response) => {
        if (response.ok) {
          return response.json();
        }
        throw new Error("Something went wrong");
      })
      .then((data) => {
        devices.value = "";
        devicesData.value = [];
        devicesOp.value = [];
        step.value = 1;
        PID.value = "";
        CID.value = "";
        xKey.value = "";
        envelopGMXs.value = "";
        tKey.value = "";
        success(q, "disconnect successful.");
      })
      .catch((error) => {
        messageErrorLinkage(q, error);
      });
  }

  /**
   * แปลง byte เป็น string
   * @param {Array} array ข้อความที่แปลงเป็น byte
   * @returns {string} ข้อความที่แปลงเป็น string
   */
  function bin2String(array: number[]) {
    // Creating new byte array using
    // Uint8Array instance
    let byteArray = new Uint8Array(array);

    // Creating textDecoder instance
    let decoder = new TextDecoder("utf-8");

    // Using decode method to get string output
    let str = decoder.decode(byteArray);

    return str;
    // return String.fromCharCode.apply(String, array);
  }

  /**
   * แปลง text ascii เป็น hexa
   * @param str
   * @returns
   */
  function ascii_to_hexa(str: string) {
    var arr1 = [];
    for (var n = 0, l = str.length; n < l; n++) {
      var hex = Number(str.charCodeAt(n)).toString(16);

      arr1.push(hex);
    }
    return arr1.join("");
  }

  return {
    devicesData,
    devices,
    devicesOp,
    step,
    CID,
    PID,
    tKey,

    fetchDeviceLists,
    readDevice,
    getInfo,
    postReadIdCard,
    amiEnvironment,
    amiConnect,

    authentication,
    verifyPin,

    amiRequest,

    disconnect,
  };
});
