import { CollectionShop } from '../module/collection_shop';
import { ResOpen, shopItem } from '../shared/protocols/shop/PtlOpen';
import { PublicShared } from '../shared/public/public';
import { ShiwuFun } from './shiwu';

type shopData = ResOpen;
type changeData = {
    [k in keyof (shopData & { version?: number | string })]: (shopData & { version?: number | string })[k]
};

export class ShopFun {
    static changeType: Partial<changeData>;

    static getShopItem(shops: shopItem[]): shopItem {
        let item = PublicShared.randomDropAny(shops);

        if (item?.a == 'shiwu') {

            let shiwu: any = {
                shiwuId: item.t.toString(),
                colour: item.colour,
                fujia: []
            };
            shiwu.jichu = ShiwuFun.randomJichu(shiwu);
            ShiwuFun.randomFujiaAll(shiwu);
            ShiwuFun.randomZhuanshu(shiwu);

            return {
                ...item,
                shiwuBuff: shiwu
            };
        }

        return item;
    }

    /**从商品掉落组中获取商品 */
    static getShopItems(shopId: string | number, lv: number) {
        let shopItems: shopItem[] = [];

        for (let id of G.gc.shop[shopId].shopItems) {
            let shops = G.gc.shopItem[id].filter(si => lv >= si.lv[0] && lv <= si.lv[1]);
            let item = this.getShopItem(shops);
            item && shopItems.push(item);
        }
        let sDay = PublicShared.getOpenServerDay();
        return shopItems.filter(s => s.openDay <= sDay);
    }

    static async changeShopData(uid: string, shopId: string, change: Partial<changeData>) {
        let where = { uid: uid, shopId: shopId }
        G.mongodb.collection("shop").updateOne(where, { $set: change })
    }

    static async initShopData(uid: string, shopId: string) {
        let gud = await G.mongodb.collection("user").findOne({ uid: uid }, {
            projection: { lv: 1, _id: 0 }
        })
        let lv = gud?.lv || 1;

        let shopConf = G.gc.shop[shopId];
        let zt = PublicShared.getToDayZeroTime(G.time)

        let n
        if (!shopConf?.autoRefreshTime) {
            n = 0
        } else {
            n = Math.trunc((G.time - zt) / shopConf.autoRefreshTime)
        }

        return (await G.mongodb.collection("shop").findOneAndUpdate(
            { uid: uid, shopId: shopId },
            {
                $set: {
                    buyNum: {},
                    shopItems: this.getShopItems(shopId, lv),
                    useFreeRefreshNum: 0,
                    useRecoilRefreshNum: 0,
                    lastAutoRefreshTime: PublicShared.getToDayZeroTime(G.time) + n * shopConf.autoRefreshTime,
                    lastFreeRefreshTime: G.time
                }
            },
            { upsert: true, returnDocument: 'after' }
        )).value
    }

    static async getShopData(uid: string, shopId: string, lv: number) {
        let where = {
            uid: uid,
            shopId: shopId
        };
        let shopConf = G.gc.shop[shopId];
        let shopData = await G.mongodb.collection("shop").findOne(where);

        // 商店自动刷新
        if (!shopData || (shopConf.autoRefreshTime > 0 && G.time - shopData.lastAutoRefreshTime >= shopConf.autoRefreshTime)) {
            return await this.initShopData(uid, shopId)
        }

        // 免费刷新次数刷新
        if (shopConf.freeRefreshInterval > 0 && G.time - shopData.lastFreeRefreshTime >= shopConf.freeRefreshInterval) {
            shopData.useFreeRefreshNum = 0;
            shopData.lastFreeRefreshTime = G.time;
            await this.changeShopData(uid, shopId, { useFreeRefreshNum: 0, lastFreeRefreshTime: G.time });
        }

        if (shopConf.version && shopConf.version != shopData.version) {
            shopData.shopItems = this.getShopItems(shopId, lv);
            await this.changeShopData(uid, shopId, { shopItems: shopData.shopItems, version: shopConf.version });
        }

        return shopData
    }
    static async changeGHShopData(ghid: string, shopId: string, change: Partial<changeData>) {
        this.changeShopData(ghid, shopId, change)
    }
}