import { request } from "@cqsjjb/jjb-common-lib/http.js";
import dayjs from "dayjs";
import { ID_NUMBER } from "../regular";

/**
 * 计算序号
 */
export function serialNumber(pagination, index) {
  return (pagination.current - 1) * pagination.pageSize + (index + 1);
}

/**
 * 字符串数组转数组
 */
export function toArrayString(value) {
  // eslint-disable-next-line no-eval
  return value ? eval(value).map(String) : [];
}

/**
 * 判断文件后缀名是否符合
 */
export function interceptTheSuffix(name, suffix) {
  return name.substring(name.lastIndexOf("."), name.length).toLowerCase() === suffix.toLowerCase();
}

/**
 * 图片转base64
 */
export function image2Base64(imgUrl) {
  return new Promise((resolve) => {
    const img = new Image();
    img.src = imgUrl;
    img.crossOrigin = "Anonymous";
    img.onload = function () {
      const canvas = document.createElement("canvas");
      canvas.width = img.width;
      canvas.height = img.height;
      const ctx = canvas.getContext("2d");
      ctx.drawImage(img, 0, 0, img.width, img.height);
      const ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase();
      resolve(canvas.toDataURL(`image/${ext}`));
    };
  });
}

/**
 图片转base64 (File对象版本)
 */
export function image2Base642(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = (e) => {
      resolve(e.target.result);
    };
    reader.onerror = (error) => {
      reject(error);
    };
  });
}

/**
 base64转File对象
 */
export function base642File(base64, filename = "file") {
  const arr = base64.split(",");
  const mime = arr[0].match(/:(.*?);/)[1];
  const ext = mime.split("/")[1];
  const bstr = atob(arr[1]);
  let n = bstr.length;
  const u8arr = new Uint8Array(n);

  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }

  return new File([u8arr], `${filename}.${ext}`, { type: mime });
}

/**
 * 判断图片是否可访问成功
 */
export function checkImgExists(imgUrl) {
  return new Promise((resolve, reject) => {
    const ImgObj = new Image();
    ImgObj.src = imgUrl;
    ImgObj.onload = function (res) {
      resolve(res);
    };
    ImgObj.onerror = function (err) {
      reject(err);
    };
  });
}

/**
 * 获取数据类型
 */
export function getDataType(data) {
  return Object.prototype.toString.call(data).slice(8, -1);
}

/**
 * 数组去重
 */
export function ArrayDeduplication(arr) {
  return [...new Set(arr)];
}

/**
 * 数组对象去重
 */
export function arrayObjectDeduplication(arr, key) {
  const obj = {};
  arr = arr.reduce((previousValue, currentValue) => {
    if (!obj[currentValue[key]]) {
      obj[currentValue[key]] = true;
      previousValue.push(currentValue);
    }
    return previousValue;
  }, []);
  return arr;
}

/**
 * 查找字符串中指定的值第几次出现的位置
 */
export function findCharIndex(options) {
  const { str, char, num } = options;
  let index = str.indexOf(char);
  if (index === -1)
    return -1;
  for (let i = 0; i < num - 1; i++) {
    index = str.indexOf(char, index + 1);
    if (index === -1)
      return -1;
  }
  return index;
}

/**
 * 生成指定两个值之间的随机数
 */
export function randoms(min, max) {
  return Math.random() * (max - min + 1) + min;
}

/**
 * 千位分隔符
 */
export function numFormat(num) {
  if (num) {
    const numArr = num.toString().split(".");
    const arr = numArr[0].split("").reverse();
    let res = [];
    for (let i = 0; i < arr.length; i++) {
      if (i % 3 === 0 && i !== 0)
        res.push(",");
      res.push(arr[i]);
    }
    res.reverse();
    if (numArr[1])
      res = res.join("").concat(`.${numArr[1]}`);
    else
      res = res.join("");
    return res;
  }
}

/**
 * 验证是否为空
 */
export function isEmpty(value) {
  return (
    value === undefined
    || value === null
    || (typeof value === "object" && Object.keys(value).length === 0)
    || (typeof value === "string" && value.trim().length === 0)
  );
}

/**
 * 获取url参数
 */
