/**
 * 会费管理逻辑
 */

import moment = require("moment");
import { MEMBERSTATE, MEMBERTYPE, ORDEREXAMINE, ORDERSTATE, PAYMENTTYPE, RECEIPTCONFIRMATION, STATE, UNITMEMBERTYPE, USERREGISTERSTATE } from "../../config/enum";
import { TABLEENUM } from "../../data/models/model";
import { find, findCount, findOnce, findToPage, findToSort, findToSortToPage } from "../../data/select";
import { extractData } from "../../util/piecemeal";
import { changeEnumValue } from "../../util/verificationEnum";
import { BizError } from "../../util/bizError";
import { ERRORENUM } from "../../config/errorEnum";
import { updateOneData } from "../../data/update";
import { successResult } from "../../tools/system";
import { addOneData } from "../../data/add";



/**
 * 导出会费管理表格
 * @param param0 
 */
export async function outPutDataForExcel({type, files}) {
    if (type == 1) {
        //未缴费名单

    } else if (type == 2) {
        //已缴费名单

    } else if (type == 3) {
        //缴费期名单

    } else {
        //宽限期名单


    }

    return {dataList:[["测试", "测试2"]]};
}


/**
 * 已缴费列表 success
 * @param name 名称关键字：个人会员匹配真实姓名，单位会员匹配单位名称
 * @param memberType 会员类别 unitMemberType、individualMemberType  多选
 * 会员类别：个人【个人会员、专业会员】单位【院校、机构、其他】返回前端枚举：MEMBERTYPEECCENUM
 * @param documentId 身份证
 * @param phone 登录手机号
 * @param mail 单位/个人邮箱
 * @param joinStartTime 入会开始时间
 * @param joinEndTime 入会结束时间
 * @param memberLevel 会员级别/职务 多选
 * 会员级别/职务：【普通会员、理事会员、常务理事会员】
 * @param pageNumber 当前页
 */
export async function getPaid({name, memberType, documentId, phone, mail, joinStartTime, joinEndTime, memberLevel, pageNumber}) {
    const NowMs = new Date().valueOf();
    /**到期时间距离今天大于90天 */
    let selectParam:any = {
        lifespanEndTime:{"$gt":NowMs + (90 * 24 * 3600 * 1000)},
        isAdmin:STATE.否,
        isGracePeriod:STATE.否,
        userRegisterState:USERREGISTERSTATE.通过
    }

    if (name) {
        selectParam["$or"] = [
            {unitName:{"$regex":`${name}`}},
            {name:{"$regex":`${name}`}}
        ]
    }
    if (memberType.length) {
        if (memberType < UNITMEMBERTYPE.院校) {
            selectParam.individualMemberType = {"$in":memberType};
        } else {
            selectParam.unitMemberType = {"$in":memberType};
        }
    }
    if (documentId) selectParam.documentId = documentId; 
    if (phone) selectParam.phone = phone;
    if (mail) selectParam.mail = mail;
    if (joinStartTime) {
        selectParam["joinTime"] = {"$gt":joinStartTime};
    }
    if (joinEndTime) {
        if (!selectParam["joinTime"]) selectParam["joinTime"] = {};
        selectParam["joinTime"]["$lt"] = joinEndTime;
    }
    if (memberLevel.length) selectParam.memberLevel = {"$in":memberLevel};

    const SelectFiles = ["userId", "memberState", "unitName", "name", "loginId", "phone", "joinTime", "memberType", "lifespanStartTime", "lifespanEndTime", "memberLevel"];
    let dbList = await findToPage(TABLEENUM.用户表, selectParam, SelectFiles, pageNumber);
    let dataCount = await findCount(TABLEENUM.用户表, selectParam);

    let dataList = [];
    const itemFiles = ["userId", "memberState", "unitName", "name", "loginId", "phone", "joinTime", "memberType"];
    dbList.forEach(info => {
        let item:any = extractData(info, itemFiles);
        item.lifespanTime = `${moment(info.lifespanStartTime).format("YYYY-MM-DD")} 至 ${moment(info.lifespanEndTime).format("YYYY-MM-DD")}`;
        item.nextLifespanTime = "大于90天";
        item.joinTime = moment(item.joinTime).format("YYYY-MM-DD");
        item.memberState = changeEnumValue(MEMBERSTATE, item.memberState);
        item.memberType = changeEnumValue(MEMBERTYPE, item.memberType);
        dataList.push(item);
    });

    return {dataList, dataCount};
}

