import {OptionalId, UpdateFilter} from 'mongodb';
import {ApiCall} from "tsrpc";
import {CollectionPlayerInfo} from '../../module/collection_palyerInfo';
import {ChatFun} from '../../public/chat';
import {PlayerFun} from '../../public/player';
import {UserFun} from '../../public/user';
import {ResOpen} from '../../shared/protocols/jiaotang/PtlOpen';
import {ReqLottery, ResLottery} from "../../shared/protocols/jiuba/PtlLottery";
import {PublicShared} from '../../shared/public/public';
import {HongDianChange} from '../hongdian/fun';
import {RankKfjs} from "../../public/rank/rank_kfjs";
import {PushGiftFun} from "../../public/pushgift";

export default async function (call: ApiCall<ReqLottery, ResLottery>) {

    let need: atn[];
    let prize: atn[];
    let result = await G.mongodb.collection('playerInfo', 'jiuba').findOne({uid: call.uid, type: 'jiuba'});
    let update: UpdateFilter<OptionalId<CollectionPlayerInfo<"jiuba">>>;
    let changeData: Partial<ResOpen>;

    if (call.req.type == 1) {
        let isReplace = false;
        let conf = G.gc.choujiang.jiuba[1];
        let toDayZeroTime = PublicShared.getToDayZeroTime();
        let oneReplaceNum = result?.oneReplaceNum || 0;

        if (toDayZeroTime <= result?.freeTime) {
            let meet = await PlayerFun.checkNeedByArgs(call, conf.need1, conf.need2);
            need = [meet.atn];
        }

        prize = [];
        prize = prize.concat(PublicShared.randomDropGroup(oneReplaceNum == conf.replace.num ? conf.replace.diaoluo : conf.diaoluo.random()));
        if (!result || (result.oneNum < 1 && result.tenNum < 1)) {
            prize = PublicShared.randomDropGroup(conf.firstdiaoluo);
        }

        for (let atn of prize) {
            let atnConf = PublicShared.getAtnConf(atn) as any;
            if (conf.replace.colour.includes(atnConf.colour) || conf.replace.colour.includes(atnConf.star)) {
                isReplace = true;
                break;
            }
        }

        update = {
            $inc: {oneNum: 1},
            $set: {oneReplaceNum: isReplace ? 0 : oneReplaceNum + 1}
        };

        changeData = {
            oneNum: (result?.oneNum || 0) + 1
        };

        if (!result || !result.freeTime || result.freeTime < toDayZeroTime) {
            Object.assign(update.$set, {freeTime: G.time});
            Object.assign(changeData, {freeTime: G.time});
        }
    } else if (call.req.type == 10) {
        let conf = G.gc.choujiang.jiuba[2];
        let allNum = (result?.tenNum || 0) * 10;
        let meet = await PlayerFun.checkNeedByArgs(call, conf.need1, conf.need2);
        need = [meet.atn];

        let dlArr = result?.tenNum ? [...conf.diaoluo] : [...conf.firstdiaoluo];
        dlArr.sort(() => {
            return 0.5 - Math.random();
        });

        if (G.gc.choujiang.jiubabaodi.numbd[allNum]) {
            dlArr.splice(0, G.gc.choujiang.jiubabaodi.numbd[allNum].length);
            dlArr.push(...G.gc.choujiang.jiubabaodi.numbd[allNum]);
            dlArr.sort(() => {
                return 0.5 - Math.random();
            });
        }


        prize = [];
        for (let id of dlArr) {
            prize = prize.concat(PublicShared.randomDropGroup(id));
        }
        if (!result || (result.oneNum < 1 && result.tenNum < 1)) {
            prize.pop()
            prize = prize.concat(PublicShared.randomDropGroup(G.gc.choujiang.jiuba[1].firstdiaoluo));
        }

        update = {
            $inc: {tenNum: 1}
        };

        changeData = {
            tenNum: (result?.tenNum || 0) + 1
        };
    }

    need && await PlayerFun.cutNeed(call, need);
    await PlayerFun.sendPrize(call, prize);

    prize.forEach(p => {
        if (p.a == 'hero' && G.gc.hero[p.t]?.star == 5) {
            ChatFun.newMsg({
                type: 'local',
                msg: G.gc.pmd.get_hero_star5_pmd,
                time: G.time,
                sender: 'system',
                otherData: {
                    pmd: true,
                    args: [call.conn.gud.name, G.gc.hero[p.t].name]
                }
            });
        }
    });

    G.mongodb.collection('playerInfo', 'jiuba').updateOne(
        {
            uid: call.uid,
            type: 'jiuba'
        },
        {
            ...update
        },
        {
            upsert: true
        }
    );

    HongDianChange.sendChangeKey(call.uid, ['jiuba', 'taskhd', 'huodonghd']);

    let oneNum = result?.oneNum || 0;
    let tenNum = result?.tenNum || 0;
    UserFun.activeHeadFrame(call.uid, 'jiuba/Lottery', oneNum + tenNum * 10 + call.req.type);

    call.succ({
        prize: prize,
        changeData: changeData
    });

    let rankKfjs = RankKfjs(1)
    rankKfjs.setDataAndCheck({
        player: call.conn.gud,
        valArr: [await rankKfjs.getRankScore(call.uid) + call.req.type]
    });

    // 十连抽推送礼包
    if (call.req.type == 10) {
        PushGiftFun.chkRecruitGift(call.uid)
    }
}