'use strict';

/**
 * 项目账号数据模型
 *
 * @author CaiAoLin
 * @date 2017/11/16
 * @version
 */

// 加密类
const crypto = require('crypto');
const SSO = require('../lib/sso');
module.exports = app => {

    class ProjectAccount extends app.BaseService {

        /**
         * 构造函数
         *
         * @param {Object} ctx - egg全局变量
         * @return {void}
         */
        constructor(ctx) {
            super(ctx);
            this.tableName = 'project_account';
        }

        /**
         * 数据验证规则
         *
         * @param {String} scene - 场景
         * @return {Object} - 返回数据
         */
        rule(scene) {
            let rule = {};
            switch (scene) {
                case 'login':
                    rule = {
                        account: { type: 'string', required: true, min: 2 },
                        project_password: { type: 'string', required: true, min: 4 },
                        project: { type: 'string', required: true, min: 13 },
                    };
                    break;
                case 'ssoLogin':
                    rule = {
                        username: { type: 'string', required: true, min: 2 },
                        password: { type: 'string', required: true, min: 4 },
                    };
                default:
                    break;
            }

            return rule;
        }

        /**
         * 账号登录
         *
         * @param {Object} data - 表单post数据
         * @param {Number} loginType - 登录类型 1 | 2
         * @return {Boolean} - 返回登录结果
         */
        async accountLogin(data, loginType) {
            let result = false;
            try {
                // 验证数据
                const scene = loginType === 1 ? 'ssoLogin' : 'login';
                const rule = this.rule(scene);
                this.ctx.validate(rule, data);

                let accountData = {};
                let projectInfo = {};
                let projectList = [];
                if (loginType === 2) {
                    // 查找项目数据
                    const projectData = await this.ctx.service.project.getProjectByCode(data.project.toString());
                    if (projectData === null) {
                        throw '不存在项目数据';
                    }
                    projectInfo = {
                        id: projectData.id,
                        name: projectData.name,
                        userAccount: projectData.user_account,
                    };

                    // 查找对应数据
                    accountData = await this.db.get(this.tableName, {
                        account: data.account,
                        project_id: projectData.id,
                        enable: 1,
                    });

                    if (accountData === null) {
                        throw '不存在对应用户数据';
                    }

                    projectList = await this.getProjectInfoByAccount(data.account);

                    // 判断密码
                    if (accountData.is_admin === 1) {
                        // 管理员则用sso通道判断
                        const sso = new SSO(this.ctx);
                        result = await sso.loginValid(data.account, data.project_password.toString());
                    } else {
                        // 加密密码
                        const encryptPassword = crypto.createHmac('sha1', data.account).update(data.project_password)
                            .digest().toString('base64');
                        result = encryptPassword === accountData.password;
                    }
                } else {
                    // sso登录（演示版）
                    const sso = new SSO(this.ctx);
                    result = await sso.loginValid(data.username, data.password.toString());
                    accountData.account = data.username;
                    accountData.id = sso.accountID;
                }


                // 如果成功则更新登录时间
                if (result) {
                    const currentTime = new Date().getTime() / 1000;
                    if (loginType === 2) {
                        const updateData = {
                            last_login: currentTime,
                        };
                        await this.update(updateData, { id: accountData.id });
                    }
                    // 加密token
                    const sessionToken = crypto.createHmac('sha1', currentTime + '').update(accountData.account)
                        .digest().toString('base64');
                    // 存入session
                    this.ctx.session.sessionUser = {
                        account: accountData.account,
                        accountId: accountData.id,
                        loginTime: currentTime,
                        sessionToken,
                        loginType,
                    };
                    this.ctx.session.sessionProject = projectInfo;
                    this.ctx.session.sessionProjectList = projectList;
                }
            } catch (error) {
                console.log(error);
                result = false;
            }

            return result;
        }

        /**
         * 根据项目id获取用户列表
         *
         * @param {Number} projectId - 项目id
         * @return {Array} - 返回用户数据
         */
        async getAccountByProjectId(projectId) {
            const condition = {
                columns: ['id', 'account', 'name', 'company', 'role', 'mobile', 'telephone', 'enable'],
                where: { project_id: projectId, is_admin: 0 },
            };
            const accountList = await this.getAllDataByCondition(condition);

            return accountList;
        }

        /**
         * 停用/启用
         *
         * @param {Number} accountId - 账号id
         * @return {Boolean} - 返回操作结果
         */
        async enableAccount(accountId) {
            let result = false;
            const accountData = await this.getDataByCondition({ id: accountId });
            if (accountData === null) {
                return result;
            }

            const changeStatus = accountData.enable === 1 ? 0 : 1;
            result = await this.update({ enable: changeStatus }, { id: accountId });

            return result;
        }

        /**
         * 根据账号id查找对应的项目数据
         *
         * @param {Number} account - 账号
         * @return {Array} - 返回数据
         */
        async getProjectInfoByAccount(account) {
            let column = ['p.name', 'p.id'];
            column = column.join(',');
            const sql = 'SELECT ' + column + ' FROM ' +
                '?? AS pa ' +
                'LEFT JOIN ?? AS p ' +
                'ON pa.`project_id` = p.`id` ' +
                'WHERE pa.`account` = ? ' +
                'GROUP BY pa.`project_id`;';
            const sqlParam = [this.tableName, this.ctx.service.project.tableName, account];
            const projectInfo = await this.db.query(sql, sqlParam);

            return projectInfo;
        }
    }

    return ProjectAccount;
};