/**
 * 已缴费列表中的订单日志 success
 * @param id 会员列表返回的userId  
 */
export async function paidOrderList({id}) {
    let dbList = await findToSort(TABLEENUM.订单表, {userId:id}, {payTime:-1}, ["orderCycleStart", "orderCycleEnd", "money", "paymentMethod", "state"]);

    let dataList = [];
    dbList.forEach(info => {
        let {orderCycleStart, orderCycleEnd, money, paymentMethod, state} = info;
        let paymentMethodStr = '-';
        if ( state == ORDERSTATE.已支付 ) {
            paymentMethodStr = changeEnumValue(PAYMENTTYPE, paymentMethod);
        }
        dataList.push({
            orderCycle:`${moment(orderCycleStart).format("YYYY-MM-DD")}至${moment(orderCycleEnd).format("YYYY-MM-DD")}`,
            money,
            paymentMethod:paymentMethodStr,
            state:changeEnumValue(ORDERSTATE, state)
        });
    });

    return {dataList};
}


/**
 * 待缴费列表 success  缴费期列表
 * @param name 名称关键字：个人会员匹配真实姓名，单位会员匹配单位名称
 * @param memberType 会员类别 unitMemberType、individualMemberType  多选
 * 会员类别：个人【个人会员、专业会员】单位【院校、机构、其他】返回前端枚举：MEMBERTYPEECCENUM
 * @param documentId 身份证
 * @param phone 登录手机号
 * @param mail 单位/个人邮箱
 * @param joinStartTime 入会开始时间
 * @param joinEndTime 入会结束时间
 * @param memberLevel 会员级别/职务 多选
 * 会员级别/职务：【普通会员、理事会员、常务理事会员】
 * @param pageNumber 当前页 
 */
export async function unpaidList({name, memberType, documentId, phone, mail, joinStartTime, joinEndTime, memberLevel, pageNumber}) {
    const NowMs = new Date().valueOf();
    /**到期时间距离今天小于90天 */
    let selectParam:any = {
        lifespanEndTime:{"$lt":NowMs + (90 * 24 * 3600 * 1000), "$gt":NowMs},
        isAdmin:STATE.否,
        isGracePeriod:STATE.否,
        userRegisterState:USERREGISTERSTATE.通过
    }
    if (documentId) selectParam.documentId = documentId;
    if (phone) selectParam.phone = phone;
    if (mail) selectParam.mail = mail;
    if (memberLevel.length) selectParam.memberLevel = {"$in":memberLevel};
    if (name) {
        if (!selectParam["$and"]) selectParam["$and"] = [];
        selectParam["$or"] = [
            {unitName:{"$regex":`${name}`}},
            {name:{"$regex":`${name}`}}
        ]
    }
    if (joinStartTime) {
        selectParam["joinTime"] = {"$gt":joinStartTime};
    }
    if (joinEndTime) {
        if (!selectParam["joinTime"]) selectParam["joinTime"] = {};
        selectParam["joinTime"]["$lt"] = joinEndTime;
    }
    if (memberType.length) {
        if (memberType < UNITMEMBERTYPE.院校) {
            selectParam.individualMemberType = {"$in":memberType};
        } else {
            selectParam.unitMemberType = {"$in":memberType};
        }
    }
    

    const SelectFiles = ["userId", "memberState", "unitName", "loginId", "phone", "joinTime", "memberType", "lifespanStartTime", "lifespanEndTime"];
    // let dbList = await findToPage(TABLEENUM.用户表, selectParam, SelectFiles, pageNumber, 10);
    let dbList = await findToSortToPage(TABLEENUM.用户表, selectParam, SelectFiles, {joinTime:-1}, pageNumber);
    let dataCount = await findCount(TABLEENUM.用户表, selectParam);

    let dataList = [];
    const itemFiles = ["userId", "memberState", "unitName", "loginId", "phone", "joinTime", "memberType"];
    dbList.forEach(info => {
        let item:any = extractData(info, itemFiles);
        item.lifespanTime = `${moment(info.lifespanStartTime).format("YYYY-MM-DD")} 至 ${moment(info.lifespanEndTime).format("YYYY-MM-DD")}`;
        item.joinTime = `${moment(info.joinTime).format("YYYY-MM-DD")}`;
        item.nextLifespanTime = "不足90天";
        if (info.lifespanEndTime < ( NowMs + (30 * 24 * 3600 * 1000) ) ) item.nextLifespanTime = "不足30天";
    
        item.memberState = changeEnumValue(MEMBERSTATE, item.memberState);
        item.memberType = changeEnumValue(MEMBERTYPE, item.memberType);
        dataList.push(item);
    });

    return {dataList, dataCount};
}


