import {ApiCall, ApiReturn} from "tsrpc";
import {HongDianChange} from "../api_s2c/hongdian/fun";
import {taskType} from "../shared/protocols/task/type";
import {PublicShared} from "../shared/public/public";
import {PeijianFun} from "./peijian";
import {manager} from "./taskclass";

let taskDict = {};
const SHUJUKU = "task";

export class TaskFun {
    /**获取所有任务stype 注册监听使用 */
    static async getStypes() {
        let _con = G.gc.task;
        let _r = [];
        for (let index = 0; index < Object.keys(_con).length; index++) {
            const element = _con[Object.keys(_con)[index]];
            let _values = Object.values(element);
            _values.forEach(ele => {
                if (_r.indexOf(ele["stype"]) == -1) {
                    _r.push(ele["stype"]);
                }
            });
        }
        return _r;
    }

    static async addeventHanshu(index) {
        let _name = "Class_task_" + index;
        if (taskDict[_name]) return 1;
        let _tmp;
        try {
            _tmp = new (<any>manager)[_name]();
        } catch {
            return 0;
        }
        taskDict[index] = _tmp;
        return 2;
    }

    /**注册监听 */
    static async addevent() {
        let _stypes = [1, 999, 100, 101, 102, 103, 104, 105];
        for (let index = 0; index < _stypes.length; index++) {
            const element = _stypes[index];
            let _tmp = await this.addeventHanshu(element);
        }

        for (let index = 106; index < 900; index++) {
            let _tmp = await this.addeventHanshu(index);
            if (_tmp != 2) break;
        }
    }

    /**
     *
     * @param type 任务类型
     * @returns 相关类型任务的所有配置
     */
    static async getTaskConsByType(type: number) {
        let _taskCon: {};
        try {
            _taskCon = G.gc.task[type];
        } catch {
            _taskCon = {};
            console.log(`====== task type getcon error  task >>> >>> ${type}`);
        }
        return _taskCon;
    }

    /**
     *
     * @param type
     * @param taskid
     * @returns 获取任务配置
     */
    static async getTaskConByType(type: number, taskid: number) {
        let _taskCon: {};
        try {
            _taskCon = G.gc.task[type][taskid];
        } catch {
            _taskCon = {};
            console.log(`====== task getcon error  taskid >>> >>> ${taskid}`);
        }
        return _taskCon;
    }

    /**
     *
     * @param call
     * @param stype 任务stype
     * @param val 任务完成值
     * @param chkCall  检测回调
     * @param chkval  任务条件检测值
     * @param isinc 是否累加
     * 设置某种任务类型的nval
     * @param alchangeVal
     * @param arg
     */
    static async setTaskVal(call: ApiCall, stype: number, val: number, chkCall: Function, chkval: number = 0, isinc: number = 0, alchangeVal: Function, arg) {
        let uid = call.uid;
        // let _unFinish = await this.getFinishByStype(call, stype, { finish: 0, "$where": "return this.pval > this.nval" });
        //let _unFinish = await this.getFinishByStype(call, stype, {finish: 0});
        //_unFinish = _unFinish.filter(x => x.pval > x.nval)
        let _unFinish = await this.getFinishByStype(call, stype, {
            finish: 0, '$expr': {
                $gt: ["$pval", "$nval"]
            }
        });

        if (_unFinish.length == 0) return;
        for (let index = 0; index < _unFinish.length; index++) {
            const _task = _unFinish[index];
            let _taskCon = await this.getTaskConByType(_task["type"], _task["taskid"]);
            if (!_taskCon || Object.keys(_taskCon).length == 0) {
                // 策划改了任务 找不到 自动删除任务
                await G.mongodb.collection(SHUJUKU).deleteMany({uid: call.uid, taskid: _task["taskid"]});
                continue
            }

            let _pval = _taskCon["pval"];
            let _nval = _task["nval"];
            if (_nval >= _pval) continue;
            // 不符合任务要求
            if (!await chkCall(_taskCon["cond"], chkval, arg)) continue;

            // 根据需求改写
            val = await alchangeVal(call, _taskCon, val, arg);

            let _resVal: number;
            // 累加型
            if (isinc == 1) {
                _resVal = _nval + val;
            } else {  // 覆盖型
                if (val <= _nval) {
                    continue;
                } else {
                    _resVal = val;
                }
            }

            // 任务值上限检测
            _resVal = _resVal > _pval ? _pval : _resVal;
            // 设置任务
            let _setData = {nval: _resVal};
            let _where = {taskid: _task["taskid"]};
            await this.setTask(uid, _where, _setData);

            if (_resVal == _pval) {
                G.server.sendMsgByUid(call.uid, 'msg_s2c/TaskChange', {..._task, nval: _resVal})
            }
        }
    }

