import _ from 'lodash';

// 手机
export const phone = /^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9])|(19[0-9]))\d{8}$/;
// 固话
export const tel = /^(\d{4}-)?\d{6,8}$/;
// 邮箱
export const email = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
// 身份证
export const IDCard = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
// qq号
export const qq = /^[1-9]\d{4,11}$/;
// 微信号
export const wechart = /^[a-zA-Z][a-zA-Z0-9_-]{5,19}$/;
// 密码(登录密码长度至少8位，必须符合由数字,大写字母,小写字母,特殊符,至少其中三种组成密码)
export const password = /^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\\W_!@#$%^&*`~()-+=]+$)(?![a-z0-9]+$)(?![a-z\\W_!@#$%^&*`~()-+=]+$)(?![0-9\\W_!@#$%^&*`~()-+=]+$)[a-zA-Z0-9\\W_!@#$%^&*`~()-+=]{8,30}$/;

export const url = /^(https?|ftp|file):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/;
// 数字+字母+_+-
export const number_letter = /^[0-9a-zA-Z_\-\/]*$/;

// 数字+字母
export const numberLetter = /^[0-9a-zA-Z]*$/;

// 中文+中文符号
export const chineseReq = /[\u4e00-\u9fa5]|[\（\）\《\》\——\；\，\。\“\”\<\>\！\？\：]+/;

// 手机号码
export const checkPhone = val => phone.test(val);
// 固话
export const checkTel = val => tel.test(val);
// 邮箱
export const checkEmail = val => email.test(val);
// 身份证
export const checkIDCard = val => IDCard.test(val);
// 校验15或18位
export function checkIDCard2(val) {
  const city = {
    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: '澳门',
    91: '国外 '
  };
  let pass = true;

  if (!val || !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(val)) {
    //身份证号格式错误
    pass = false;
  } else if (!city[val.substr(0, 2)]) {
    //地址编码错误
    pass = false;
  } else {
    //18位身份证需要验证最后一位校验位
    if (val.length == 18) {
      // idcard = val.split('');
      //∑(ai×Wi)(mod 11)
      //加权因子
      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];
      let sum = 0;
      let ai = 0;
      let wi = 0;
      for (let i = 0; i < 17; i++) {
        ai = val[i];
        wi = factor[i];
        sum += ai * wi;
      }
      let last = parity[sum % 11];
      if (parity[sum % 11] != val[17]) {
        //校验位错误
        pass = false;
      }
    }
  }
  return pass;
}
// qq号
export const checkQq = val => qq.test(val);
// 微信号
export const checkWechart = val => wechart.test(val);
// 密码
export const checkPassword = val => password.test(val);
// URL
export const checkUrl = val => url.test(val);

// 数字+字母+_
export const checkNumLetter = val => number_letter.test(val);

// 数字+字母
export const checkNumberLetter = val => numberLetter.test(val);

// 中文+中文特殊符号
export const checkChinese = val => chineseReq.test(val);

// 身份证中获取出生日期
export const getBirthdayFromIdCard = idCard => {
  if (_.isEmpty(idCard) || !checkIDCard(idCard)) {
    return;
  }
  let birthday = '';
  if (idCard.length === 15) {
    birthday = '19' + idCard.slice(6, 12);
  } else if (idCard.length === 18) {
    birthday = idCard.slice(6, 14);
  }
  birthday = birthday.replace(/(.{4})(.{2})/, '$1-$2-');
  return birthday;
};

/**
 * 身份证中获取性别
 * @param {String} idCard 身份证
 * @param {Object|Array} dd 字典 { 0: '女', 1: '男' }、['女', '男']
 * @returns {any} 默认返回数字 1: 男、0: 女
 */
export const getSexFromIdCard = (idCard, dd) => {
  if (_.isEmpty(idCard) || !checkIDCard(idCard)) {
    return;
  }
  const val = parseInt(idCard.splice(-2, -1)) % 2;
  return dd ? dd[val] : val;
};

/**
 * const idCard = new SplitIdCard('110101199003075592')
 * idCard.sex
 * idCard.birthday
 * idCard.validate
 */
export class SplitIdCard {
  static Reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;

  constructor(idCard) {
    this.idCard = idCard;
  }

  get validate() {
    const { idCard } = this;
    return idCard && SplitIdCard.Reg.test(idCard);
  }

  get sex() {
    const { validate, idCard } = this;
    if (!validate) {
      return '';
    }
    return parseInt(idCard.slice(-2, -1)) % 2;
  }

  get birthday() {
    const { validate, idCard } = this;
    if (!validate) {
      return '';
    }
    let birthday = '';
    if (idCard.length === 15) {
      birthday = '19' + idCard.slice(6, 12);
    } else if (idCard.length === 18) {
      birthday = idCard.slice(6, 14);
    }
    birthday = birthday.replace(/(.{4})(.{2})/, '$1-$2-');
    return birthday;
  }
}