/**
 * 会费管理-欠费 success
 * @param name 名称关键字：个人会员匹配真实姓名，单位会员匹配单位名称
 * @param memberType 会员类别 unitMemberType、individualMemberType  多选
 * 会员类别：个人【个人会员、专业会员】单位【院校、机构、其他】返回前端枚举：MEMBERTYPEECCENUM
 * @param documentId 身份证
 * @param phone 登录手机号
 * @param mail 单位/个人邮箱
 * @param joinStartTime 入会开始时间
 * @param joinEndTime 入会结束时间
 * @param memberLevel 会员级别/职务 多选
 * 会员级别/职务：【普通会员、理事会员、常务理事会员】
 * @param pageNumber 当前页
 */
export async function getRenewalPeriod({name, memberType, documentId, phone, mail, joinStartTime, joinEndTime, memberLevel, pageNumber}) {
    const NowMs = new Date().valueOf();
    let selectParam:any = {
        "$or":[
            { 
                isGracePeriod:STATE.否, 
                lifespanEndTime:{"$lt":NowMs}
            }, 
            {
                isGracePeriod:STATE.是, 
                lifespanEndTime:{"$lt":NowMs},
                gracePeriodEndTime:{"$lt":NowMs}
            }
        ],
        userRegisterState:USERREGISTERSTATE.通过,
        isAdmin:STATE.否,
    }
    if (name){
        if (!selectParam["$and"]) selectParam["$and"] = [];
        selectParam["$and"].push({
            "$or":[
                {unitName:{"$regex":`${name}`}},
                {name:{"$regex":`${name}`}}
            ]
        });
    }
    if (joinStartTime) {
        selectParam["joinTime"] = {"$gt":joinStartTime};
    }
    if (joinEndTime) {
        if (!selectParam["joinTime"]) selectParam["joinTime"] = {};
        selectParam["joinTime"]["$lt"] = joinEndTime;
    }
    if (memberType.length) {
        if (memberType < UNITMEMBERTYPE.院校) {
            selectParam.individualMemberType = {"$in":memberType};
        } else {
            selectParam.unitMemberType = {"$in":memberType};
        }
    }
    if (documentId) selectParam.documentId = documentId;
    if (phone) selectParam.phone = phone;
    if (mail) selectParam.mail = mail;
    if (memberLevel.length) selectParam.memberLevel = {"$in":memberLevel};

    const SelectFiles = ["userId", "memberState", "unitName", "loginId", "phone", "joinTime", "memberType", "lifespanStartTime", "lifespanEndTime", "name"];
    let dbList = await findToPage(TABLEENUM.用户表, selectParam, SelectFiles, pageNumber, 10);
    let dataCount = await findCount(TABLEENUM.用户表, selectParam);

    let dataList = [];
    const itemFiles = ["userId", "memberState", "unitName", "loginId", "phone", "joinTime", "memberType", "name"];
    dbList.forEach(info => {
        let item:any = extractData(info, itemFiles);
        item.lifespanTime = `${moment(info.lifespanEndTime).format("YYYY-MM-DD")}`;
        if (info.lifespanEndTime > ( NowMs - (30 * 24 * 3600 * 1000) ) ) item.nextLifespanTime = "过期30天内";
        else  {
            item.nextLifespanTime = "过期1年及以上";
        }
    
        item.joinTime = moment(item.joinTime).format("YYYY-MM-DD");
        item.memberState = changeEnumValue(MEMBERSTATE, item.memberState);
        item.memberType = changeEnumValue(MEMBERTYPE, item.memberType);
        dataList.push(item);
    });

    return {dataList, dataCount};
}