    /**
     * 检测任务刷新
     */
    static async refreshTask(call: ApiCall) {
        let _refre = Object.keys(await this.getDayReSetType());
        for (let index = 0; index < _refre.length; index++) {
            const _ttype = _refre[index];
            await this.reSetTaskByType(call, parseInt(_ttype));
        }
    }

    /**
     * 重置任务类型
     */
    static async getDayReSetType() {
        let _r = {
            1: "day",    // 每日任务
            // 2: "week"    // 主线任务
            // 3: "week"    // 成就任务
            4: "baoxiang"   // 每日任务的宝箱
        };
        return _r;
    }

    /**
     * 重置任务
     */
    static async reSetTaskByType(call: ApiCall, ttype: number) {
        let _dayType = await this.getDayReSetType();
        if (!_dayType[ttype]) {
            return;
        }
        // 重置每日任务
        if (ttype == 1 || ttype == 4) {
            let _zero = PublicShared.getToDayZeroTime(G.time);
            let _where = {retime: {$gte: _zero, $lte: _zero + 24 * 60 * 60 - 1}, type: ttype};
            let _tmp = await this.getUserTaksList(call.uid, _where);
            if (_tmp.length == 0) await this.resetDailyTask(call, ttype);
        }
    }

    /**
     * 重置每日任务
     */
    static async resetDailyTask(call: ApiCall, type: number = 1) {
        await this.delTasks(call.uid, {type: type});
        // 该限制改到红点检测判断，避免此处注释后，红点检测与账号创建初始化任务并发。
        // if (PublicShared.chkSameDate(call.conn.gud.cTime, G.time)) return;
        let _taskCons = await this.getTaskConsByType(type);
        let _taskInfo = [];
        for (let _taskid in _taskCons) {
            let task = _taskCons[_taskid];
            // 起步任务
            if (task.pretask == 0) {
                let _temp = await this.fmtTask(call, task);
                _taskInfo.push(_temp);
            }
        }
        await this.insertTasks(call, _taskInfo);
    }

    /**
     *
     * @param call
     * @param taskcon
     * @returns 任务初始完成值
     */
    static async getTaskNval(call: ApiCall, taskcon) {
        let _resVal: number;
        try {
            _resVal = await taskDict[taskcon.stype].getInitVal(call, taskcon);
        } catch {
            _resVal = 0;
        }
        return _resVal;
    }

    /**
     * 获取所有相关 stype 的任务
     * @param stype 任务stype
     */
    static async getFinishByStype(call: ApiCall, stype: number, where: {}) {
        // 任务刷新
        await this.refreshTask(call);
        Object.assign(where, {stype: stype});
        let _r = await this.getUserTaksList(call.uid, where);
        return _r;
    }

    /**
     * 获取所有相关 ttype 的任务
     * @param ttype 任务type
     */
    static async getFinishByTtype(call: ApiCall, ttype: number[], where: {}, ischk = 0) {
        // 任务刷新
        if (ischk == 1) await this.refreshTask(call);
        let _r = {};
        let _w = {};
        // 未完成任务的 type 也返回
        const _finishType = [1, 4];
        // Object.assign(where, { type: { $in: ttype } })
        for (let index = 0; index < ttype.length; index++) {
            const _type = ttype[index];
            Object.assign(_w, {type: _type, ...where});
            if (_finishType.indexOf(_type) != -1) {
                delete _w["finish"];
            }
            let _tmp = await this.getUserTaksList(call.uid, _w);
            _r[_type] = _tmp;
        }
        return _r;
    }

    /**
     * 格式化任务数据
     * @param call
     * @param task 任务配置
     */
    static async fmtTask(call: ApiCall, task: { stype: number, type: number, id: number, pval: number; }) {
        let _nt = G.time;
        let _r: taskType = {
            stype: task.stype,
            type: task.type,
            taskid: task.id,
            pval: task.pval,
            nval: await this.getTaskNval(call, task),
            finish: 0,
            lasttime: _nt,
            retime: _nt,
            uid: call.uid
        };
        return _r;
    }

