export function isUsername(username: string): boolean {
  return /^[A-Za-z_\-一-龥]{1}[A-Za-z0-9_\-.一-龥]{4,19}$/.test(username)
}

export function isMobile(mobile: string): boolean {
  return /^(1)\d{10}$/.test(mobile)
}

export function isEmail(email: string): boolean {
  return /^\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}$/.test(email)
}

export function isURL(str: string): boolean {
  return /^http[s]?:\/\/.*/.test(str)
}

export function isIdCard(idCard: string): boolean {
  const checkProv = (val: string): boolean => {
    const pattern = /^[1-9][0-9]/
    const provs: Record<string, string> = {
      '11': '北京', '12': '天津', '13': '河北', '14': '山西', '15': '内蒙古',
      '21': '辽宁', '22': '吉林', '23': '黑龙江', '31': '上海', '32': '江苏',
      '33': '浙江', '34': '安徽', '35': '福建', '36': '江西', '37': '山东',
      '41': '河南', '42': '湖北', '43': '湖南', '44': '广东', '45': '广西',
      '46': '海南', '50': '重庆', '51': '四川', '52': '贵州', '53': '云南',
      '54': '西藏', '61': '陕西', '62': '甘肃', '63': '青海', '64': '宁夏',
      '65': '新疆', '71': '台湾', '81': '香港', '82': '澳门'
    }
    return pattern.test(val) && !!provs[val]
  }

  const checkDate = (val: string): boolean => {
    const pattern = /^(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)$/
    if (!pattern.test(val)) return false
    const year = val.substring(0, 4)
    const month = val.substring(4, 6)
    const date = val.substring(6, 8)
    const date2 = new Date(year + '-' + month + '-' + date)
    return date2.getMonth() === parseInt(month) - 1
  }

  const checkCode = (val: string): boolean => {
    const p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
    const factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
    const parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
    const code = val.substring(17)
    if (!p.test(val)) return false
    let sum = 0
    for (let i = 0; i < 17; i++) sum += parseInt(val[i]) * factor[i]
    return parity[sum % 11] + '' === code.toUpperCase()
  }

  return checkProv(idCard.substring(0, 2)) && checkDate(idCard.substring(6, 14)) && checkCode(idCard)
}

export function isPc(): boolean {
  const userAgentInfo = navigator.userAgent
  const agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']
  return !agents.some(agent => userAgentInfo.includes(agent))
}

export function validateNull(val: any): boolean {
  if (typeof val === 'boolean') return false
  if (typeof val === 'number') return false
  if (isArray(val)) return val.length === 0
  if (val instanceof Object) return JSON.stringify(val) === '{}'
  return val === 'null' || val === null || val === 'undefined' || val === undefined || val === ''
}

export function isObject(o: any): boolean {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Object'
}

export function isArray(o: any): boolean {
  return Object.prototype.toString.call(o).slice(8, -1) === 'Array'
}

export function isNumber(val: any): boolean {
  if (val === null || val === undefined || val === '') return false
  if (typeof val === 'number' && isFinite(val)) return val >= 0
  return /^(?:\d+(?:\.\d+)?|\.\d+)$/.test(String(val).trim())
}

export function isInteger(val: any): boolean {
  if (val === null || val === undefined || val === '') return false
  if (typeof val === 'number' && isFinite(val)) return Number.isInteger(val) && val >= 0
  return /^\d+$/.test(String(val).trim())
}
