import { ApiCall, ApiReturn } from 'tsrpc';
import { ServiceType } from '../shared/protocols/serviceProto';
import { ResAllFinsh } from '../shared/protocols/task/PtlAllFinsh';

type taskType = 'day' | 'week' | 'round';

export class ZhanLingTasks {
    static addListener(node: {
        call: ApiCall<any, any, any>;
        return: ApiReturn<any>;
    }) {
        let res = node.return.res;
        let call = node.call;
        let args: { type: taskType; key: string; val?: number; }[] = [];


        switch (call.service.name as keyof ServiceType['api']) {
            // case 'user/Login':
            //     args.push({ type: 'day', key: call.service.name });
            //     break;
            case 'gonghui/Jx':
                args.push({ type: 'day', key: call.service.name });
                if (call.req.index == G.gc.shili_com.juanxian.length - 1) args.push({ type: 'week', key: `${call.service.name}/${call.req.index}` });
                break;
            case 'pata/Fight':
            case 'pata/SaoDang':
                args.push({ type: 'day', key: 'pata' });
                break;
            case 'jjc/Fight':
                args.push({ type: 'day', key: call.service.name });
                break;
            case 'task/Finsh':
                if (Object.keys(G.gc.task['1']).includes(call.req.taskid.toString())) args.push({ type: 'week', key: 'task_finish_type_1' });
                break;
            case 'task/AllFinsh':
                if (call.req.type == 1 && (res as ResAllFinsh).finishtask.length > 0) {
                    args.push({ type: 'week', key: 'task_finish_type_1', val: (res as ResAllFinsh).finishtask.length });
                }
                break;
            case 'tanxian/FastGuaJi':
                args.push({ type: 'week', key: call.service.name });
                args.push({ type: 'round', key: call.service.name });
                break;
            case 'dixiaqianzhuang/Qf':
                args.push({ type: 'week', key: call.service.name, val: call.req.type });
                break;
            case 'jiuba/Lottery':
                args.push({ type: 'round', key: call.service.name, val: call.req.type });
                break;
            case 'gonglukuangbiao/Fight':
                args.push({ type: 'round', key: call.service.name, val: call.req.type });
                break;
        }

        args.forEach(arg => {
            this.addLog(call.uid, arg.type, arg.key, arg.val || 1);
        });
    }
    static addLog(uid: string, type: taskType, key: string, val = 1) {
        G.mongodb.collection('zhanling').updateOne(
            { uid: uid, type: type },
            { $inc: G.mongodb.createTreeObj({ key: `data.${key}`, val: val }) },
            { upsert: true }
        );

        G.server.sendMsgByUid(uid, 'msg_s2c/HongDianChange', ['zhuishalinghd']);
    }
    static async getLog(uid: string, arg: { type: taskType; key: string; }): Promise<number>;
    static async getLog(uid: string, arg: { type: taskType; key: string; }[]): Promise<k_v<number>>;
    static async getLog(uid: string, args: any) {
        let obj: k_v<number> = {};
        let arr = [].concat(args) as { type: taskType; key: string; }[];
        let dbs = await G.mongodb.collection('zhanling').find({ uid: uid }).toArray();
        let fmt = Object.fromEntries(dbs.map(db => [db.type, db]));

        for (let arg of arr) {
            obj[`${arg.type}@${arg.key}`] = fmt[arg.type]?.data?.[arg.key] || 0;
        }

        if (args instanceof Array) return obj;
        else if (args.type) return obj[`${args.type}@${args.key}`];
        else return obj[args.key];
    }
    static clearLog(uid: string, type: taskType) {
        G.mongodb.collection('zhanling').updateOne(
            { uid: uid, type: type },
            { $set: type == 'day' ? { data: { 'user/Login': 1, 'tqexp': 1 } } : { data: {} } },
            { upsert: true }
        );
    }
}