    /**
     * 检测生成后续任务
     * @param call
     * @param _follow 后续任务id
     * @param _task 任务数据
     * @returns 新的任务
     */
    static async setTaskInfo(call: ApiCall, _follow: number, _task: { type: number; }) {
        let newTask: taskType;
        // 新任务配置
        let _ftaskCon = await TaskFun.getTaskConByType(_task["type"], _follow);
        if (Object.keys(_ftaskCon).length > 0) {
            // @ts-ignore
            newTask = await TaskFun.fmtTask(call, _ftaskCon);
            // 插入任务
            await TaskFun.insertTasks(call, [newTask]);
        }
        if (newTask["_id"]) delete newTask["_id"];
        return newTask;
    }

    /**
     * 更新主线任务
     * @returns 新的任务
     * @param call
     */
    static async updateMainTask(call: ApiCall) {
        let data = await G.mongodb.collection(SHUJUKU).findOne({uid: call.uid, type: 2, finish: 0});

        let _ftaskCon = await TaskFun.getTaskConByType(2, data.taskid);
        // @ts-ignore
        let newTask = await TaskFun.fmtTask(call, _ftaskCon);

        G.mongodb.collection(SHUJUKU).updateOne({
            uid: call.uid,
            type: 2,
            finish: 0,
            taskid: data.taskid
        }, {$set: {...newTask, nval: data.nval || newTask.nval, retime: data.retime,}}, {upsert: true})
    }

    /**
     * 生成所有任务
     */
    static async generateAllTask(call: ApiCall) {
        let _r = await G.mongodb.collection(SHUJUKU).count({uid: call.uid});
        if (_r > 0) return;
        let _taskInfo = [];
        let _con = G.gc.task;
        for (let _type in _con) {
            for (let _taskid in _con[_type]) {
                let task = _con[_type][_taskid];
                // 起步任务
                if (task.pretask == 0) {
                    let _temp = await this.fmtTask(call, task);
                    _taskInfo.push(_temp);
                }
            }
        }

        await this.insertTasks(call, _taskInfo);
    }

    /**生成指定类型任务-初始化 */
    static async reInitTask(call: ApiCall, type: string) {
        // 查询类型任务是否存在
        let _r = await G.mongodb.collection(SHUJUKU).count({uid: call.uid, type: ~~type});
        let _taskInfo = [];
        if (_r == 0) {
            let _con = G.gc.task;
            // 数据不存在，未初始化，执行初始化
            for (let _taskid in _con[type]) {
                let task = _con[type][_taskid];
                if (task.pretask == 0) {
                    let _temp = await this.fmtTask(call, task)
                    _taskInfo.push(_temp);
                }
            }
        }
        _taskInfo.length > 0 && await this.insertTasks(call, _taskInfo);
        return _taskInfo;
    }

    /**
     * 获取任务列表
     */
    static async getUserTaksList(uid: string, where: {}) {
        // type : 1 主线  2 成就  3 每日
        Object.assign(where, {uid: uid});
        let _taskInfo = await G.mongodb.collection(SHUJUKU).find(where).toArray();
        _taskInfo.forEach(e => {
            if (e._id) delete e._id;
        });
        return _taskInfo;
    }

    /**
     * 删除相关任务
     */
    static async delTasks(uid: string, where: { type: number; }) {
        Object.assign(where, {uid: uid});
        await G.mongodb.collection(SHUJUKU).deleteMany(where);
    }

    /**
     * 批量插入任务
     * @param call
     * @param _tasks
     */
    static async insertTasks(call: ApiCall, _tasks: taskType[]) {
        if (_tasks.length == 0) {
            return;
        }
        await G.mongodb.collection(SHUJUKU).insertMany(_tasks);

        _tasks.map(i => {
            if (i.type == 2) {
                G.server.sendMsgByUid(call.uid, 'msg_s2c/TaskChange', i)
            }
        })

        // await G.mongodb.collection(SHUJUKU).updateMany(
        //     { uid: uid },
        //     _tasks
        // );
    }

    /**
     * 设置单个任务值
     */
    static async setTask(uid: string, where: {}, setData: {}) {
        if (Object.keys(setData).length == 0) {
            return;
        }
        Object.assign(where, {uid});
        setData = {$set: setData};
        await G.mongodb.collection(SHUJUKU).updateOne(where, setData);
    }