/**
 * 线下付款 会费管理 success
 * @param param0 
 */
export async function offlinePayment({orderId, paymentNum, offlinePaymentUrl }) {
    let orderInfo = await findOnce(TABLEENUM.订单表, {id:orderId});
    if (!orderInfo || !orderInfo.id) throw new BizError(ERRORENUM.目标数据不存在);
    if (orderInfo.state == ORDERSTATE.已支付 && orderInfo.confirmReceipt != RECEIPTCONFIRMATION.退回) throw new BizError(ERRORENUM.该订单已支付);

    let updateInfo = {
        paymentNum,
        offlinePaymentUrl,
        state:ORDERSTATE.已支付,
        paymentMethod:PAYMENTTYPE.线下支付,
        payTime:new Date().valueOf(),
        confirmReceipt:RECEIPTCONFIRMATION.待确认
    };

    await updateOneData(TABLEENUM.订单表, {id:orderId}, updateInfo);

    
    //添加审批日志
    let addLogInfo = {
        orderId,
        operationTime:new Date().valueOf(),
        operationBehavior:ORDEREXAMINE.用户提交,
        remarks:""
    };
    await addOneData(TABLEENUM.订单审批历史表, addLogInfo );

    return successResult();
}


/**
 * 多比订单时选择线下付款页面的选择缴费周期页
 * @param param0 
 * @returns 
 */
export async function selectManyOrderForUser({id}) {
    let notPayList = await find(TABLEENUM.订单表, {userId:id, state:ORDERSTATE.未支付},["orderCycleStart", "orderCycleEnd", "id"] );

    let dataList = [];

    notPayList.forEach(info => {
        let {orderCycleStart, orderCycleEnd, id} = info;

        dataList.push({
            key: `${moment(orderCycleStart).format("YYYY-MM-DD")} 至 ${moment(orderCycleEnd).format("YYYY-MM-DD")}`,
            value:id
        });
    });
    return {dataList};
}



/**
 * 设置宽限期 success
 * @param param0 
 */
export async function setGracePeriod({id, gracePeriodEndTime}) {
    let userInfo = await findOnce(TABLEENUM.用户表, {userId:id, isAdmin:STATE.否}, ["userId"]);
    if (!userInfo || !userInfo.userId) throw new BizError(ERRORENUM.目标数据不存在);

    let updateInfo = {
        isGracePeriod:STATE.是,
        gracePeriodEndTime
    };

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

    return successResult();
}


/**
 * 宽限期列表 success
 * @param name 名称关键字：个人会员匹配真实姓名，单位会员匹配单位名称
 * @param memberType 会员类别 unitMemberType、individualMemberType  多选
 * 会员类别：个人【个人会员、专业会员】单位【院校、机构、其他】返回前端枚举：MEMBERTYPEECCENUM
 * @param documentId 身份证
 * @param phone 登录手机号
 * @param mail 单位/个人邮箱
 * @param joinStartTime 入会开始时间
 * @param joinEndTime 入会结束时间
 * @param memberLevel 会员级别/职务 多选
 * 会员级别/职务：【普通会员、理事会员、常务理事会员】
 * @param pageNumber 当前页
 */
