import {ApiCall} from "tsrpc";
import {ZhanLingTasks} from '../../../public/zhanling';
import {ReqOpen, ResOpen} from "../../../shared/protocols/event/zhanling/PtlOpen";
import {player} from '../../../shared/protocols/user/type';
import {PublicShared} from '../../../shared/public/public';

export default async function (call: ApiCall<ReqOpen, ResOpen>) {
    let zls = await G.mongodb.collection('scheduler').findOne({type: 'zhanling'});
    let data = await G.mongodb.cEvent('zhanling').findOne({uid: call.uid, type: 'zhanling'});

    if (!data || data.round != (zls?.round | 0)) {
        let set = {
            lv: 1,
            exp: 0,
            rec: {},
            isPay: false,
            taskRec: [],
            round: zls?.round || 0,
            reWeekTime:G.time,
            refreshTime: G.time,
        }

        data = (await G.mongodb.cEvent('zhanling').findOneAndUpdate({
            uid: call.uid,
            type: 'zhanling'
        }, {$set: set}, {upsert: true, returnDocument: 'after'})).value;
    }

    if (PublicShared.getToWeekMondayZeroTime() > data.reWeekTime || PublicShared.getToDayZeroTime() > data.refreshTime) {
        let set: any = {taskRec: []};

        let reType = [];
        if (PublicShared.getToWeekMondayZeroTime() > data.reWeekTime) {
            set.reWeekTime = G.time;
            reType.push("week");
        }

        if (PublicShared.getToDayZeroTime() > data.refreshTime) {
            set.refreshTime = G.time;
            reType.push("day")
        }

        for (let idx of data.taskRec) {
            if (reType && reType.indexOf(G.gc.zhanling.task[idx].type) == -1) {
                set.taskRec.push(idx);
            }
        }

        data = (await G.mongodb.cEvent('zhanling').findOneAndUpdate({
            uid: call.uid,
            type: 'zhanling'
        }, {$set: set}, {upsert: true, returnDocument: 'after'})).value;
    }

    let tasks = G.gc.zhanling.task.map(t => {
        return {type: t.type as 'day' | 'week' | 'round', key: t.taskId};
    });
    let taskFinished = await ZhanLingTasks.getLog(call.uid, tasks);


    let result: { rec: {}; isPay: boolean; taskRec: any[]; taskFinished: k_v<number>; refreshTime: number; lv: number; exp: number, nextRoundTime: number } = {
        ...data,
        taskFinished: taskFinished,
        nextRoundTime: PublicShared.getToDayZeroTime(zls?.lastRunTime || PublicShared.getToDayZeroTime(G.openTime)) + 86400 * G.gc.zhanling.eventOpen.day
    }

    call.succ(result);
}

export async function payZhanLing(player: player) {
    let zlData = await G.mongodb.cEvent('zhanling').findOne({uid: player.uid, type: 'zhanling'});
    let curLv = zlData?.lv || 1;
    let maxLv = Number(Object.keys(G.gc.zhanling.lv).slice(-1)[0]);
    let addLv = maxLv - curLv >= G.gc.zhanling.payAddLv ? G.gc.zhanling.payAddLv : maxLv - curLv;

    await G.mongodb.cEvent('zhanling').updateOne(
        {uid: player.uid, type: 'zhanling'},
        {$set: {isPay: true, exp: G.gc.zhanling.lv[curLv + addLv], lv: curLv + addLv}},
        {upsert: true}
    );
}