const {
  dbCmd,
  verifyCollection
} = require('../../common/constants')
const {
  ERROR
} = require('../../common/error')
const {
  getVerifyCode
} = require('../../common/utils')

async function setVerifyCode ({
  mobile,
  email,
  code,
  expiresIn,
  scene
} = {}) {
  const now = Date.now()
  const record = {
    mobile,
    email,
    scene,
    code: code || getVerifyCode(),
    state: 0,
    ip: this.getClientInfo().clientIP,
    created_date: now,
    expired_date: now + expiresIn * 1000
  }
  await verifyCollection.add(record)
  return {
    errCode: 0
  }
}

async function setEmailVerifyCode ({
  email,
  code,
  expiresIn,
  scene
} = {}) {
  email = email && email.trim()
  if (!email) {
    throw {
      errCode: ERROR.INVALID_EMAIL
    }
  }
  email = email.toLowerCase()
  return setVerifyCode.call(this, {
    email,
    code,
    expiresIn,
    scene
  })
}

async function setMobileVerifyCode ({
  mobile,
  code,
  expiresIn,
  scene
} = {}) {
  mobile = mobile && mobile.trim()
  if (!mobile) {
    throw {
      errCode: ERROR.INVALID_MOBILE
    }
  }
  return setVerifyCode.call(this, {
    mobile,
    code,
    expiresIn,
    scene
  })
}

async function verifyEmailCode ({
  email,
  code,
  scene
} = {}) {
  email = email && email.trim()
  if (!email) {
    throw {
      errCode: ERROR.INVALID_EMAIL
    }
  }
  email = email.toLowerCase()
  const {
    data: codeRecord
  } = await verifyCollection.where({
    email,
    scene,
    code,
    state: 0,
    expired_date: dbCmd.gt(Date.now())
  }).limit(1).get()

  if (codeRecord.length === 0) {
    throw {
      errCode: ERROR.EMAIL_VERIFY_CODE_ERROR
    }
  }
  await verifyCollection.doc(codeRecord[0]._id).update({
    state: 1
  })
  return {
    errCode: 0
  }
}

async function verifyMobileCode ({
  mobile,
  code,
  scene
} = {}) {
  mobile = mobile && mobile.trim()
  if (!mobile) {
    throw {
      errCode: ERROR.INVALID_MOBILE
    }
  }
  const {
    data: codeRecord
  } = await verifyCollection.where({
    mobile,
    scene,
    code,
    state: 0,
    expired_date: dbCmd.gt(Date.now())
  }).limit(1).get()

  if (codeRecord.length === 0) {
    throw {
      errCode: ERROR.MOBILE_VERIFY_CODE_ERROR
    }
  }

  await verifyCollection.doc(codeRecord[0]._id).update({
    state: 1
  })
  return {
    errCode: 0
  }
}

module.exports = {
  verifyEmailCode,
  verifyMobileCode,
  setEmailVerifyCode,
  setMobileVerifyCode
}