    /**红点 */
    static async getHongDian(call: ApiCall) {
        let _res = {
            show: false,
            val: {
                tasktypes: []
            }
        };
        // 如果是创建当天，不跑红点刷新
        if (!PublicShared.chkSameDate(call.conn.gud.cTime, G.time)) await this.refreshTask(call)
        const _ttype = {
            1: [1, 4],    // 每日
            2: [2],       // 主线任务
            3: [3]     // 成就  删掉 type 5 的成就宝箱任务
        };
        for (let index = 0; index < Object.keys(_ttype).length; index++) {
            const element = Object.keys(_ttype)[index];
            if ((element == "1" || element == "3") && call.conn.gud.lv < 7) continue;
            let _values: number[] = _ttype[element];
            let _where: {} = {
                uid: call.uid, type: {$in: _values}, finish: 0, '$expr': {
                    $lte: ["$pval", "$nval"]
                }
            };

            //let taskArr = await G.mongodb.collection(SHUJUKU).find(_where).toArray();
            let count = await G.mongodb.collection(SHUJUKU).count(_where);
            //let _tmp = taskArr.filter(x => x.pval <= x.nval)
            //if (_tmp.length) {
            if (count > 0) {
                _res.show = true;
                _res.val.tasktypes.push(element);
            }
        }
        return _res;
    }
}

