import { Base64 } from "js-base64";
import { positionTransform } from "./mt4";
import { alert } from "@/helper/message";

export const asyncTimeout = (mis: number = 0) => new Promise(resolve => setTimeout(resolve, mis))

export const dateFormat = (date: Date, fmt: string) => {
  var o: any = {
    "M+": date.getMonth() + 1, //月份
    "d+": date.getDate(), //日
    "h+": date.getHours(), //小时
    "m+": date.getMinutes(), //分
    "s+": date.getSeconds(), //秒
    "q+": Math.floor((date.getMonth() + 3) / 3), //季度
    S: date.getMilliseconds(), //毫秒
  };
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(
      RegExp.$1,
      (date.getFullYear() + "").substr(4 - RegExp.$1.length)
    );
  }
  for (var k in o) {
    if (new RegExp("(" + k + ")").test(fmt)) {
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
      );
    }
  }
  return fmt;
};

export const copyText = (text: string) => {
  const input = document.createElement("input");
  document.body.appendChild(input);

  input.setAttribute("value", text);
  input.select();

  document.execCommand("copy");

  document.body.removeChild(input);
};

// 防抖
export const debounce = <T extends (...args: any) => any>(
  fn: T,
  delay: number = 160
) => {
  let timeout: any;

  return function <This>(this: This, ...args: Parameters<T>) {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
};
export const throttle = <Args extends any[]>(
  fn: (...args: Args) => void,
  deley: number
) => {
  let valib = false;
  let lastCtx: { self: any; args: Args } | null = null;

  return function (this: any, ...args: Args) {
    lastCtx = {
      args,
      self: this,
    };
    if (valib) {
      return;
    }
    const currentCtx = lastCtx;
    valib = true;

    setTimeout(() => {
      fn.apply(currentCtx.self, currentCtx.args);
      valib = false;
    }, deley);
  };
};

function randomWord(randomFlag: boolean, min: number, max?: number) {
  let str = "";
  let range = min;
  const arr = [
    "0",
    "1",
    "2",
    "3",
    "4",
    "5",
    "6",
    "7",
    "8",
    "9",
    "a",
    "b",
    "c",
    "d",
    "e",
    "f",
    "g",
    "h",
    "i",
    "j",
    "k",
    "l",
    "m",
    "n",
    "o",
    "p",
    "q",
    "r",
    "s",
    "t",
    "u",
    "v",
    "w",
    "x",
    "y",
    "z",
    "A",
    "B",
    "C",
    "D",
    "E",
    "F",
    "G",
    "H",
    "I",
    "J",
    "K",
    "L",
    "M",
    "N",
    "O",
    "P",
    "Q",
    "R",
    "S",
    "T",
    "U",
    "V",
    "W",
    "X",
    "Y",
    "Z",
  ];
  // 随机产生
  if (randomFlag && max) {
    range = Math.round(Math.random() * (max - min)) + min;
  }
  for (let i = 0; i < range; i++) {
    const pos = Math.round(Math.random() * (arr.length - 1));
    str += arr[pos];
  }
  return str;
}

/**
 * 密码加密
 * @param {String} pwd
 */
export function encodePwd(str: string, strv: string): string[];
export function encodePwd(str: string): string;
export function encodePwd(str: string, strv = "") {
  str = Base64.encode(str);
  const NUM = 2;
  const front = randomWord(false, 8);
  const middle = randomWord(false, 8);
  const end = randomWord(false, 8);

  const str1 = str.substring(0, NUM);
  const str2 = str.substring(NUM);

  if (strv) {
    const strv1 = strv.substring(0, NUM);
    const strv2 = strv.substring(NUM);
    return [
      front + str2 + middle + str1 + end,
      front + strv2 + middle + strv1 + end,
    ];
  }

  return front + str2 + middle + str1 + end;
}

/**
 *获取id
 */
export const guid = () => {
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
    let r = (Math.random() * 16) | 0,
      v = c == "x" ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
};

export const mix = (origin: any, clear = false, ...appends: any[]) => {
  if (clear) {
    for (const key in origin) {
      delete origin[key];
    }
  }

  for (const append of appends) {
    console.log(origin, append);
    for (const key in append) {
      origin[key] = append[key];
    }
  }
  return origin;
};
export const urlToBlob = async (url: string) => {

  try {
    const response = await fetch(url, { mode: 'no-cors' }); // 获取文件内容
    const blob = await response.blob(); // 转成 blob
    console.log('urlToBlob', blob);
    if(blob.type == 'text/html'){
      throw "暂未获取到平面图，请前往三维场景制作并保存";
      return
    }
    return blob;
  } catch (error) {
    // 请求出错，说明图片不存在
    alert("暂未获取到平面图，请前往三维场景制作并保存");
  }
}
export const base64ToBlob = (base64Data: string) => {
  let arr = base64Data.split(",");
  let matchs = arr[0].match(/:(.*?);/);
  if (!matchs) {
    return null;
  }

  let fileType = matchs[1];
  let bstr = atob(arr[1]),
    l = bstr.length,
    u8Arr = new Uint8Array(l);

  while (l--) {
    u8Arr[l] = bstr.charCodeAt(l);
  }
  return new Blob([u8Arr], {
    type: fileType,
  });
};

export const drawImage = (
  ctx: CanvasRenderingContext2D,
  bg_w: number,
  bg_h: number,
  imgPath: CanvasImageSource,
  imgWidth: number,
  imgHeight: number,
  x: number,
  y: number
) => {
  let dWidth = bg_w / imgWidth; // canvas与图片的宽度比例
  let dHeight = bg_h / imgHeight; // canvas与图片的高度比例
  if (
    (imgWidth > bg_w && imgHeight > bg_h) ||
    (imgWidth < bg_w && imgHeight < bg_h)
  ) {
    if (dWidth > dHeight) {
      ctx.drawImage(
        imgPath,
        0,
        (imgHeight - bg_h / dWidth) / 2,
        imgWidth,
        bg_h / dWidth,
        x,
        y,
        bg_w,
        bg_h
      );
    } else {
      ctx.drawImage(
        imgPath,
        (imgWidth - bg_w / dHeight) / 2,
        0,
        bg_w / dHeight,
        imgHeight,
        x,
        y,
        bg_w,
        bg_h
      );
    }
  } else {
    if (imgWidth < bg_w) {
      ctx.drawImage(
        imgPath,
        0,
        (imgHeight - bg_h / dWidth) / 2,
        imgWidth,
        bg_h / dWidth,
        x,
        y,
        bg_w,
        bg_h
      );
    } else {
      ctx.drawImage(
        imgPath,
        (imgWidth - bg_w / dHeight) / 2,
        0,
        bg_w / dHeight,
        imgHeight,
        x,
        y,
        bg_w,
        bg_h
      );
    }
  }
};

export const mixEnum = <T, K>(enum1: T, enum2: K): T | K => {
  return {
    ...enum1,
    ...enum2,
  };
};

/**
 * 解析 URL 中的所有参数，返回对象
 * @param {string} url 可选，不传默认取当前页面 url
 * @returns {object} 参数对象
 */
export const strToParams = (url = window.location.href) => {
  // 取出 ? 后面的参数部分
  const queryStr = url.split('?')[1] || ''
  if (!queryStr) return {}

  // 解析成键值对
  const params = {}
  new URLSearchParams(queryStr).forEach((val, key) => {
    params[key] = val
  })
  return params
}
export const getDomMatrix = (dom: HTMLElement) => {
  const str = getComputedStyle(dom, null).getPropertyValue("transform");
  const matrix2d = str
    .substring(7, str.length - 2)
    .split(", ")
    .map(Number);

  return [
    matrix2d[0],
    matrix2d[1],
    0,
    0,
    matrix2d[2],
    matrix2d[3],
    0,
    0,
    0,
    0,
    1,
    0,
    matrix2d[4] + dom.offsetWidth / 2,
    matrix2d[5] + dom.offsetHeight / 2,
    0,
    1,
  ];
};
export function copyTextToClipboard(input: string, { target = document.body }: Options = {}) {
  const element = document.createElement('textarea');
  const previouslyFocusedElement = document.activeElement;

  element.value = input;

  element.setAttribute('readonly', '');

  (element.style as any).contain = 'strict';
  element.style.position = 'absolute';
  element.style.left = '-9999px';
  element.style.fontSize = '12pt';

  const selection = document.getSelection();
  let originalRange;
  if (selection && selection.rangeCount > 0) {
    originalRange = selection.getRangeAt(0);
  }

  target.append(element);
  element.select();

  element.selectionStart = 0;
  element.selectionEnd = input.length;

  let isSuccess = false;
  try {
    isSuccess = document.execCommand('copy');
  } catch (e: any) {
    throw new Error(e);
  }

  element.remove();

  if (originalRange && selection) {
    selection.removeAllRanges();
    selection.addRange(originalRange);
  }

  if (previouslyFocusedElement) {
    (previouslyFocusedElement as HTMLElement).focus();
  }
  return isSuccess;
}
function getExtension (name) {
  if(!name) return
  return name.substring(name.lastIndexOf("."))
}
// 根据URL下载图片
export function downloadFile(url, name) {
  console.log("downloadFile", url, name)
    let image = new Image();
    image.setAttribute("crossOrigin", "anonymous");
    image.src = url;
    image.onload = () => {
        let canvas = document.createElement("canvas");
        canvas.width = image.width;
        canvas.height = image.height;
        let ctx = canvas.getContext("2d");
        ctx.drawImage(image, 0, 0, image.width, image.height);
        canvas.toBlob(blob => {
            let url = URL.createObjectURL(blob);
            let a = document.createElement("a");
            if(name) {
              a.download = name;
            }
            a.href = url;
            a.click();
            a.remove();
            // 用完释放URL对象
            URL.revokeObjectURL(url);
        });
    };
}
function openWindow(
  url: string,
  opt?: { target?: string; noopener?: boolean; noreferrer?: boolean },
) {
  const { target = '__blank', noopener = true, noreferrer = true } = opt || {};
  const feature: string[] = [];

  noopener && feature.push('noopener=yes');
  noreferrer && feature.push('noreferrer=yes');

  window.open(url, target, feature.join(','));
}
export function downloadByUrl({
  url,
  target = '_blank',
  fileName,
}: {
  url: string;
  target?: string;
  fileName?: string;
}): boolean {
  const isChrome = window.navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
  const isSafari = window.navigator.userAgent.toLowerCase().indexOf('safari') > -1;
  console.log("downloadFile", url, fileName)

  if (/(iP)/g.test(window.navigator.userAgent)) {
    console.error('Your browser does not support download!');
    return false;
  }
  if (isChrome || isSafari) {
    const link = document.createElement('a');
    link.href = url;
    link.target = target;
    let newfileName = fileName + getExtension(url);
    if (link.download !== undefined) {
      link.download = fileName ? newfileName : url.substring(url.lastIndexOf('/') + 1, url.length);
    }
    
    if (document.createEvent) {
      const e = document.createEvent('MouseEvents');
      e.initEvent('click', true, true);
      link.dispatchEvent(e);
      return true;
    }
  }
  if (url.indexOf('?') === -1) {
    url += '?download';
  }

  openWindow(url, { target });
  return true;
}
export const isImage = (url) => {
  return /\.(jpg|jpeg|png|gif|bmp)$/i.test(url);
};

export const recursiveSearch = (nodes) => {
    // 如果没有节点，直接返回
    if (!nodes || !nodes.length) return;
    
    // 遍历当前节点
    for (const node of nodes) {
      // 检查是否符合条件
      if (node.caseFilesList && node.caseFilesList.length > 0 && node.caseFilesList.some(file => file.filesUrl)) {
        // 如果只需要第一个，直接返回
            return true; // 终止递归
      }
      
      // 如果有子节点，递归查询
      if (node.childrenList && node.childrenList.length) {
        const found = recursiveSearch(node.childrenList);
        // 如果已经找到第一个，终止递归
        if(found){
          return true;
        }
      }
    }
    
    return false;
  }
  /**
 * 从 URL 中提取文件名
 * @param {string} url - 完整的 URL 地址
 * @returns {string} 提取到的文件名，无文件名时返回空字符串
 */
  export function getFileNameFromUrl(url) {
  try {
    // 1. 解析 URL，分离出路径部分（去除参数和锚点）
    const parsedUrl = new URL(url);
    let path = parsedUrl.pathname;

    // 2. 去除路径末尾的斜杠（如果有）
    path = path.replace(/\/$/, '');

    // 3. 提取最后一个斜杠后的部分（即文件名）
    const fileName = path.split('/').pop();

    // 4. 如果提取到的是目录名（无扩展名），返回空字符串
    return fileName.includes('.') ? fileName : '';
  } catch (error) {
    // 处理无效 URL 的情况
    console.error('URL 格式错误:', error);
    return '';
  }
}
