
'use strict';

const Service = require('egg').Service;
const uuidV4 = require('uuid/v4');
const moment = require('moment');
const R = require('ramda');

class UserService extends Service {
  // 发送验证码
  async sendVerificationCode(input) {
    const { ctx } = this;
    const phone = input.phone;

    // to do

    const ret = { result: true };
    return ret;
  }

  // 手机号登录
  async loginByPhone(input) {
    const { ctx } = this;
    const phone = input.phone;
    const code = input.code;

    // 判断用户是否存在
    let userInfo = await ctx.classModel.V5.CourseUser.findOne({ where: { phone, is_deleted: 0 } });
    if (ctx.isEmpty(userInfo)) {
      const uuid = uuidV4();
      userInfo = await ctx.classModel.V5.CourseUser.findOrCreate({ where: { phone, is_deleted: 0 }, defaults: { uuid, phone } });
    }

    // 校验验证码
    if (code !== 'fuck') {
      ctx.failed('验证码错误');
    }

    const key = 'course_v5_user_session_' + userInfo.uuid;
    const value = {
      user_uuid: userInfo.uuid,
      openid: userInfo.openid,
      session_key: '',
      phone,
    };
    await ctx.app.memcache.set(key, value);
    const authToken = ctx.helper.md5(userInfo.uuid + userInfo.openid + userInfo.phone + 'jbwl');

    const ret = {
      user_uuid: userInfo.uuid,
      openid: userInfo.openid,
      bind_phone: ctx.isEmpty(userInfo.phone) ? 0 : 1,
      auth_token: authToken,
    };

    return ret;
  }

  // 微信登录
  async loginByWX(input) {
    const { ctx, app } = this;
    const code = input.code;
    if (ctx.isEmpty(code)) {
      ctx.failed('error code');
    }

    // 请求微信授权 获取openid
    const wxAuthInfo = await this.requestWxAuth(code);
    const openid = wxAuthInfo.openid;// 获取openid
    const session_key = wxAuthInfo.session_key;

    // 判断用户是否存在
    let userInfo = await ctx.classModel.V5.CourseUser.findOne({ where: { openid, is_deleted: 0 } });
    if (ctx.isEmpty(userInfo)) {
      const uuid = uuidV4();
      userInfo = await ctx.classModel.V5.CourseUser.findOrCreate({ where: { openid, is_deleted: 0 }, defaults: { uuid, openid } });
    }

    // 存储缓存标识
    const userUuid = userInfo.uuid;
    const key = 'course_v5_user_session_' + userUuid;
    const value = {
      user_uuid: userInfo.uuid,
      openid,
      session_key,
      phone: userInfo.phone,
    };
    await app.memcache.set(key, value);
    const authToken = ctx.helper.md5(userInfo.uuid + openid + userInfo.phone + 'jbwl');

    const ret = {
      user_uuid: userInfo.uuid,
      openid: userInfo.openid,
      bind_phone: ctx.isEmpty(userInfo.phone) ? 0 : 1,
      auth_token: authToken,
    };

    ctx.success(ret);
  }

