/**
 * 小程序端 企业角色用户 逻辑
 * 作者:lxm
 * 3.0更新功能
 */

import { ERRORENUM } from "../../config/errorEnum";
import * as sysTools from "../../tools/system";
import { BizError } from "../../util/bizError";
import * as enterpriseData from "../../data/enterprise/enterprise";
import moment = require("moment");
import * as codeData from "../../data/fuHuaQi/code";
import { sendChangePwdCode } from "../sms";
import { CODETYPE } from "../../config/enum";

/**
 * 企业登录
 * @param uscc 企业统一信用代码
 * @param pwd 
 */
export async function enterpriseLogin(uscc:string, pwd:string) {
    if (!sysTools.eccUscc(uscc)) throw new BizError(ERRORENUM.统一社会信用代码不合法, '孵化器登录时');

    let enterpriseInfo = await enterpriseData.findEnterpriseByUscc(uscc);
    if (!enterpriseInfo) throw new BizError(ERRORENUM.账号不存在);

    if ( moment(enterpriseInfo.createTime).format("YYYY-MM") == moment().format("YYYY-MM") ) {
        throw new BizError(ERRORENUM.企业审批中请下个自然月登录);
    }

    let checkPwd = sysTools.getPwdMd5(enterpriseInfo.uscc, pwd);
    if (enterpriseInfo.pwd != checkPwd) throw new BizError(ERRORENUM.密码错误);

    const Token = sysTools.getToken(uscc);
    
    let userInfo = {
        uscc: enterpriseInfo.uscc,
        // name: fuhuaqiInfo.name,
        firstLogin : !enterpriseInfo.firstLoginIsChangePwd,
        token:Token
    };

    enterpriseInfo.token = Token;
    enterpriseInfo.tokenMs = new Date().valueOf();

    await enterpriseInfo.save();
    
    return userInfo;
}


/**
 * 首次登录修改密码
 * @param uscc 企业统一信用代码
 * @param pwd 密码
 * @param confirmPwd 确认密码 
 */
export async function firstChangePwd(uscc:string, pwd:string, confirmPwd:string) {
    if (pwd != confirmPwd) throw new BizError(ERRORENUM.密码不一致);
    if (pwd.search(/^[A-Za-z0-9]{6,18}$/) < 0) throw new BizError(ERRORENUM.密码只能由6至18位字符和数字组成);

    let dataBaseInfo = await enterpriseData.findEnterpriseByUscc(uscc);
    if (dataBaseInfo.firstLoginIsChangePwd) throw new BizError(ERRORENUM.不能重复修改密码, `企业端 重复调用了首次登录之后的修改密码接口${uscc}`);

    dataBaseInfo.pwd = sysTools.getPwdMd5(uscc, sysTools.md5PwdStr(pwd));
    dataBaseInfo.firstLoginIsChangePwd = true;
    await dataBaseInfo.save();

    return {isSuccess:true};
}




/**
 * 找回密码 
 * @param phone 负责人电话号码  如果和库里的对不上 就要报错
 * @param uscc 企业统一信用代码
 * @param code 验证码
 * @param pwd 密码
 * @param confirmPwd 确认密码 
 */
export async function resettingPwd(phone:string, uscc:string, code:string, pwd:string, confirmPwd:string) {
    if (!sysTools.eccUscc(uscc)) throw new BizError(ERRORENUM.统一社会信用代码不合法, '重置密码时');
    let enterpriseInfo = await enterpriseData.findEnterpriseByUscc(uscc);
    if (!enterpriseInfo) throw new BizError(ERRORENUM.账号不存在, `重置密码时 uscc:${uscc}`);
    if (!enterpriseInfo.securePhon) throw new BizError(ERRORENUM.未填安全手机号无法修改密码, '企业-修改密码发验证码时-没有安全手机号');
    if ( phone != enterpriseInfo.securePhon) throw new BizError(ERRORENUM.号码与主体不一致, '企业-修改密码发验证码时');

    if (pwd != confirmPwd) throw new BizError(ERRORENUM.密码不一致);
    if (pwd.search(/^[A-Za-z0-9]{6,18}$/) < 0) throw new BizError(ERRORENUM.密码只能由6至18位字符和数字组成);

    let todayMs = sysTools.getTodayMs();
    let codeList = await codeData.findTodayCodeByUscc(uscc, todayMs);

    let now = new Date().valueOf();

    let codeId = '';
    let msg = ERRORENUM.验证码错误;
    codeList.forEach(info => {
        if (info.code == code) {
            if (info.isUse) msg = ERRORENUM.验证码失效;
            else if ( (now - info.sendMs) > (30 * 60 * 1000) ) msg = ERRORENUM.验证码过期
            else codeId = info.id;
        }
    });

    if (!codeId) throw new BizError(msg, `uscc:${uscc}重置密码的code:${code}`);

    await codeData.updateCodeState(codeId);

    enterpriseInfo.pwd = sysTools.getPwdMd5(uscc, sysTools.md5PwdStr(pwd));

    await enterpriseInfo.save();

    return {isSuccess:true};
}


/**
 * 发送修改密码的短信验证码
 * @param uscc 企业统一信用代码
 */
export async function changePwdSendCode(uscc:string, phone:string) {
    if (!sysTools.eccUscc(uscc)) throw new BizError(ERRORENUM.统一社会信用代码不合法, '重置密码时');
    let enterpriseInfo = await enterpriseData.findEnterpriseByUscc(uscc);
    if (!enterpriseInfo) throw new BizError(ERRORENUM.账号不存在, `企业-发送验证码时 uscc:${uscc}`);
    if (!enterpriseInfo.securePhon) throw new BizError(ERRORENUM.未填安全手机号无法修改密码, '企业-修改密码发验证码时-没有安全手机号');
    if ( phone != enterpriseInfo.securePhon) throw new BizError(ERRORENUM.号码与主体不一致, '企业-修改密码发验证码时');

    let todayMs = sysTools.getTodayMs();
    let todayCodeList = await codeData.findTodayCodeByUscc(uscc, todayMs);
    if (todayCodeList.length >= 4) throw new BizError(ERRORENUM.发送验证码次数超限制, `${uscc} 修改密码发送验证码次数超限制4`);

    let sendMs = todayMs;
    todayCodeList.forEach(info => {
        sendMs = Math.max(sendMs, info.sendMs);
    });

    let now = new Date().valueOf();
    if ((now - sendMs) <= (60 * 1000) ) throw new BizError(ERRORENUM.发送验证码频率过快, `${uscc}`);

    let codeId = sysTools.getSMSCodeId(uscc, todayCodeList.length);
    let code = sysTools.getSMSCode();

    
    await sendChangePwdCode(phone, code);
    now = new Date().valueOf();

    await codeData.createCode(uscc, codeId, code, CODETYPE.修改密码, now);

    return {
        isSuccess:true,
        sendMs:now
    };
}

export async function getFirstUpdatePwdState(uscc:string) {
    let enterpriseInfo = await enterpriseData.findEnterpriseByUscc(uscc);

    return {firstLogin : !enterpriseInfo.firstLoginIsChangePwd,};
}