/** 双字节字符(包括汉字在内，即占两个英文字符位置的字符) */
export const double_byte_RegEx = /[^\x00-\xFF]/ // eslint-disable-line no-control-regex

/** 中文字符 */
export const chinese_RegEx = /[\u4E00-\u9FA5]/

/** 密码至少包含字母、数字、特殊字符中的两种，且不能出现4个大小连续或相同的数字 */
export const password_RegEx
  // eslint-disable-next-line regexp/optimal-quantifier-concatenation
  = /^(?!.*(.)\1{3})(?!.*(0123|1234|2345|3456|4567|5678|6789|9876|8765|7654|6543|5432|4321))(?=.*[a-z])(?=.*\d|.*[!@#¥%&*.,])[a-z\d!@#¥%&*.,]+$/i

/** 密码至少包含字母、数字、特殊字符中的两种，且不能出现4个大小连续或相同的数字，且为 8到 24 位  */
export const password_RegEx2
  // eslint-disable-next-line regexp/optimal-quantifier-concatenation
  = /^(?!.*(.)\1{3})(?!.*(0123|1234|2345|3456|4567|5678|6789|9876|8765|7654|6543|5432|4321))(?=.*[a-z])(?=.*\d|.*[!@#¥%&*.,])[a-z\d!@#¥%&*.,]{8,24}$/i
/** 验证电话号 */
export const tel_RegEx = /^1\d{10}$/

/** 邮箱 */
export const email_RegEx = /^([\w-]+)@([\w-]+\.?)*\w\.[a-z]{2,10}$/i

/** 网址(不带参数) */
export const url_RegEx = /^(https?:\/\/)([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(\/\S*)?$/
/** 网址(带参数) */
export const url_RegEx2 = /^(https?:\/\/)([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(\/[^\s?#]*)?(\?[^?\s#]*)?(#\S*)?$/

/** 身份证 */
export const IDcard_RegEx = /^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9X])$/i

/** 视频 */
// eslint-disable-next-line regexp/no-dupe-disjunctions
export const video_RegEx = /\.(mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|m3u8)/i

/**
 * 验证密码合法性
 */
export function verifyPassword(str: string): boolean {
  return Boolean(password_RegEx.test(str))
}

/**
 * 验证电话号
 */
export function verifyTel(str: string): boolean {
  return Boolean(tel_RegEx.test(str))
}

/**
 * 验证邮箱
 */
export function verifyEmail(str: string): boolean {
  return Boolean(email_RegEx.test(str))
}

/**
 * 验证身份证
 */
export function verifyIDcard(str: string): boolean {
  if (!IDcard_RegEx.test(str)) {
    return false
  }
  try {
    // 出生年月日校验
    const year = str.slice(6, 10) // 身份证年
    const month = str.slice(10, 12) // 身份证月
    const date = str.slice(12, 14) // 身份证日
    const d = new Date(`${year}/${month}/${date}`)
    const dY = Number(d.getFullYear())
    const dM = Number(d.getMonth()) + 1
    const dD = Number(d.getDate())
    if (Number(year) === dY && Number(month) === dM && Number(date) === dD) {
      // 限制起始年份为1850且不能超过今天
      if (d.getTime() <= new Date().getTime() && dY >= 1850) {
        return true
      }
      else {
        return false
      }
    }
    else {
      return false
    }
    // oxlint-disable-next-line no-unused-vars
  }
  // eslint-disable-next-line unused-imports/no-unused-vars
  catch (_) {
    return false
  }
}

/**
 * 验证网址
 * @param str - 网址
 * @param isParam - 可以携带参数 默认为 true
 */
export function verifyUrl(str: string, isParam = true): boolean {
  return Boolean(isParam ? url_RegEx2.test(str) : url_RegEx.test(str))
}

/**
 * 是否为纯对象 不包含 Array,undefined function 等等
 */
export function isObject(obj: unknown): obj is Record<number | string | symbol, unknown> {
  return Object.prototype.toString.call(obj) === '[object Object]'
}

/**
 * 是否为dom
 */
export function isDOM(obj: unknown): obj is HTMLElement {
  if (typeof HTMLElement === 'object') {
    return obj instanceof HTMLElement
  }
  else if (obj && typeof obj === 'object') {
    return (obj as Record<string, unknown>).nodeType === 1 && typeof (obj as Record<string, unknown>).nodeName === 'string'
  }
  else {
    return false
  }
}

/**
 * 是否为日期对象
 */
export function isDate(obj: unknown): obj is Date {
  return Object.prototype.toString.call(obj) === '[object Date]'
}

/**
 * 是否为Math对象
 */
export function iIsMath(obj: unknown): obj is Math {
  return Object.prototype.toString.call(obj) === '[object Math]'
}

/**
 * 是否为RegExp对象
 */
export function isRegExp(obj: unknown): obj is RegExp {
  return Object.prototype.toString.call(obj) === '[object RegExp]'
}

/**
 * 是否为json对象
 */
export function isJson(obj: unknown): obj is Record<string, unknown> | unknown[] {
  return Boolean(isObject(obj) || Array.isArray(obj))
}

/**
 * 是否为空对象(传入对象为假也代表是空对象,如false,null,0等)
 */
export function isNullObj(obj: unknown): boolean {
  return Boolean(!obj || JSON.stringify(obj) === '{}')
}

/**
 * 判断是否为小屏幕
 */
export function isSmallScreen(): boolean {
  return document.documentElement.clientWidth < 900
}
