const CODE_DURATION = 60 * 10
const Login = require('../models/index').login
const axios = require('axios')
const uuidv1 = require('uuid/v1')
const { isDev } = require('../util')

class LoginService {
  /**
   * 发送获取验证码请求
   * @param {string} param.id  手机号
   * @param {boolean} param.isUpdate 是否是更新模式
   */
  async _getCodeFromUDB (tel) {
    try {
      let data = await axios.get('http://udbproxy.duowan.com/api/sendcode', {
        params: {
          tel
        }
      })
      return data.data.data
    } catch (e) {
      console.error('_getCodeFromUDB error', e)
    }
  }
  async sendCodeRequest ({ id, isUpdate = false }) {
    let data = null
    try {
      let code = await this._getCodeFromUDB(id)
      data = {
        code: code,
        updatedAt: Date.now()
      }

      if (isUpdate) {
        await Login.update(data, {
          where: {
            id
          }
        })
      } else {
        data.id = id
        await Login.create(data)
      }
    } catch (e) {
      console.error('sendCodeRequest error:', e)
    }

    return data
  }
  /**
   * 查询手机号
   * @param {string} phone 手机号
   */
  async findCode (phone) {
    let data = await Login.findOne({ where: { id: phone } })
    let duration = 0
    let code = null
    if (data && data.code != null) {
      let now = Date.now()
      duration = CODE_DURATION - Math.ceil((now - data.updatedAt) / 1e3)
      // 大于CODE_DURATION 验证码无效，重新发送
      if (duration < 0) {
        data = await this.sendCodeRequest({
          id: phone,
          isUpdate: true
        })
        duration = CODE_DURATION
      }
      code = data.code
      // 测试环境返回code 用于测试
      if (isDev()) {
        return {
          duration,
          code
        }
      } else {
        return {
          duration
        }
      }
    }
  }
  /**
   * 获取验证码
   * @param {string} phone 手机号
   */
  async getCode (phone) {
    await this.sendCodeRequest({ id: phone })
    return {
      duration: CODE_DURATION
    }
  }
  /**
   * 验证验证码
   * @param {string} phone 手机号
   * @param {string} code 验证码
   * @return {boolean|null}
   */
  async checkCode (phone, code) {
    let data = await Login.findOne({ where: { id: phone } })
    if (!data || data.code == null) {
      return null
    } else {
      return data.code === code
    }
  }

  /**
   * 创建Token
   * @param {string} id 手机号
   */
  async createToken (id) {
    let token = uuidv1()

    await Login.update(
      {
        token: token
      },
      {
        where: {
          id
        }
      }
    )

    return token
  }

  /**
   * 校验用户登录态id
   * @param {string} id 用户手机号
   * @param {string} token 用户登录token
   */
  async authUser (id, token) {
    let data = await Login.findOne({ where: { id, token } })
    return data
  }
}

module.exports = new LoginService()
