import { ApiCall } from "tsrpc";
import { Wjjl } from '../../../module/collection_wjjl';
import { EmailFun } from '../../../public/email';
import { PayFun } from '../../../public/pay';
import { ReqOpen, ResOpen } from "../../../shared/protocols/event/kaifukuanghuan/PtlOpen";
import { player } from '../../../shared/protocols/user/type';
import { PublicShared } from '../../../shared/public/public';

export default async function (call: ApiCall<ReqOpen, ResOpen>) {
    let [isOpen, tips] = PublicShared.getOpenCond(call, "kaifukuanghuan")
    if (!isOpen) return call.error('', { code: -1, message: tips });

    let data = await G.mongodb.cEvent('kaifukuanghuan').findOne({ uid: call.uid, type: 'kaifukuanghuan' });

    if (!data) {
        data = {
            _id: null,
            uid: call.uid,
            type: 'kaifukuanghuan',
            buyShop: {},
            receiveBox: [],
            receiveTask: Object.fromEntries(Object.keys(G.gc.kaifukuanghuan.task).map(day => [day, []])),
            receiveLogin: [],
        };
        G.mongodb.cEvent('kaifukuanghuan').insertOne(data);
    }

    let tasks = Object.values(G.gc.kaifukuanghuan.task as k_v<_gcType['kaifukuanghuan']['task']['1']>).map(tasks => tasks.map(task => task.taskType)).reduce((a, b) => a.concat(b));
    let taskFinished = await getTaskVal(call.conn.gud, [...new Set(tasks)]);
    let { _id, uid, type, ...ops } = data;

    call.succ({
        ...ops,
        day: PublicShared.getOpenServerDay(),
        taskFinished: taskFinished
    });
}

export async function reissuePrize(gud: player, lastTime: number, curTime: number) {
    let cZeroTime = PublicShared.getToDayZeroTime(gud.cTime);

    if (curTime > cZeroTime + 7 * 24 * 3600 && lastTime < cZeroTime + 7 * 24 * 3600) {
        let loginDay = gud.loginDays;
        let db = await G.mongodb.cEvent('kaifukuanghuan').findOne({ uid: gud.uid, type: 'kaifukuanghuan' });
        let recLogin = db?.receiveLogin || [];
        let prize: atn[] = [];
        G.gc.kaifukuanghuan.loginPrize.forEach((v, i) => {
            if (loginDay >= i + 1 && !recLogin.includes(i)) prize.push(...v);
        });

        prize.length > 0 && EmailFun.addEmail({
            uid: gud.uid,
            type: 'system',
            title: G.gc.kaifukuanghuan.email.title,
            content: G.gc.kaifukuanghuan.email.content,
            prize: PublicShared.mergePrize(prize),
            contentInsertArr: []
        });
    }
}

export async function getTaskVal(gud: player, taskTyps: string[]) {
    let val: k_v<number> = {};

    taskTyps = taskTyps.filter(t => {
        if (['power', 'helpHeros'].includes(t)) return true;
        if (gud[t] != undefined) {
            if (typeof gud[t] == 'number') val[t] = gud[t];
            else if (t == 'wxcLv') val[t] = gud[t].lv;
            else val[t] = 0;
            return false;
        } else {
            return true;
        }
    });

    for (let t of taskTyps) {
        if (t == 'toDayLogin') val[t] = 1;
        else if (t.indexOf('toDayPay') != -1) {
            let daystr = t.split('_')[1] || '1';
            let day = Number(daystr);
            let zeroTime = PublicShared.getToDayZeroTime(G.openTime);
            val[t] = await PayFun.getPayDaysAllPayNum(
                gud.uid,
                zeroTime + (day - 1) * 24 * 3600, zeroTime + day * 24 * 3600
            ) * 10;
        } else if (t == 'zccg_level') {
            val[t] = (await G.mongodb.collection('pata').findOne({ uid: gud.uid }))?.lv || 0;
        } else if (t.indexOf('has_equip_color') != -1) {
            let color = Number(t.split('_').last());
            let lshd = G.server.uid_connections[gud.uid].lshd.equip || {};
            if (Object.keys(lshd).length == 0) val[t] = 0;
            else {
                let meets = Object.entries(lshd).filter(v => G.gc.equip[v[0]].colour >= color);
                if (meets.length > 0) {
                    val[t] = meets.map(v => v[1]).reduce((a, b) => a + b);
                } else {
                    val[t] = 0;
                }
            }
        } else {
            // 竞技场默认取值 1000 ，不能为0
            let _default = t == 'jjc_rank' ? 1000 : 0
            val[t] = await Wjjl.getVal(gud.uid, t) || _default;
        }
    }

    return val;
}

