import { Base64 } from "js-base64";
import { positionTransform } from "./mt4";

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 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,
  };
};

// 字符串转params对象
export const strToParams = (str: string) => {
  if (str[0] === "?") {
    str = str.substr(1);
  }

  const result: { [key: string]: string } = {};
  const splitRG = /([^=&]+)(?:=([^&]*))?&?/;

  let rgRet;
  while ((rgRet = str.match(splitRG))) {
    result[rgRet[1]] = rgRet[2] === undefined ? "" : rgRet[2];
    str = str.substr(rgRet[0].length);
  }

  return result;
};

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,
  ];
};