  // 微信授权
  async requestWxAuth(code) {
    const { ctx } = this;
    const APPID = ctx.app.config.COURSE_WX_APPID;
    const SECRET = ctx.app.config.COURSE_WX_SECRET;
    const url = `https://api.weixin.qq.com/sns/jscode2session?appid=${APPID}&secret=${SECRET}&js_code=${code}&grant_type=authorization_code`;

    const result = await ctx.helper.send_request(url, {}, { method: 'GET' });
    // const result = {"data":{"session_key":"Ce7HE1+MXfyZpWLYmkP0Iw==","openid":"oSjKI5LlG6AF7_vdV5Qb_DsbHcf4"},"status":200,"headers":{"connection":"keep-alive","content-type":"text/plain","date":"Tue, 24 Sep 2019 06:18:58 GMT","content-length":"82"},"res":{"status":200,"statusCode":200,"statusMessage":"OK","headers":{"connection":"keep-alive","content-type":"text/plain","date":"Tue, 24 Sep 2019 06:18:58 GMT","content-length":"82"},"size":82,"aborted":false,"rt":113,"keepAliveSocket":false,"data":{"session_key":"Ce7HE1+MXfyZpWLYmkP0Iw==","openid":"oSjKI5LlG6AF7_vdV5Qb_DsbHcf4"},"requestUrls":["https://api.weixin.qq.com/sns/jscode2session?appid=wx4769ebba9b91f8ec&secret=680440637b4e38c9b66529cfd5dc590e&js_code=021678ss18NNAk0Fohps1oA6ss1678sT&grant_type=authorization_code"],"timing":{"queuing":15,"dnslookup":15,"connected":27,"requestSent":57,"waiting":111,"contentDownload":113},"remoteAddress":"101.227.162.120","remotePort":443,"socketHandledRequests":1,"socketHandledResponses":1}};
    ctx.logger.info(JSON.stringify({ course_mini_auth_ret: result }));
    if (result.status !== 200) {
      ctx.failed('授权失败');
    }

    const ret = result.data;
    if (!ret.session_key && !ret.openid && ret.errcode !== 0) {
      ctx.failed(ret.errmsg);
    }

    const openid = ret.openid;
    const session_key = ret.session_key;

    return { openid, session_key };
  }

  // 保存用户信息
  async registerUserInfo(input) {
    const { ctx, app } = this;
    const userUuid = ctx.userUuid;
    const { avatar, nickname, sex, encryptedData, iv } = input;
    // 查找用户是否存在并更新
    const user = await ctx.classModel.V5.CourseUser.findOne({ where: { uuid: userUuid, is_deleted: 0 } });
    if (ctx.isEmpty(user)) {
      ctx.failed('用户不存在');
    }

    const data = {};
    if (!ctx.isEmpty(avatar)) {
      data.avatar = avatar;
    }
    if (!ctx.isEmpty(nickname)) {
      data.nickname = nickname;
    }
    if (!ctx.isEmpty(sex)) {
      data.sex = sex;
    }

    if (!ctx.isEmpty(encryptedData) && !ctx.isEmpty(iv)) {
      const decoded = await ctx.service.course.v5.wechat.decodeData(encryptedData, iv);
      if (!ctx.isEmpty(decoded) && !ctx.isEmpty(decoded.phoneNumber)) {
        data.phone = decoded.phoneNumber;
      }
    }

    // 校验手机号是否已经存在
    const userInfo = await ctx.classModel.V5.findOne({ where: { phone: data.phone, is_deleted: 0 } });
    if (!ctx.isEmpty(userInfo)) {
      // 新微信覆盖旧微信
      data.openid = user.openid;
      await ctx.classModel.V5.update(data, { where: { id: userInfo.id } });
      data.uuid = userInfo.uuid;
    } else {
      await ctx.classModel.V5.update(data, { where: { id: user.id } });
      data.uuid = user.uuid;
    }

    // 更新登录信息
    const key = 'course_v5_user_session_' + data.uuid;
    const value = {
      user_uuid: data.uuid,
      openid: user.openid,
      session_key: '',
      phone: data.phone,
    };
    await app.memcache.set(key, value);
    const authToken = ctx.helper.md5(data.uuid + user.openid + data.phone + 'jbwl');

    const ret = {
      user_uuid: data.uuid,
      openid: user.openid,
      bind_phone: 1,
      auth_token: authToken,
    };
    return ret;
  }

  // 获取用户信息
  async getUserInfo() {
    const { ctx } = this;
    const userUuid = ctx.userUuid;
    const userInfo = await ctx.classModel.V5.CourseUser.findOne({ where: { uuid: userUuid, is_deleted: 0 } });
    if (ctx.isEmpty(userInfo)) {
      ctx.failed('用户不存在');
    }

    const ret = {
      user_uuid: userInfo.uuid,
      nickname: userInfo.nickname,
      avatar: userInfo.avatar,
      sex: userInfo.sex,
      openid: userInfo.openid,
      bind_phone: ctx.isEmpty(userInfo.phone) ? 0 : 1,
    };

    return ret;
  }
}

module.exports = UserService;
