'use strict';
const Hex = require('crypto-js/enc-hex');
const SHA1 = require('crypto-js/sha1');
const MD5 = require('crypto-js/md5');
const moment = require('moment');
const uuid = require('uuid');

async function login (ctx, next) {
   const transaction = await ctx.fs.dc.orm.transaction();
   try {
      const models = ctx.fs.dc.models;
      const params = ctx.request.body;
      let password = Hex.stringify(MD5(params.password));
      const userRes = await models.User.findOne({
         where: {
            username: params.username,
            password: password,
            delete: false,
            enable: true
         },
         attributes: { exclude: ['password'] },
         include: [{
            attributes: ["resourceId"],
            model: models.UserResource
         }]
      });


      if (!userRes) {
         ctx.status = 400;
         ctx.body = {
            "message": "账号或密码错误"
         }
      }

      if (userRes)
         if (userRes && !userRes.enable) {
            ctx.status = 400;
            ctx.body = { message: "该用户已被禁用" }
         } else {
            const token = uuid.v4();
            let deptInfo = null;
            if (userRes) {
               const { departmentId } = userRes.dataValues;
               deptInfo = await models.Department.findOne({
                  where: {
                     id: departmentId
                  }
               })
            }

            if (!userRes) {
               ctx.status = 400;
               ctx.body = { message: "暂无登录权限,请联系管理员" }
               return;
            }

            let userData = userRes.dataValues;
            let userRslt = Object.assign(userData, {
               authorized: true,
               token: token,
               userResources: userRes ? userRes.userResources.map(r => r.resourceId) : [],
               type: deptInfo ? deptInfo.type : '',
               deptName: deptInfo ? deptInfo.name : '',
            });
            await models.UserToken.create({
               token: token,
               userInfo: userRslt,
               expired: moment().add(30, 'days').format()
            });

            ctx.status = 200;
            ctx.body = userRslt;
         }
      await transaction.commit();
   } catch (error) {
      await transaction.rollback();
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {
         "message": "登录失败"
      }
   }
}

async function varfiyCode (ctx) {
   try {
      const { models } = ctx.fs.dc;
      const { pushBySms, pushByEmail } = ctx.app.fs.utils
      const { phone, sig, r } = ctx.request.body

      // 伪造的请求可能由相同的sig参数组成
      const checkSigUsed = await models.PhoneValidateCode.findOne({
         where: { sig: sig }
      });
      if (checkSigUsed) {
         throw '参数错误!'
      }

      // 验证sig正确性            
      const checkSig = Hex.stringify(SHA1(phone + r));
      if (!r || !sig || sig != checkSig) {
         throw '参数错误!'
      }

      let varifyCode = ''
      for (let i = 0; i < 6; i++) {
         varifyCode += Math.floor(Math.random() * 10)
      }

      // await pushBySms({
      //     phone: phone,
      //     templateCode: 'SMS_248250074',
      //     templateParam: {
      //         code: varifyCode
      //     },
      // })

      await models.PhoneValidateCode.create({
         phone: phone,
         code: varifyCode,
         sig: sig,
         expired: moment().add(10, 'minutes').format('YYYY-MM-DD HH:mm:ss')
      })

      ctx.status = 204;
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {
         message: typeof error == 'string' ? error : '获取验证码失败'
      }
   }
}

async function logout (ctx) {
   try {
      const models = ctx.fs.dc.models;
      const params = ctx.request.body;

      await models.UserToken.destroy({
         where: {
            token: params.token,
         }
      });

      ctx.status = 204;
   } catch (error) {
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {
         message: typeof error == 'string' ? error : undefined
      }
   }
}

async function screenlogin (ctx, next) {
   let message = '登录失败'
   const transaction = await ctx.fs.dc.orm.transaction();
   try {
      const models = ctx.fs.dc.models;
      let { p, username, password } = ctx.request.body;

      if (!p) {
         message = '缺少pcode'
         throw ''
      }
      let userRes = await models.ProjectUser.findOne({
         where: { code: p },
      }) || {}

      if (!userRes.id) {
         message = 'pcode不存在'
         throw ''
      }

      if (userRes.del) {
         message = '该项目已被删除,账户无法登录'
         throw ''
      }

      let passwords = Hex.stringify(MD5(password));
      if (username = !userRes.account || passwords != userRes.password) {
         message = '账号或密码错误'
         throw ''
      }

      let token = uuid.v4();

      let userData = userRes.dataValues;
      let userRslt = Object.assign({
         projectName:userData.projectName,
         projectType:userData.projectType,
         projectDescribe:userData.projectDescribe,
         monitorObject:userData.monitorObject,
         id:userData.id,
         del:userData.del,
         createTime:userData.createTime,
         account:userData.account,
      }, {
         authorized: true,
         token: token,
      });
      await models.UserToken.create({
         token: token,
         userInfo: userRslt,
         expired: moment().add(30, 'days').format()
      });

      ctx.status = 200;
      ctx.body = userRslt;

      await transaction.commit();
   } catch (error) {
      await transaction.rollback();
      ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
      ctx.status = 400;
      ctx.body = {
         "message": message
      }
   }
}

module.exports = {
   login,
   varfiyCode,
   logout,
   screenlogin,

};