/**
 * 审批逻辑 success
 */

import moment = require("moment");
import { BANXUELEIXING, CERTIFICATETYPE, DOCUMENTTYPE, EDUCATION, INDIVIDUALMEMBERTYPE, MEMBERLEVEL, MEMBERSTATE, MEMBERTYPE, MEMBERTYPEECCENUM, NATION, OPERATIONREHAVIOR, PAYMENTSTATUS, PROFCATEGORY, REGISTERFLOW, SEX, STATE, UNITMEMBERTYPE, USERREGISTERSTATE } from "../../config/enum";
import { ERRORENUM } from "../../config/errorEnum";
import { addManyData } from "../../data/add";
import { TABLEENUM } from "../../data/models/model";
import { find, findCount, findOnce, findToSortToPage } from "../../data/select";
import { updateOneData } from "../../data/update";
import { generateSystemId, getMenberNum, getSessionByEdition, successResult } from "../../tools/system";
import { BizError } from "../../util/bizError";
import { extractData } from "../../util/piecemeal";
import { changeEnumValue } from "../../util/verificationEnum";
import { createOrder } from "./order";
import { getCityNameByCode } from "../../config/cityConfig";
import { sendPassNotice } from "../sms";
import { SessionTimeMsConfig } from "../../config/serverConfig";

/**
 * 待审核列表 success
 * @param name 名称关键字：个人会员匹配真实姓名，单位会员匹配单位名称
 * @param memberType 会员类别 unitMemberType、individualMemberType
 * 会员类别、职务、级别改成多选
 * 会员类别：个人【个人会员、专业会员】单位【院校、机构、其他】返回前端枚举：MEMBERTYPEECCENUM
 * @param documentId 身份证
 * @param phone 登录手机号
 * @param mail 单位/个人邮箱
 * @param sheng 省
 * @param shi 市
 * @param pageNumber 当前页 
 */
export async function pendingReviewList({name, memberType, documentId, phone, mail, sheng, shi, pageNumber, examineState}) {
    /**查询条件 */
    let selectParam:any = {
        isAdmin:STATE.否
    }; //审批列表展示状态除通过外的数据
    if (name) {
        if (!selectParam["$and"]) selectParam["$and"] = [];
        selectParam["$and"] = [
            {"$or":[
                {unitName:{"$regex":`${name}`}, memberType:MEMBERTYPE.单位会员},
                {name:{"$regex":`${name}`}, memberType:MEMBERTYPE.个人会员}
            ]}
        ];
    }
    if (examineState) {
        if (examineState == 1) {
            if (!selectParam["$and"]) selectParam["$and"] = [];
            selectParam["$and"].push({"$or":[
                {userRegisterState:USERREGISTERSTATE.重新提交},
                {userRegisterState:USERREGISTERSTATE.待审核}
            ]});
        } else {
            selectParam.userRegisterState = USERREGISTERSTATE.驳回修改
        }
       
    }
    
    let memberTypeLen = Object.keys(MEMBERTYPEECCENUM).filter(key => isNaN(Number(key))).length;
    if (memberType.length == 0 || memberType.length == memberTypeLen) {
        if (!selectParam["$or"]) selectParam["$or"] = [];
        selectParam["$or"].push(
            {"$or":[
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第二步 },
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第二步 }
            ]},
            {"$or":[
                { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第三步 },
                { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
                { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第三步 },
            ]}
        );
    } else {
        if (!selectParam["$or"]) selectParam["$or"] = [];
        if (memberType.indexOf(MEMBERTYPE.个人会员) > -1) {
            // selectParam.memberType = MEMBERTYPE.个人会员;
            selectParam["$or"].push(
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第二步 },
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
                { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第二步 }
            );
        }
        if (memberType.indexOf(UNITMEMBERTYPE.其他) > -1 || memberType.indexOf(UNITMEMBERTYPE.机构) > -1 || memberType.indexOf(UNITMEMBERTYPE.院校) > -1) {//单位
            // selectParam.unitMemberType = {"$in":memberType};
            selectParam["$or"].push(
                { unitMemberType:{"$in":memberType}, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第三步 },
                { unitMemberType:{"$in":memberType}, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
                { unitMemberType:{"$in":memberType}, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第三步 },
            );
        }
    }

    if (documentId) selectParam.documentId = documentId;
    if (phone) selectParam.phone = phone;
    if (mail) selectParam.mail = mail;
    if (sheng) selectParam.sheng = sheng;
    if (shi) selectParam.shi = shi;

    const SelectFiles = ["userId", "userRegisterState", "unitName", "name", "loginId", "phone", "askForTime", "memberLevel", "sheng", "shi", "qu", "individualMemberType", "unitMemberType", "memberType", "mail"];
    let dbList = await findToSortToPage(TABLEENUM.用户表, selectParam, SelectFiles, {askForTime:-1}, pageNumber);
    let dataCount = await findCount(TABLEENUM.用户表, selectParam);

    let dataList = [];
    dbList.forEach(info => {
        let item:any = extractData(info, SelectFiles);
        /**处理枚举值 */
        if (!item.userRegisterState) item.userRegisterState = USERREGISTERSTATE.待审核;
        else item.userRegisterState = changeEnumValue(USERREGISTERSTATE, item.userRegisterState);
        item.memberLevel = changeEnumValue(MEMBERLEVEL, item.memberLevel);
        item.sheng = getCityNameByCode(item.sheng);
        item.shi = getCityNameByCode(item.shi);
        item.qu = getCityNameByCode(item.qu);
        if(item.individualMemberType) {
            item.memberType = changeEnumValue(MEMBERTYPEECCENUM, info.individualMemberType);
        }
        if(item.unitMemberType) {
            item.memberType = changeEnumValue(MEMBERTYPEECCENUM, info.unitMemberType);
        }

        //这一行代码是兼容老用户没有 individualMemberType
        if (info.memberType == MEMBERTYPE.个人会员) {
            item.memberType = "个人会员";
        }

        dataList.push(item);
    });

    return {dataList, dataCount};
}