export class TaskAllEmitFun {
    // 所有任务监听执行
    static async allEmit(node: {
        call: ApiCall<any, any, any>;
        return: ApiReturn<any>;
    }) {
        if (node.call.service.name == 'sign/GetPrize' && node.return.isSucc) {
            // 签到一次
            G.emit("Class_task_100", 'Class_task_100', node.call, 1, 0);
        }
        if (node.call.service.name == 'hero/LvUp' && node.return.isSucc) {
            // 升级一次干部
            G.emit("Class_task_101", 'Class_task_101', node.call, 1, 0);
        }
        if (node.call.service.name == 'shop/Buy' && node.return.isSucc) {
            let _val = node.call.req.buyNum ? node.call.req.buyNum : 1;
            if (node.call.req.shopId == "1") {
                // 杂货铺购买 n 次
                G.emit("Class_task_102", 'Class_task_102', node.call, _val, 0);
            }
            // 商店购买 n 次道具
            G.emit("Class_task_119", 'Class_task_119', node.call, _val, 0);
            if (node.call.req.shopId == "9") {
                // 获得 x 个 配置颜色 配件  后面复写数值
                G.emit("Class_task_137", 'Class_task_137', node.call, 1, 0, node.call.return.res.prize);
            }
        }
        if (node.call.service.name == 'task/Finsh' && node.return.isSucc) {
            if (node.call.return.res.task.type == 1) {
                // 日常任务完成 n 次
                G.emit("Class_task_999", 'Class_task_999', node.call, 1, 0);
            }
            if (node.call.return.res.task.type == 3) {
                // 成就任务完成 n 次
                G.emit("Class_task_105", 'Class_task_105', node.call, 1, 0);
            }
        }
        if (node.call.service.name == 'task/AllFinsh' && node.return.isSucc) {
            let _val = node.call.return.res.finishtask.length;
            if (node.call.req.type == 1 && _val != 0) {
                // 日常任务完成 n 次
                G.emit("Class_task_999", 'Class_task_999', node.call, _val, 0);
            }
            if (node.call.req.type == 3 && _val != 0) {
                // 成就任务完成 n 次
                G.emit("Class_task_105", 'Class_task_105', node.call, _val, 0);
            }
        }
        // 多加一次经验变化检测，防止出现等级达到但任务未完成的情况
        if (node.call.eventMsg && node.call.eventMsg["msg_s2c/PlayerChange"] &&
            (node.call.eventMsg["msg_s2c/PlayerChange"].lv || node.call.eventMsg["msg_s2c/PlayerChange"].nexp)) {
            // 玩家升级
            let _lv = node.call.conn.gud.lv;
            G.emit("Class_task_104", 'Class_task_104', node.call, _lv, 0);
            if (node.call.eventMsg["msg_s2c/PlayerChange"].lv) HongDianChange.sendChangeKey(node.call.uid, ['jijinhd'])
        }
        if (node.call.service.name == 'tanxian/Fight' && node.return.isSucc) {
            let _val = node.call.conn.gud.mapId;
            // 玩家通关主线关卡 n 次
            G.emit("Class_task_1", 'Class_task_1', node.call, _val, 0);
            // 探险进行 n 次战斗 不管输赢
            G.emit("Class_task_120", 'Class_task_120', node.call, 1, 0);
        }
        if (node.call.service.name == 'hero/LvUp' && node.return.isSucc) {
            let _val = node.call.return.res.lv;
            let usertasklog = await G.mongodb.collection('playerInfo', 'usertasklog').findOne({
                uid: node.call.conn.uid,
                type: 'usertasklog'
            });
            if (_val > (usertasklog?.maxherolv | 0)) {
                await G.mongodb.collection('playerInfo', 'usertasklog').updateOne({
                        uid: node.call.conn.uid,
                        type: 'usertasklog'
                    },
                    {$set: {maxherolv: _val}});
            }
            // 干部等级达到 n 级
            G.emit("Class_task_106", 'Class_task_106', node.call, _val, 0);
        }
        if (node.call.service.name == 'hero/ChangePos' && node.return.isSucc) {
            // if (node.call.req.state == 'set') {
            //     let _val = Object.values(node.call.return.res).filter(v => { return v; }).length;
            //     G.emit("Class_task_107", 'Class_task_107', node.call, _val, 0);
            // }
            let _val = Object.values(node.call.return.res).filter(v => {
                return v;
            }).length;
            G.emit("Class_task_107", 'Class_task_107', node.call, _val, 0);
        }
        if (node.call.service.name == 'hero/JinJie' && node.return.isSucc) {
            let _val = 0;   // 后面有复写
            G.emit("Class_task_108", 'Class_task_108', node.call, _val, 0);
        }

        if (node.call.service.name == 'chat/Send' && node.return.isSucc) {
            if (node.call.req.type == 'local') {
                // 综合聊天1次
                G.emit("Class_task_109", 'Class_task_109', node.call, 1, 0);
            }
        }

        if (node.call.service.name == 'gongyu/xunlianjihua/UpSkill' && node.return.isSucc) {
            // 升级 n 次训练技能
            G.emit("Class_task_110", 'Class_task_110', node.call, 1, 0);
        }

        if (node.call.service.name == 'equip/LvUp' && node.return.isSucc) {
            // 装备强化 n 次
            G.emit("Class_task_111", 'Class_task_111', node.call, node.call.return.res.addlv, 0);
            // 装备强化到 n 级
            let _val = node.call.return.res.lv;
            let usertasklog = await G.mongodb.collection('playerInfo', 'usertasklog').findOne({
                uid: node.call.conn.uid,
                type: 'usertasklog'
            });
            if (_val > (usertasklog?.maxequiplv | 0)) {
                await G.mongodb.collection('playerInfo', 'usertasklog').updateOne({
                        uid: node.call.conn.uid,
                        type: 'usertasklog'
                    },
                    {$set: {maxequiplv: _val}});
            }
            G.emit("Class_task_112", 'Class_task_112', node.call, _val, 0);
            // 有 n 件强化 配置 等级装备   后面复写正确值
            G.emit("Class_task_113", 'Class_task_113', node.call, 0, 0);
        }

        if (node.call.service.name == 'equip/OneKeyLvUp' && node.return.isSucc) {
            // 装备强化 n 次
            let _qhNum = Object.values(node.call.return.res.posLvUp).sum();
            G.emit("Class_task_111", 'Class_task_111', node.call, _qhNum, 0);
            // 装备强化到 n 级
            let _val = Object.values(node.call.return.res.log).max();
            G.emit("Class_task_112", 'Class_task_112', node.call, _val, 0);
            // 更新强化等级
            let usertasklog = await G.mongodb.collection('playerInfo', 'usertasklog').findOne({
                uid: node.call.conn.uid,
                type: 'usertasklog'
            });
            if (_val > (usertasklog?.maxequiplv | 0)) {
                await G.mongodb.collection('playerInfo', 'usertasklog').updateOne({
                        uid: node.call.conn.uid,
                        type: 'usertasklog'
                    },
                    {$set: {maxequiplv: _val}});
            }
            // 有 n 件强化 配置 等级装备   后面复写正确值
            G.emit("Class_task_113", 'Class_task_113', node.call, 0, 0);
        }

        if (node.call.eventMsg && node.call.eventMsg["msg_s2c/HeroChange"]) {
            // 获得 n 个 配置颜色 干部
            let array = Object.values(node.call.eventMsg["msg_s2c/HeroChange"]);
            for (let index = 0; index < array.length; index++) {
                const element = array[index];
                if (element.heroId && element.lv == 1) {
                    let _color = G.gc.hero[element.heroId].colour;
                    G.emit("Class_task_114", 'Class_task_114', node.call, 1, _color);
                    await G.mongodb.collection('playerInfo', 'usertasklog').updateOne({
                            uid: node.call.conn.uid,
                            type: 'usertasklog'
                        },
                        {$inc: G.mongodb.createTreeObj({key: `herocolor.${_color}`, val: 1})});
                }
            }
        }
        if (node.call.eventMsg && node.call.eventMsg["msg_s2c/EquipChange"]) {
            // 获得 n 个 配置颜色 装备
            let array = Object.values(node.call.eventMsg["msg_s2c/EquipChange"]);
            // 获取task配置装备数量
            let usertasklog = await G.mongodb.collection('playerInfo', 'usertasklog').findOne({
                uid: node.call.uid,
                type: 'usertasklog'
            })
            for (let index = 0; index < array.length; index++) {
                const element = array[index];
                if (element.equipId && element.lv == 0 && !element.wearaId) {
                    let _color = G.gc.equip[element.equipId].colour;
                    // 增加相关等级装备数量
                    if (!usertasklog.equipcolor[_color]) usertasklog.equipcolor[_color] = 0
                    usertasklog.equipcolor[_color]++
                    G.emit("Class_task_115", 'Class_task_115', node.call, 1, _color);
                }
            }
            // 更新表内装备数量，重置任务时会依据该内容计算已获得数量。
            await G.mongodb.collection('playerInfo', 'usertasklog').updateOne({
                uid: node.call.uid,
                type: 'usertasklog'
            }, {$set: {equipcolor: usertasklog.equipcolor}})
        }
        // if (node.call.service.name == 'chongzhi/Open' && node.return.isSucc) {
        //     // 累计充值 n 钻石  数量后面复写
        //     G.emit("Class_task_116", 'Class_task_116', node.call, 1, 0);
        // }
        if (node.call.service.name == 'dixiaqianzhuang/Qf' && node.return.isSucc) {
            // 使用 n 次点金
            let _val = Object.values(node.call.return.res.bj).sum();
            G.emit("Class_task_117", 'Class_task_117', node.call, _val, 0);
        }
        if (node.call.service.name == 'jiuba/Lottery' && node.return.isSucc) {
            // 酒吧招募 n 次
            let _val = node.call.req.type;
            G.emit("Class_task_118", 'Class_task_118', node.call, _val, 0);
        }
        if (node.call.service.name == 'gonghui/Jx' && node.return.isSucc) {
            // 势力捐献进行 n 次捐献
            G.emit("Class_task_121", 'Class_task_121', node.call, 1, 0);
            // 势力 配置xx 捐献进行 n 次捐献
            G.emit("Class_task_142", 'Class_task_142', node.call, 1, node.call.req.index);
        }
        if ((node.call.service.name == 'equip/Wear' || node.call.service.name == 'equip/OneKeyWear') && node.return.isSucc) {
            // 穿戴X件以上装备
            G.emit("Class_task_143", 'Class_task_143', node.call, 1, 0);
        }
        if ((node.call.service.name == 'friend/Apply' || node.call.service.name == 'friend/Gift') && node.return.isSucc) {
            // 进行x次好友申请或送礼
            let usertasklog = await G.mongodb.collection('playerInfo', 'usertasklog').findOne({
                uid: node.call.conn.uid,
                type: 'usertasklog'
            });

            let _val = 1
            if (node.call.service.name == 'friend/Gift') {
                _val = (node.call.return.res.change.sendGift?.length || 0)
            }
            _val = _val + usertasklog.friendAsk + usertasklog.sendGift
            await G.mongodb.collection('playerInfo', 'usertasklog').updateOne({
                    uid: node.call.conn.uid,
                    type: 'usertasklog'
                },
                {$set: {friendAsk: _val}});
            G.emit("Class_task_144", 'Class_task_144', node.call, 1, 0);
        }
        if (node.call.service.name == 'tanxian/FastGuaJi' && node.return.isSucc) {
            // 进行 n 次快速探险
            G.emit("Class_task_122", 'Class_task_122', node.call, 1, 0);
        }
        if (node.call.service.name == 'tanxian/GuaJi' && node.return.isSucc) {
            // 领取 n 次挂机收益
            G.emit("Class_task_145", 'Class_task_145', node.call, 1, 0);
        }
        if (node.call.service.name == 'jjc/Fight' && node.return.isSucc) {
            // 竞技场中挑战 n 次对手
            G.emit("Class_task_123", 'Class_task_123', node.call, 1, 0);
        }
        if ((node.call.service.name == 'pata/Fight' || node.call.service.name == 'pata/SaoDang') && node.return.isSucc) {
            let _val = node.call.service.name == 'pata/Fight' ? 1 : node.call.req.num;
            // 斩草除根进行 n 次通关或扫荡
            G.emit("Class_task_124", 'Class_task_124', node.call, _val, 0);
        }
        if (node.call.service.name == 'meirishilian/Fight' && node.return.isSucc) {
            // 挑战 n 次物资筹集
            G.emit("Class_task_125", 'Class_task_125', node.call, 1, 0);
        }
        if (node.call.service.name == 'kuangdong/ZhanLing' && node.return.isSucc) {
            // 地盘争夺抢夺或战领 n 次
            G.emit("Class_task_126", 'Class_task_126', node.call, 1, 0);
        }

        if (node.call.service.name == 'qjzzd/Fight' && node.return.isSucc) {
            // 挑战 n 次清缴真主党
            G.emit("Class_task_127", 'Class_task_127', node.call, 1, 0);
        }

        if (node.call.service.name == 'jjc/Fight' && node.return.isSucc) {
            // 竞技场首次达到x名  后面复写
            G.emit("Class_task_129", 'Class_task_129', node.call, 1, 0);
        }

        if (node.call.service.name == 'jjc/Open' && node.return.isSucc) {
            // 竞技场首次达到x名  后面复写
            G.emit("Class_task_129", 'Class_task_129', node.call, 1, 0);
        }

        if (node.call.service.name == 'peijiancangku/Deal' && node.return.isSucc) {
            if (node.call.req.num == 10) {
                // 在仓库使用 x 次交易10次(交易一次不算)
                G.emit("Class_task_130", 'Class_task_130', node.call, 1, 0);
            }
            // 在仓库交易x次
            G.emit("Class_task_141", 'Class_task_141', node.call, node.call.req.num, 0)
            // 获得 x 个 配置颜色 配件  后面复写数值
            G.emit("Class_task_137", 'Class_task_137', node.call, 1, 0, node.call.return.res.prize);
        }

        if (node.call.service.name == 'peijiancangku/Jump' && node.return.isSucc) {
            // 在仓库使用 x 次指定高级仓库
            G.emit("Class_task_131", 'Class_task_131', node.call, 1, 0);
        }

        if (node.call.service.name == 'gonglukuangbiao/Fight' && node.return.isSucc) {
            // 进行 x 次公路狂飙
            G.emit("Class_task_132", 'Class_task_132', node.call, 1, 0);
        }

        if (node.call.service.name == 'jiaotang/Lottery' && node.return.isSucc) {
            // 进行 x 教会招募
            let _val = node.call.req.type;
            G.emit("Class_task_133", 'Class_task_133', node.call, _val, 0);
        }
        if (node.call.service.name == 'item/Use' && node.return.isSucc) {
            let itemConf = G.gc.item[node.call.req.itemId];
            if ([3, 4].includes(itemConf.type)) {
                // 进行 x 次英雄合成
                let prizeList = node.return.res.prize
                //console.log(prizeList)

                let heroList = prizeList.filter(i => i.a == 'hero')
                let equipList = prizeList.filter(i => i.a == 'equip')
                if (heroList.length) {
                    let _val = heroList.reduce((c, r) => c + r.n, 0)
                    G.emit("Class_task_146", 'Class_task_146', node.call, _val, 0);
                }
                if (equipList.length) {
                    let _val = equipList.reduce((c, r) => c + r.n, 0)
                    G.emit("Class_task_147", 'Class_task_147', node.call, _val, 0);
                }
            }
        }

        if (node.call.service.name == 'gongyu/mingdao/Repair' && node.return.isSucc) {
            // 修复 x 次名刀
            let _val = node.call.req.num;
            G.emit("Class_task_136", 'Class_task_136', node.call, _val, 0);
            // todo 统计藏品修复胶，此处只是临时处理，防止线上任务数据出错，正确做法是，统计修复胶的消耗，走136任务的统计
            G.emit("Class_task_134", 'Class_task_134', node.call, _val, 0, []);
        }

        if (node.call.service.name == 'peijian/LvUp' && node.return.isSucc) {
            // 配件升级 xx 次
            let _val = node.call.req.num;
            G.emit("Class_task_138", 'Class_task_138', node.call, _val, 0);
        }

        if (node.call.service.name == 'peijian/OneKeyLvUp' && node.return.isSucc) {
            // 配件升级 xx 次
            let _val = node.call.return.res.sjnum;
            G.emit("Class_task_138", 'Class_task_138', node.call, _val, 0);
        }

        if (node.call.service.name == 'gongyu/zuozhanjihua/SetSkill' && node.return.isSucc) {
            // 主角的家布置计划上阵{1}个技能
            let _val = R.compose(R.filter(i => !!i), R.values())(node.call.conn.gud.fightSkills).length;
            G.emit("Class_task_148", 'Class_task_148', node.call, _val, 0);
        }

        if (node.call.service.name == 'pata/Fight' && node.return.isSucc) {
            // 黑暗塔通关至{1}层
            let _val = node.return.res.mydata.lv - 1;
            G.emit("Class_task_149", 'Class_task_149', node.call, _val, 0);
        }

        if (node.call.service.name == 'weixiuchang/UpLv' && node.return.isSucc) {
            // 维修厂进行{1}次安装或一键安装
            G.emit("Class_task_150", 'Class_task_150', node.call, 1, 0);
        }

        if (node.call.service.name == 'zhanqianbushu/Select' && node.return.isSucc) {
            // 出战阵型启用任意阵型
            let _val = node.call.conn.gud.selectMatrix ? 1 : 0;
            G.emit("Class_task_151", 'Class_task_151', node.call, _val, 0);
        }

        if (node.call.service.name == 'zhanqianbushu/Up' && node.return.isSucc) {
            // 升级{1}次阵型
            let _val = R.compose(R.sum(), R.values())(node.call.conn.gud.matrix);
            G.emit("Class_task_152", 'Class_task_152', node.call, _val, 0);
        }

        if (node.call.service.name == 'yongbingzhuzhan/Handle' && node.return.isSucc) {
            // 干部助战上阵{1}个干部
            let _val = node.call.conn.gud.helpHeros.length;
            G.emit("Class_task_153", 'Class_task_153', node.call, _val, 0);
        }

        if (node.call.service.name == 'event/yuandan/DMRec' && node.return.isSucc) {
            // 今日参与{1}次抓娃娃小游戏
            G.emit("Class_task_158", 'Class_task_158', node.call, 1, 0);
        }


        if (node.call.eventMsg && node.call.eventMsg["msg_s2c/PeijianChange"] && node.call.eventMsg["msg_s2c/PeijianChange"]) {
            let _change = node.call.eventMsg["msg_s2c/PeijianChange"];

            // 配件记录信息
            let usertasklog = await G.mongodb.collection('playerInfo', 'usertasklog').findOne({
                uid: node.call.conn.uid,
                type: 'usertasklog'
            });
            let _setData = {$set: {}};    // 更新配件记录

            let peijianCon = G.gc.peijian;
            let _lv = 0;
            for (let index = 0; index < Object.keys(_change).length; index++) {
                const _tmp = Object.keys(_change)[index];
                let element = _change[_tmp];
                if (!element.lv) continue;

                if (element.lv > (usertasklog?.maxpeijianlv || 0)) {
                    _lv = element.lv;
                    _setData["$set"]["maxpeijianlv"] = _lv;
                }

                // 配件颜色信息
                let _peijian = await PeijianFun.getPeijian(node.call, _tmp);
                let _color = peijianCon[_peijian.peijianId].colour;
                if (element.lv > (usertasklog?.peijiancolor ? [_color] : 0)) {
                    // if (!_setData["$set"]["peijiancolor"]) _setData["$set"]["peijiancolor"] = {}
                    _setData["$set"][`peijiancolor.${_color}`] = element.lv;
                    // 配置 配件升级到 xx 级（颜色限制）
                    G.emit("Class_task_140", 'Class_task_140', node.call, element.lv, _color);
                }
            }

            if (Object.keys(_setData["$set"]).length > 0) {
                // 配件升级到 xx 级
                if (_setData["$set"]["maxpeijianlv"]) G.emit("Class_task_139", 'Class_task_139', node.call, _lv, 0);
                await G.mongodb.collection('playerInfo', 'usertasklog').updateOne({
                        uid: node.call.conn.uid,
                        type: 'usertasklog'
                    },
                    _setData);
            }
        }

    }
}

// TaskFun.addevent()