export async function getGracePeriod({name, memberType, documentId, phone, mail, joinStartTime, joinEndTime, memberLevel, duties, pageNumber}) {
    const NowMs = new Date().valueOf();
    /**到期时间距离今天大于90天 */
    let selectParam:any = {
        isGracePeriod:STATE.是, 
        gracePeriodEndTime:{"$gt":NowMs},
        isAdmin:STATE.否,
        userRegisterState:USERREGISTERSTATE.通过
    }
    if (name) {
        selectParam["$or"] = [
            {unitName:{"$regex":`${name}`}},
            {name:{"$regex":`${name}`}}
        ]
    }
    if (joinStartTime) {
        selectParam["joinTime"] = {"$gt":joinStartTime};
    }
    if (joinEndTime) {
        if (!selectParam["joinTime"]) selectParam["joinTime"] = {};
        selectParam["joinTime"]["$lt"] = joinEndTime;
    }
    if (memberType.length) {
        if (memberType < UNITMEMBERTYPE.院校) {
            selectParam.individualMemberType = {"$in":memberType};
        } else {
            selectParam.unitMemberType = {"$in":memberType};
        }
    }
    if (documentId) selectParam.documentId = documentId;
    if (phone) selectParam.phone = phone;
    if (mail) selectParam.mail = mail;
    if (memberLevel.length) selectParam.memberLevel = {"$in":memberLevel};

    const SelectFiles = [ "userId", "memberState", "unitName", "loginId", "phone", "joinTime", "memberType", "joinTime", "lifespanEndTime"];
    let dbList = await findToPage(TABLEENUM.用户表, selectParam, SelectFiles, pageNumber, 10);
    let dataCount = await findCount(TABLEENUM.用户表, selectParam);

    let dataList = [];
    // const itemFiles = ["userId", "memberState", "loginId", "phone", "joinTime", "memberType", "unitName"];
    dbList.forEach(info => {
        let dataInfo = {
            userId:info.userId,
            memberState:changeEnumValue(MEMBERSTATE, info.memberState),
            loginId:info.loginId,
            phone:info.phone,
            unitName:info.unitName,
            joinTime:`${moment(info.joinTime).format("YYYY-MM-DD")}`,
            lifespanTime:`${moment(info.lifespanEndTime).format("YYYY-MM-DD")}`,
            nextLifespanTime:"宽限期中",
            memberType:changeEnumValue(MEMBERTYPE, info.memberType)
        };

        dataList.push(dataInfo);
    });

    return {dataList, dataCount};
}


/**
 * 移除宽限期
 * @param id 宽限期列表返回的userId  
 * @returns 
 */
export async function delGracePeriod({id}) {
    let userInfo = await findOnce(TABLEENUM.用户表, {userId:id, isAdmin:STATE.否}, ["userId"]);
    if (!userInfo || !userInfo.userId) throw new BizError(ERRORENUM.目标数据不存在);
    if (userInfo.isGracePeriod) throw new BizError(ERRORENUM.该用户已在宽限期内);

    let updateInfo = {
        isGracePeriod:STATE.否,
        gracePeriodEndTime:0
    };

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

    return successResult();
}



/**
 * 个人欠费周期列表 
 * @param param0 
 */
export async function memberArrearsList({id}) {
    /**获取用户欠费的周期列表 包含id 周期 金额 */
    
    let dbList = await findToSort(TABLEENUM.订单表, {userId:id}, {orderCycleStart:1}, ["id", "orderCycleStart", "orderCycleEnd", "money"] );

    let dataList = [];
    dbList.forEach(info => {
        let {id, orderCycleStart, orderCycleEnd, money } = info;
        let renewalPeriod = `${moment(orderCycleStart).format("YYYY-MM-DD")}-${moment(orderCycleEnd).format("YYYY-MM-DD")}`;
        dataList.push({
            id, renewalPeriod, money
        })
    });

    return {dataList};
}