/**
 * 通过审核 success
 * @param id 待审核列表返回的用户id 
 * @returns 
 */
export async function adopt({id, session}) {
    let userInfo = await findOnce(TABLEENUM.用户表, {userId:id, isAdmin:STATE.否}, ["userId", "registerFlow", "loginId","userRegisterState", "memberType", "unitName", "name", "phone", "sheng"]);
    if (!userInfo || !userInfo.userId) throw new BizError(ERRORENUM.目标数据不存在);
    if (userInfo.memberType == MEMBERTYPE.个人会员 && userInfo.registerFlow != REGISTERFLOW.完成第二步) {
        throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}为个人会员，并没有完成第二步`);
    }
    if (userInfo.memberType == MEMBERTYPE.单位会员 && userInfo.registerFlow != REGISTERFLOW.完成第三步) {
        throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}为单位会员，并没有完成第三步`);
    }
    if (userInfo.userRegisterState == USERREGISTERSTATE.驳回修改) {
        throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}当前状态为驳回修改`);
    }
    if (userInfo.userRegisterState == USERREGISTERSTATE.通过) {
        throw new BizError(ERRORENUM.重复提交, `${userInfo.userId}当前状态为已通过`);
    }

    let thisDate = new Date();
    const NowMs = thisDate.valueOf();
    
    let userCount = await findCount(TABLEENUM.用户表, {isAdmin:0, memberType:userInfo.memberType,  userRegisterState:USERREGISTERSTATE.通过});
    let memberNum = getMenberNum(thisDate, userInfo.sheng, userCount, userInfo.memberType);

    let joinTime = 0;
    let orderTimeMs = 0;
    let sessionDate = getSessionByEdition(Math.floor(session/100),Math.floor(session%100));
    if (sessionDate) {
        joinTime = sessionDate.timeMs;
    } else {
        joinTime = new Date().valueOf();
    }
    let updateInfo:any = {
        auditTime:NowMs,
        joinTime,
        userRegisterState:USERREGISTERSTATE.通过,
        session:session,
        paymentStatus:PAYMENTSTATUS.未支付,
        lifespanStartTime:NowMs,
        lifespanEndTime:NowMs + 1000,
        memberLevel:MEMBERLEVEL.普通会员,
        memberState:MEMBERSTATE.异常,
        memberNum
    };
    let unitName = userInfo.unitName;
    let subType = userInfo.unitMemberType;
    if (userInfo.memberType == MEMBERTYPE.个人会员) {
        updateInfo.individualMemberType = INDIVIDUALMEMBERTYPE.普通会员;
        subType = userInfo.individualMemberType;
    }

    //创建初始订单
    //创建初始订单应该使用
    //创建今年的订单
    let thisYear = new Date().getFullYear();
    let orderStartMonthStr = moment(joinTime).format("MM-DD HH:mm:SS");
    let orderStartMs = new Date(`${thisYear}-${orderStartMonthStr}`).valueOf();
    await createOrder(id, userInfo.loginId, userInfo.phone, unitName, orderStartMs, MEMBERLEVEL.普通会员, userInfo.memberType, subType, true);

    await updateOneData(TABLEENUM.用户表, {userId:id}, updateInfo);

    /**提交审批历史信息 */
    let addApprovalHistory = {
        id:generateSystemId(TABLEENUM.审批历史表, id),
        userId:id,
        operationTime:NowMs,
        operationBehavior:OPERATIONREHAVIOR.通过,
        remarks:"通过"
    };
    await addManyData(TABLEENUM.审批历史表, addApprovalHistory);

    //发送短信
    let smsName = userInfo.memberType == MEMBERTYPE.个人会员 ? userInfo.name : userInfo.unitName;
    await sendPassNotice(userInfo.phone, smsName);

    return successResult();
}


/**
 * 批量通过
 * @param param0 
 */
export async function batchAdopt({idList, session}) {
    //限制长度
    if (idList.length > 10) throw new BizError(ERRORENUM.批量操作超过个数限制);

    let thisDate = new Date();
    const NowMs = thisDate.valueOf();

    for (let i = 0; i < idList.length; i++) {
        let id = idList[i];
        if (!id) continue;//空id跳过

        let userInfo = await findOnce(TABLEENUM.用户表, {userId:id, isAdmin:STATE.否}, ["userId", "registerFlow", "loginId","userRegisterState", "memberType", "unitName", "name", "phone", "sheng"]);
        if (!userInfo || !userInfo.userId) throw new BizError(ERRORENUM.目标数据不存在, id);
        if (userInfo.memberType == MEMBERTYPE.个人会员 && userInfo.registerFlow != REGISTERFLOW.完成第二步) {
            throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}为个人会员，并没有完成第二步`);
        }
        if (userInfo.memberType == MEMBERTYPE.单位会员 && userInfo.registerFlow != REGISTERFLOW.完成第三步) {
            throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}为单位会员，并没有完成第三步`);
        }
        if (userInfo.userRegisterState == USERREGISTERSTATE.驳回修改) {
            throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}当前状态为驳回修改`);
        }
        if (userInfo.userRegisterState == USERREGISTERSTATE.通过) {
            throw new BizError(ERRORENUM.重复提交, `${userInfo.userId}当前状态为已通过`);
        }

        let userCount = await findCount(TABLEENUM.用户表, {isAdmin:0, memberType:userInfo.memberType,  userRegisterState:USERREGISTERSTATE.通过});
        let memberNum = getMenberNum(thisDate, userInfo.sheng, userCount, userInfo.memberType);
    
        let joinTime = 0;
        let sessionDate = getSessionByEdition(Math.floor(session/100),Math.floor(session%100));
        if (sessionDate) {
            joinTime = sessionDate.timeMs;
        } else {
            joinTime = new Date().valueOf();
        }

        let updateInfo:any = {
            auditTime:NowMs,
            joinTime,
            userRegisterState:USERREGISTERSTATE.通过,
            session:session,
            paymentStatus:PAYMENTSTATUS.未支付,
            lifespanStartTime:NowMs,
            lifespanEndTime:NowMs + 1000,
            memberLevel:MEMBERLEVEL.普通会员,
            memberState:MEMBERSTATE.异常,
            memberNum
        };
        let unitName = userInfo.unitName;
        let subType = userInfo.unitMemberType;
        if (userInfo.memberType == MEMBERTYPE.个人会员) {
            updateInfo.individualMemberType = INDIVIDUALMEMBERTYPE.普通会员;
            subType = userInfo.individualMemberType;
        }
        
        //创建初始订单
        await createOrder(id, userInfo.loginId, userInfo.phone, unitName, NowMs + 1000, MEMBERLEVEL.普通会员, userInfo.memberType, subType, true);
    
        await updateOneData(TABLEENUM.用户表, {userId:id}, updateInfo);
    
        /**提交审批历史信息 */
        let addApprovalHistory = {
            id:generateSystemId(TABLEENUM.审批历史表, id),
            userId:id,
            operationTime:NowMs,
            operationBehavior:OPERATIONREHAVIOR.通过,
            remarks:"通过"
        };
        await addManyData(TABLEENUM.审批历史表, addApprovalHistory);

    }

    return successResult();
}