export function getUrlParam(key) {
  const reg = new RegExp(`(^|&)${key}=([^&]*)(&|$)`);
  const r = window.location.search.substr(1).match(reg);
  if (r != null)
    return decodeURI(r[2]);
  return "";
}

/**
 * 数据分页
 */
export function paging(options) {
  const { list, currentPage, pageSize } = options;
  return list.filter((item, index) => index < +currentPage * +pageSize && index >= (+currentPage - 1) * +pageSize);
}

/**
 * 获取文件后缀
 */
export function getFileSuffix(name) {
  return name.substring(name.lastIndexOf(".") + 1);
}

/**
 * 获取文件名称
 */
export function getFileName(name) {
  if (!name)
    return "";
  return name.substring(name.lastIndexOf("/") + 1);
}

/**
 * 读取txt文档
 */
export function readTxtDocument(filePah) {
  return new Promise((resolve) => {
    const FILE_URL = getFileUrl();
    const file_url = FILE_URL + filePah;
    const xhr = new XMLHttpRequest();
    xhr.open("get", file_url, true);
    xhr.responseType = "blob";
    xhr.onload = function (event) {
      const reader = new FileReader();
      reader.readAsText(event.target.response, "GB2312");
      reader.onload = function () {
        resolve(reader.result);
      };
    };
    xhr.send();
  });
}

/**
 * 将秒转换成时分秒
 */
export function secondConversion(second) {
  if (!second)
    return 0;
  const h = Number.parseInt((second / 60 / 60).toString(), 10);
  const m = Number.parseInt(((second / 60) % 60).toString(), 10);
  const s = Number.parseInt((second % 60).toString(), 10);
  if (h) {
    return `${h}小时${m}分钟${s}秒`;
  }
  else {
    if (m)
      return `${m}分钟${s}秒`;
    else
      return `${s}秒`;
  }
}

/**
 * 附件添加前缀
 */
export function addingPrefixToFile(list, options = {}) {
  if (!list)
    return [];
  const { pathKey = "filePath", nameKey = "fileName", idKey = "id" } = options;
  const FILE_URL = getFileUrl();
  return list.filter(item => item[pathKey]).map(item => ({
    url: FILE_URL + item[pathKey],
    name: item[nameKey] || getFileName(item[pathKey]),
    id: item[idKey],
    ...item,
  }));
}

/**
 * 翻译状态
 */
export function getLabelName(options) {
  const { status, list, idKey = "bianma", nameKey = "name" } = options;
  const item = list.find(item => item[idKey]?.toString() === status?.toString()) || { [nameKey]: "" };
  return item[nameKey];
}

/**
 * 计算文件大小
 */
export function calculateFileSize(size) {
  return size > 1024 ? `${(`${size / 1024}`).substring(0, (`${size / 1024}`).lastIndexOf(".") + 3)}MB` : `${size}KB`;
}

/**
 * 根据身份证号获取出生日期和性别
 */
export function idCardGetDateAndGender(idCard) {
  let sex = "";
  let date = "";
  if (ID_NUMBER.test(idCard)) {
    const org_birthday = idCard.substring(6, 14);
    const org_gender = idCard.substring(16, 17);
    const birthday = `${org_birthday.substring(0, 4)}-${org_birthday.substring(4, 6)}-${org_birthday.substring(6, 8)}`;
    const birthdays = new Date(birthday.replace(/-/g, "/"));
    const Month = birthdays.getMonth() + 1;
    let MonthDate;
    const DayDate = birthdays.getDate();
    let Day;
    if (Month < 10)
      MonthDate = `0${Month}`;
    else MonthDate = Month;
    if (DayDate < 10)
      Day = `0${DayDate}`;
    else Day = DayDate;
    sex = org_gender % 2 === 1 ? "1" : "0";
    date = `${birthdays.getFullYear()}-${MonthDate}-${Day}`;
  }
  return { sex, date };
}

/**
 * 获取匹配项
 */
export function getMatchedItems(options) {
  const { list, value, idKey = "bianma" } = options;
  return list.filter(item => value.includes(item[idKey]));
}

/**
 * 获取未匹配项
 */
export function getUnmatchedItems(options) {
  const { list, value, idKey = "bianma" } = options;
  return list.filter(item => !value.includes(item[idKey]));
}

/**
 * json转换为树形结构
 */
