import cryptoJs from 'crypto-js'
import { Base64 } from 'js-base64'
import { isObject } from './validate'

const encryptKey = '1q2w3e4r5t6y7u8i'
const encryptIv = '1234567812345678'

export const encryptByAES = (value: string): string => {
  if (value === '') return ''
  const encryptValue = cryptoJs.enc.Utf8.parse(value)
  const keyHex = cryptoJs.enc.Utf8.parse(encryptKey)
  const ivHex = cryptoJs.enc.Utf8.parse(encryptIv)
  const encrypted = cryptoJs.AES.encrypt(encryptValue, keyHex, {
    iv: ivHex,
    mode: cryptoJs.mode.CBC,
    padding: cryptoJs.pad.Pkcs7
  })
  return encrypted.toString()
}

export const decryptByAES = (value: string): string => {
  if (value === '') return ''
  const keyHex = cryptoJs.enc.Utf8.parse(encryptKey)
  const ivHex = cryptoJs.enc.Utf8.parse(encryptIv)
  const decrypted = cryptoJs.AES.decrypt(value, keyHex, {
    iv: ivHex,
    mode: cryptoJs.mode.CBC,
    padding: cryptoJs.pad.Pkcs7
  })
  return decrypted.toString(cryptoJs.enc.Utf8)
}

export const encryptByBase64 = (value: string): string => {
  if (value === '') return ''
  return Base64.encode(value)
}

export const encryptByMd5 = (value: string): string => {
  if (value === '') return ''
  return cryptoJs.MD5(value).toString()
}

export const uuid = (): string => {
  const s: string[] = []
  const hexDigits = '0123456789abcdef'
  for (let i = 0; i < 36; i++) {
    const startPos = Math.floor(Math.random() * 0x10)
    s[i] = hexDigits.substring(startPos, startPos + 1)
  }
  s[14] = '4'
  const startPos = (parseInt(s[19], 16) & 0x3) | 0x8
  s[19] = hexDigits.substring(startPos, startPos + 1)
  s[8] = s[13] = s[18] = s[23] = '-'
  return s.join('')
}

export const sortByKey = (obj: Record<string, any>): Record<string, any> => {
  if (isObject(obj)) {
    const keySortArr = Object.keys(obj).sort()
    const sortObj: Record<string, any> = {}
    for (const i of keySortArr) {
      sortObj[i] = obj[i]
    }
    return sortObj
  }
  return obj
}

export const randomLenNum = (len: number, date?: boolean): string => {
  if (len <= 0) len = 4
  if (len > 16) len = 16
  let random = Math.ceil(Math.random() * 100000000000000)
    .toString()
    .substring(0, len || 4)
  if (date) random = random + Date.now()
  return random
}

export interface RouterItem {
  path: string
  name?: string
  meta?: Record<string, any>
  children?: RouterItem[]
  [key: string]: any
}

export const getRouter = (routers: RouterItem[], path: string): RouterItem | undefined => {
  let router: RouterItem | undefined
  routers.forEach((item) => {
    if (path === item.path) {
      router = item
    }
    if (item.children) {
      const data = getRouter(item.children, path)
      if (data !== undefined) router = data
    }
  })
  return router
}

export function parseTime(time: any, pattern?: string): string | null {
  if (arguments.length === 0 || !time) return null
  const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
  let date: Date
  if (typeof time === 'object') {
    date = time
  } else {
    let val = time
    if (typeof val === 'string' && /^[0-9]+$/.test(val)) {
      val = parseInt(val)
    } else if (typeof val === 'string') {
      val = val.replace(/-/gm, '/').replace('T', ' ').replace(/\.\d{3}/gm, '')
    }
    if (typeof val === 'number' && val.toString().length === 10) {
      val = val * 1000
    }
    date = new Date(val)
  }
  const formatObj: Record<string, number> = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  return format.replace(/{([ymdhisa])+}/g, (result, key) => {
    let value: string | number = formatObj[key]
    if (key === 'a') return ['日', '一', '二', '三', '四', '五', '六'][value]
    if (result.length > 0 && (value as number) < 10) value = '0' + value
    return String(value || 0)
  })
}
