import type { DictItem, ListItem } from '@/api/dict/types';
import { find } from 'lodash-es';
import { VNode } from 'vue';

/**
 *
 * @param component 需要注册的组件
 * @param alias 组件别名
 * @returns any
 */
export const withInstall = <T>(component: T, alias?: string) => {
  const comp = component as any;
  comp.install = (app: any) => {
    app.component(comp.name || comp.displayName, component);
    if (alias) {
      app.config.globalProperties[alias] = component;
    }
  };
  return component as T & Plugin;
};

/**
 * @param str 需要转下划线的驼峰字符串
 * @returns 字符串下划线
 */
export const humpToUnderline = (str: string): string => {
  return str
    .replace(/([A-Z])/g, '-$1')
    .replace(/(\d)/, '-$1')
    .toLowerCase();
};

/**
 * @param str 需要转驼峰的下划线字符串
 * @returns 字符串驼峰
 */
export const underlineToHump = (str: string): string => {
  if (!str) return '';
  return str.replace(/\-(\w)/g, (_, letter: string) => {
    return letter.toUpperCase();
  });
};

/**
 * 驼峰转横杠
 */
export const humpToDash = (str: string): string => {
  return str.replace(/([A-Z])/g, '-$1').toLowerCase();
};

export const setCssVar = (prop: string, val: any, dom = document.documentElement) => {
  dom.style.setProperty(prop, val);
};

/**
 * 查找数组对象的某个下标
 * @param {Array} ary 查找的数组
 * @param {Functon} fn 判断的方法
 */
// eslint-disable-next-line
export const findIndex = <T = Recordable>(ary: Array<T>, fn: Fn): number => {
  if (ary.findIndex) {
    return ary.findIndex(fn);
  }
  let index = -1;
  ary.some((item: T, i: number, ary: Array<T>) => {
    const ret: T = fn(item, i, ary);
    if (ret) {
      index = i;
      return ret;
    }
  });
  return index;
};

export const trim = (str: string) => {
  return str.replace(/(^\s*)|(\s*$)/g, '');
};

/**
 * @param {Date | number | string} time 需要转换的时间
 * @param {String} fmt 需要转换的格式 如 yyyy-MM-dd、yyyy-MM-dd HH:mm:ss
 */
export function formatTime(time: Date | number | string, fmt: string) {
  if (!time) return '';
  else {
    const date = new Date(time);
    const o = {
      '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 (const 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 function toAnyString() {
  const str: string = 'xxxxx-xxxxx-4xxxx-yxxxx-xxxxx'.replace(/[xy]/g, (c: string) => {
    const r: number = (Math.random() * 16) | 0;
    const v: number = c === 'x' ? r : (r & 0x3) | 0x8;
    return v.toString();
  });
  return str;
}

/**
 * 首字母大写
 */
export function firstUpperCase(str: string) {
  return str.toLowerCase().replace(/( |^)[a-z]/g, L => L.toUpperCase());
}

/**
 * 字段列表下拉项列表
 */
export function transfDictList(list: DictItem[]): ListItem[] {
  return list.map((item: DictItem) => {
    return {
      label: item.dictName,
      value: item.dictld,
    };
  });
}

/**
 * 获取字典项名称
 */
export function findDictLabel(list: DictItem[], val: string) {
  const item = find(list, { dictld: val });
  return item ? item.dictName : '';
}

/**
 * 获取字典项名称
 */
export function findDictValue(list: DictItem[], val: string) {
  console.log(list, val);
  const item = find(list, { dictName: val });
  return item ? item.dictld : '';
}

/**
 * 获取列表项名称
 */
export function findListLabel(list: ListItem[], val: string) {
  const item = find(list, { value: val });
  return item ? item.label : '';
}

export function getExportTitle(tableColumns) {
  const filterField = ['selection', 'index', 'action'];
  const title = tableColumns
    .map(item => {
      return !filterField.includes(item.field)
        ? {
            attrName: item.field,
            titleName: item.label,
          }
        : null;
    })
    .filter(item => item);
  return title;
}

/**
 * 随机序列
 * @param {Number} n 序列数量
 * @returns {string} 返回序列
 */
export function randomCode(n: number) {
  if (n > 0) {
    const data = [
      '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',
    ];
    let nums = '';
    for (let i = 0; i < n; i++) {
      const r = parseInt((Math.random() * 61).toString());
      nums += data[r];
    }
    return nums;
  } else {
    return '';
  }
}

export const getWidth = (name: string | VNode<{}>) => {
  if (typeof name === 'string') {
    const len = name.length;
    if (len > 0) {
      return 80 + (len - 2) * 20;
    }
    return 100;
  }
  return 100;
};

/**
 * 获取url中的参数值
 * @param {String} variable 参数名
 * @param {String} url 检索的URL,非必须
 */
export function getQueryVariable(variable, url?) {
  if (!url) {
      url = location.href;
  }
  if (url.indexOf('?') == -1) {
      return;
  }
  const query = url.split('?')[1];
  const vars = query.split('&');
  for (let i = 0; i < vars.length; i++) {
      const pair = vars[i].split('=');
      if (pair[0] == variable) {
          return pair[1];
      }
  }
}