export function listTransTree(options) {
  const { json, idKey, parentIdKey, childrenKey } = options;
  const r = [];
  const hash = {};
  let i = 0;
  let j = 0;
  const len = json.length;
  for (; i < len; i++) {
    hash[json[i][idKey]] = json[i];
  }
  for (; j < len; j++) {
    const aVal = json[j];
    const hashVP = hash[aVal[parentIdKey]];
    if (hashVP) {
      !hashVP[childrenKey] && (hashVP[childrenKey] = []);
      hashVP[childrenKey].push(aVal);
    }
    else {
      r.push(aVal);
    }
  }
  return r;
}

/**
 * 将值转换为"是"/"否"显示文本
 */
export function isEmptyToWhether(value, options = {}) {
  const { yesText = "是", noText = "否", yesValue = "1" } = options;
  return !isEmpty(value) ? (value.toString() === yesValue.toString() ? yesText : noText) : "";
}

/**
 * 生成指定长度的guid
 */
export function createGuid(len = 32) {
  const chars = "abcdefghijklmnopqrstuvwxyz0123456789";
  let result = "";
  for (let i = 0; i < len; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return result;
}

/**
 * 获取序号列
 */
export function getIndexColumn(pagination) {
  return {
    title: "序号",
    key: "index",
    width: 70,
    render: (_, __, index) => pagination === false ? index + 1 : serialNumber(pagination, index),
  };
}

/**
 * 获取树形节点路径
 */
export function getTreeNodePaths(options) {
  const { data, targetId, idKey, childrenKey, path = [], isIncludeOneself } = options;
  for (let i = 0; i < data.length; i++) {
    const node = data[i];
    const newPath = [...path, node];

    // 找到目标节点，根据isIncludeOneself决定是否包含自身
    if (node[idKey] === targetId) {
      if (isIncludeOneself)
        return newPath; // 包含自身
      else
        return path; // 不包含自身，只返回父节点路径
    }

    // 递归查找子节点
    if (node[childrenKey] && node[childrenKey].length > 0) {
      const result = getTreeNodePaths({
        data: node[childrenKey],
        targetId,
        idKey,
        childrenKey,
        path: newPath,
        isIncludeOneself,
      });
      if (result)
        return result;
    }
  }

  return null;
}

/**
 * 根据 level 属性处理树数据，添加 isLeaf 属性控制节点是否可展开
 */
export function processTreeDataByLevel(options) {
  const { data, level, childrenKey, currentLevel = 1 } = options;
  return data.map((item) => {
    const processedItem = { ...item };

    // 如果指定了 level 且当前层级达到指定层级，则标记为叶子节点
    if (level && currentLevel >= level) {
      processedItem.isLeaf = true;
      // 移除子节点
      delete processedItem[childrenKey];
    }
    else if (item[childrenKey] && item[childrenKey].length > 0) {
      // 未达到指定层级，继续处理子节点
      processedItem[childrenKey] = processTreeDataByLevel({
        data: item[childrenKey],
        currentLevel: currentLevel + 1,
        level,
        childrenKey,
      });
    }
    else {
      // 没有子节点，标记为叶子节点
      processedItem.isLeaf = true;
    }

    return processedItem;
  });
}

/**
 * 根据 onlyLastLevel 属性处理树数据，添加 selectable 属性控制节点是否可选择
 */
export function processTreeDataForOnlyLastLevel(options) {
  const { data, childrenKey, onlyLastLevel = false } = options;
  if (!onlyLastLevel)
    return data;

  return data.map((item) => {
    // 检查是否有子节点
    const hasChildren = item[childrenKey] && item[childrenKey].length > 0;

    // 如果有子节点，则不可选择
    const processedItem = {
      ...item,
      selectable: !hasChildren,
    };

    // 递归处理子节点
    if (hasChildren)
      processedItem[childrenKey] = processTreeDataForOnlyLastLevel({ data: item[childrenKey], childrenKey, onlyLastLevel });

    return processedItem;
  });
}

/**
 * 验证结束时间是否大于开始时间
 */
export function validatorEndTime(options) {
  let { startTime, message = "结束时间不能早于开始时间", type = "" } = options || {};

  return {
    validator: (_, value) => {
      if (!value || !startTime)
        return Promise.resolve();

      if (!type) {
        const dateOnlyRegex = /^\d{4}-\d{2}-\d{2}$/;
        const dateTimeRegex = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
        if (dateOnlyRegex.test(startTime))
          type = "date";
        else if (dateTimeRegex.test(startTime))
          type = "datetime";
      }

      const selectedDate = dayjs.isDayjs(value) ? value : dayjs(value);

      if (selectedDate.isBefore(dayjs(startTime), type === "date" ? "day" : "seconds"))
        return Promise.reject(message);
      else
        return Promise.resolve();
    },
  };
}

/**
 * 验证时间是否大于当前时间
 */
export function validatorTimeGTCurrentDay(options) {
  const { message = "需要大于当前时间", type = "date" } = options || {};
  return {
    validator: (_, value) => {
      if (!value)
        return Promise.resolve();

      const selectedDate = dayjs.isDayjs(value) ? value : dayjs(value);
      const now = dayjs();
      const isAfter = type === "date"
        ? selectedDate.isAfter(now, "day")
        : selectedDate.isAfter(now, "seconds");

      if (!isAfter)
        return Promise.reject(message);
      else
        return Promise.resolve();
    },
  };
}
/**
 * 验证时间是否大于等于当前时间
 */
export function validatorTimeGECurrentDay(options) {
  const { message = "需要大于等于当前时间", type = "date" } = options || {};
  return {
    validator: (_, value) => {
      if (!value)
        return Promise.resolve();

      const selectedDate = dayjs.isDayjs(value) ? value : dayjs(value);
      const now = dayjs();
      const isBefore = type === "date"
        ? selectedDate.isBefore(now, "day")
        : selectedDate.isBefore(now, "seconds");

      if (isBefore)
        return Promise.reject(message);
      else
        return Promise.resolve();
    },
  };
}

/**
 * 动态加载js资源
 */
export function dynamicLoadJs(url) {
  return new Promise((resolve, reject) => {
    const script = document.createElement("script");
    script.type = "text/javascript";
    script.src = url;
    script.onload = resolve;
    script.onerror = reject;
    document.body.appendChild(script);
  });
}

/**
 * 动态加载css资源
 */
export function dynamicLoadCss(url) {
  return new Promise((resolve, reject) => {
    const link = document.createElement("link");
    link.rel = "stylesheet";
    link.type = "text/css";
    link.href = url;
    link.onload = resolve;
    link.onerror = reject;
    document.head.appendChild(link);
  });
}

/**
 * 是否空html，用于给富文本编辑器使用
 */
export function normalizeEmptyHtml(html) {
  if (!html)
    return "";
  const cleaned = html.replace(/\s+/g, "").toLowerCase();
  return cleaned === "<p><br></p>" || cleaned === "<p></p>" || cleaned === "" ? "" : html;
}

/**
 * 获取文件url
 */
export function getFileUrl() {
  return window.fileUrl || process.env.app["fileUrl"];
}

/**
 * 获取基础接口放在哪个gateway服务下
 */
export function getBaseGateway() {
  return window.baseGateway || "basicInfo";
}

/**
 * 从服务器获取文件url
 */
export async function getFileUrlFromServer() {
  if (window.fileUrl)
    return;
  const { data } = await request(`/${getBaseGateway()}/imgFiles/getImagePath`, "get");
  window.fileUrl = data;
}

// 全局请求缓存
const requestCacheMap = new Map();

/**
 * 带缓存的请求执行函数
 * @param {string | object} cacheKey - 缓存键
 * @param {Function} requestFn - 请求函数，返回 Promise
 * @param {Function} setData - 设置数据的回调
 * @returns {Promise} 请求结果
 */
export async function executeWithCache(cacheKey, requestFn, setData) {
  // 清空旧数据
  setData([]);

  // 生成缓存键
  const key = typeof cacheKey === "string" ? cacheKey : JSON.stringify(cacheKey);

  // 检查缓存，如果存在直接返回缓存结果
  if (requestCacheMap.has(key)) {
    setData(requestCacheMap.get(key));
    return requestCacheMap.get(key);
  }

  // 执行请求
  const result = await requestFn();

  // 存入缓存
  requestCacheMap.set(key, result);

  setData(result);
  return result;
}