/**
 * 驳回 success
 * @param userId 
 * @param remarks 驳回理由
 * @returns 
 */
export async function reject({id, remarks}) {
    let userId = id;
    let userInfo = await findOnce(TABLEENUM.用户表, {userId, isAdmin:STATE.否});
    if (!userInfo || !userInfo.userId) throw new BizError(ERRORENUM.目标数据不存在);
    if (userInfo.memberType == MEMBERTYPE.个人会员 && userInfo.registerFlow != REGISTERFLOW.完成第二步) {
        throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}为个人会员，并没有完成第二步`);
    }
    if (userInfo.memberType == MEMBERTYPE.单位会员 && userInfo.registerFlow != REGISTERFLOW.完成第三步) {
        throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}为单位会员，并没有完成第三步`);
    }
    if (userInfo.userRegisterState == USERREGISTERSTATE.驳回修改) {
        throw new BizError(ERRORENUM.不具备审批条件, `${userInfo.userId}当前状态为驳回修改`);
    }
    if (userInfo.userRegisterState == USERREGISTERSTATE.通过) {
        throw new BizError(ERRORENUM.重复提交, `${userInfo.userId}当前状态为已通过`);
    }

    /**驳回修改，修改该会员注册流程回到第二步 */
    let updateParam = {
        userRegisterState:USERREGISTERSTATE.驳回修改, 
        registerFlow:REGISTERFLOW.完成第一步,
        firstStep:new Date().valueOf(),
        saveUnsubmitted:STATE.否
    }
    await updateOneData(TABLEENUM.用户表, {userId}, updateParam);
    
    /**提交审批历史信息 */
    const NowMs = new Date().valueOf(); 
    let addApprovalHistory = {
        id:generateSystemId(TABLEENUM.审批历史表, userId),
        userId,
        operationTime:NowMs,
        operationBehavior:OPERATIONREHAVIOR.驳回修改,
        remarks
    };
    await addManyData(TABLEENUM.审批历史表, addApprovalHistory);

    return successResult();
}


