'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
        }
    }
}

module.exports = {
    login,
    varfiyCode,
    logout,
};