import { store } from "@/store/store";
import {
  execLocal,
  fileExists,
  nodeCheckRemoteDesktop,
} from "@/utils/nativeMethods";
import { getBlackAppConfig } from "@/utils/common";
import { watch } from "vue";

export function useRemoteAppChecker() {
  void getBlackAppConfig();
  /** 检测出错则提示；检测通过则将禁用登录按钮的flag置为false */
  async function checkRemoteAppTxt() {
    if (
      !QECSConfig.PREVENT_CHEATING_CONFIG.includes("DISABLE_REMOTE_ASSISTANCE")
    )
      return;

    let applicationNames;
    try {
      const fs: typeof import("fs") = window.nodeRequire("fs");
      try {
        applicationNames = fs.readFileSync("remoteApplication.txt", "utf-8");
      } catch (error) {
        logger({
          cnl: ["local", "server"],
          key: "checkRemoteAppTxt",
          pgu: "AUTO",
          dtl: "remoteApplication.txt出错--0",
          ejn: JSON.stringify(error),
        });
        await new Promise((resolve2) => setTimeout(resolve2, 3000));
        applicationNames = fs.readFileSync("remoteApplication.txt", "utf-8");
      }
    } catch (error) {
      logger({
        cnl: ["local", "server"],
        key: "checkRemoteAppTxt",
        pgu: "AUTO",
        stk: error instanceof Error ? error.message : JSON.stringify(error),
        dtl: "读取remoteApplication.txt出错",
        ext: { errorType: "e-01", applicationNames },
      });
      $message.error("请关闭远程控制程序后重试", {
        duration: 24 * 60 * 60 * 1000,
      });
      disableLoginBtnBecauseRemoteApp = true;
      return;
    }

    try {
      const { hasSun, hasTodesk } = nodeCheckRemoteDesktop();
      if (hasSun) {
        applicationNames = (applicationNames ? "" : ",") + "sunloginclient";
      }
      if (hasTodesk) {
        applicationNames = (applicationNames ? "" : ",") + "todesk";
      }
    } catch (error) {
      logger({
        cnl: ["local", "server"],
        key: "nodeCheckRemoteDesktop",
        pgu: "AUTO",
        stk: error instanceof Error ? error.message : JSON.stringify(error),
        dtl: "读取tasklist出错",
        ext: { errorType: "e-01", applicationNames },
      });
      // 旧版没报错，这里也别报错了
      // $message.error("系统检测出错(e-01)，请退出程序后重试！", {
      //   duration: 24 * 60 * 60 * 1000,
      // });
      // return;
    }
    if (!applicationNames?.trim()) {
      disableLoginBtnBecauseRemoteApp = false;
    } else {
      let names = applicationNames
        .replace("qq", "QQ")
        .replace("teamviewer", "TeamViewer")
        .replace("lookmypc", "LookMyPC")
        .replace("xt", "协通")
        .replace("winaw32", "Symantec PCAnywhere")
        .replace("pcaquickconnect", "Symantec PCAnywhere")
        .replace("sessioncontroller", "Symantec PCAnywhere")
        .replace(/sunloginclient/gi, "向日葵")
        .replace(/sunloginremote/gi, "向日葵")
        .replace(/选择免安装运行，截图识别/gi, "向日葵")
        .replace("wemeetapp", "腾讯会议")
        .replace("wechat", "微信");

      names = [...new Set(names.split(",").map((v) => v.trim()))].join("，");
      $message.info(
        () => (
          <div class="enhanced-error-message">
            在考试期间，请关掉{names}软件，诚信考试。
          </div>
        ),
        {
          duration: 24 * 60 * 60 * 1000,
        }
      );
      logger({
        cnl: ["local", "server"],
        key: "checkRemoteAppTxt",
        pgu: "AUTO",
        dtl: "在考试期间，请关掉" + names + "软件，诚信考试。",
      });
    }
  }

  let disableLoginBtnBecauseRemoteApp = $ref(true);

  const QECSConfig = $computed(() => store.QECSConfig);
  watch(
    () => QECSConfig.PREVENT_CHEATING_CONFIG,
    async (val, oldVal) => {
      // 由于在刷新时，会重新从sessionStorage里面获取值并设置QECSConfig，
      // 同时，还通过网络获取，所以此时的监听会发生两次，两次可能导致 remoteApplication.txt 被删除后读取不到
      // 所以此时发现值一样就不要进行后续
      if (JSON.stringify(val) === JSON.stringify(oldVal)) return;
      if (import.meta.env.DEV) {
        disableLoginBtnBecauseRemoteApp = false;
        return;
      }
      if (
        !QECSConfig.PREVENT_CHEATING_CONFIG?.includes(
          "DISABLE_REMOTE_ASSISTANCE"
        )
      ) {
        disableLoginBtnBecauseRemoteApp = false;
        return;
      }

      let exe = "Project1.exe";
      try {
        if (fileExists("Project2.exe")) {
          const { remoteApp: remoteAppName } = await getBlackAppConfig();
          exe = `Project2.exe "${remoteAppName}" `;
        }

        const fs: typeof import("fs") = window.nodeRequire("fs");
        fileExists("remoteApplication.txt") &&
          fs.unlinkSync("remoteApplication.txt");
      } catch (error) {
        console.log(error);
        logger({
          cnl: ["local", "server"],
          pgu: "AUTO",
          key: "checkRemoteAppTxt",
          dtl: "unlink remoteApplication.txt 失败",
          possibleError: error,
        });
        $message.error("请关闭远程控制程序后重试", {
          duration: 24 * 60 * 60 * 1000,
        });
        throw error;
      }
      await execLocal(exe);

      await checkRemoteAppTxt();
    },
    { immediate: true }
  );

  return {
    disableLoginBtnBecauseRemoteApp: $$(disableLoginBtnBecauseRemoteApp),
    checkRemoteAppTxt,
  };
}