/**
 * 审核历史 success
 * @param userId
 * @returns 
 */
export async function approvalHistoryList({userId}) {
    let dbList = await find(TABLEENUM.审批历史表, {userId});

    let dataList = [];
    dbList.forEach(info => {
        let item:any = extractData(info, ["operationTime", "operationBehavior", "remarks"]);
        item.operationBehavior = changeEnumValue(OPERATIONREHAVIOR, item.operationBehavior);
        dataList.push(item);
    });

    return {dataList};
}


/**
 * 导出
 * @param param0 
 * @returns 
 */
export async function outPutPendingReviewList({memberType, exportColumns}) {
    let selectParam:any = {
        isAdmin:STATE.否
    }; //审批列表展示状态除通过外的数据
    if (memberType == MEMBERTYPE.个人会员) {
        // selectParam.memberType = MEMBERTYPE.个人会员;
        selectParam["$or"] = [
            { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第二步 },
            { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
            { memberType:MEMBERTYPE.个人会员, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第二步 }
        ];
    }
    else {//单位
        selectParam["$or"] = [
            { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.待审核, registerFlow:REGISTERFLOW.完成第三步 },
            { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.驳回修改, registerFlow:REGISTERFLOW.完成第一步 },
            { memberType:MEMBERTYPE.单位会员, userRegisterState:USERREGISTERSTATE.重新提交, registerFlow:REGISTERFLOW.完成第三步 },
        ];
    }

    let selectTitle = [];
    let selectConf = [];
    exportColumns.forEach( info=> {
        if (info.key == "省市区") {
            selectTitle.push("省", "市", "区");
            selectConf.push("sheng", "shi", "qu");
        } else {
            selectTitle.push(info.key);
            selectConf.push(info.value);
        }
    })
   
    let dbList = await find(TABLEENUM.用户表, selectParam, selectConf);
    let timeChnageList = ["joinTime", "birth"];
    let addList = ["sheng", "shi", "qu"];
    
    let dataList = [selectTitle];
    dbList.forEach(info => {
        let subList = [];
        for (let i = 0; i < selectConf.length; i++) {
            let key = selectConf[i];
            let value = info[key] || "";
            if (value) {
                if (timeChnageList.indexOf(key) != -1) value = moment(value).format("YYYY-MM-DD");
                else if (key == "isInput" || key == "isGracePeriod") value = value == true ? "是" : "否";
                else if (key == "memberState") value = changeEnumValue(MEMBERSTATE, value);
                else if (key == "certificateType") value = changeEnumValue(CERTIFICATETYPE, value);
                else if (key == "individualMemberType") value = changeEnumValue(INDIVIDUALMEMBERTYPE, value);
                else if (key == "unitMemberType") value = changeEnumValue(UNITMEMBERTYPE, value);
                else if (key == "yuanXiaoBanXueLeiXing") value = changeEnumValue(BANXUELEIXING, value);
                else if (key == "memberLevel") value = changeEnumValue(MEMBERLEVEL, value);
                else if (key == "sex") value = changeEnumValue(SEX, value);
                else if (key == "documentType") value = changeEnumValue(DOCUMENTTYPE, value);
                else if (key == "nation") value = changeEnumValue(NATION, value);
                else if (key == "education") value = changeEnumValue(EDUCATION, value);
                else if (key == "profCategory") value = changeEnumValue(PROFCATEGORY, value);
                else if (addList.indexOf(key) != -1) value = getCityNameByCode(value);
            }
            subList.push(value);
        }
        dataList.push(subList);
    });

    return {dataList};
}
