import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose';
import { genCode } from '../pubUtils/util';
import { getZeroPointD } from '../pubUtils/timeUtil';
import { SHOP_REFRESH_TYPE } from '../consts';
import { DicShop } from '../pubUtils/dictionary/DicShop';

/**
  * 玩家购买商店记录表，每个商品一条，每次刷新新建一条
**/
@modelOptions({ schemaOptions: { id: false } })
@index({ roleId: 1, itemId: 1 })

export default class UserShop extends BaseModel {
    @prop({ required: true })
    code: string;					// 该记录唯一标识

    @prop({ required: true })
    roleId: string;					// 玩家id

    @prop({ required: true })
    roleName: string;				// 玩家名

    @prop({ required: true })
    shopId: number; 				// 商店id

    @prop({ required: true })
    itemId: number; 				// 商品id

    @prop({ required: true })
    goodId: number; 				// 商品包含的物品id

    @prop({ required: true })
    refreshType: number; 			// 商品刷新类型 1-每日 2-每周 3-每月

    @prop({ required: true })
    count: number; 		        	// 数量

    private static getRefreshCondition() {
        let today = getZeroPointD();
        let cutWeek = getZeroPointD(SHOP_REFRESH_TYPE.WEEKLY);
        let curMonth = getZeroPointD(SHOP_REFRESH_TYPE.MONTHLY);

        return [
            { createdAt: { $gte: today }, refreshType: SHOP_REFRESH_TYPE.DAILY },
            { createdAt: { $gte: cutWeek }, refreshType: SHOP_REFRESH_TYPE.WEEKLY },
            { createdAt: { $gte: curMonth }, refreshType: SHOP_REFRESH_TYPE.MONTHLY },
            { refreshType: SHOP_REFRESH_TYPE.FOREVER },
        ]

    }

    public static async findByShopId(roleId: string, shopId: number) {
        let timeCondition = this.getRefreshCondition();
        let rec: UserShopType[] = await UserShopModel.find({ shopId, roleId, $or: timeCondition }).lean();
        return rec;
    }

    public static async findMapByShopId(roleId: string, shopId: number) {
        let rec = await this.findByShopId(roleId, shopId);
        let map = new Map<number, UserShopType>();

        for(let userShop of rec) {
            map.set(userShop.itemId, userShop);
        }
        return map
    }

    public static async findByRoleAndItem(roleId: string, itemId: number) {
        let timeCondition = this.getRefreshCondition();
        let rec: UserShopType = await UserShopModel.findOne({ roleId, itemId, $or: timeCondition }).lean();
        return rec;
    }

    public static async purchase(roleId: string, roleName: string, dicShopItem: DicShop, inc: number) {
        let code = genCode(8);
        let timeCondition = this.getRefreshCondition();
        let { id, goodid, refreshType, shop } = dicShopItem;

        let rec: UserShopType = await UserShopModel.findOneAndUpdate(
            { roleId, itemId: id, $or: timeCondition }, 
            { $setOnInsert: { roleName, code, goodId: goodid, refreshType, shopId: shop }, $inc: { count: inc } },
            { new: true, upsert: true }
        ).lean();
        return rec;
    }

    public static async deleteAccount(roleId: string) {
        let result = await UserShopModel.deleteMany({roleId});
        return result;
    }
}

export const UserShopModel = getModelForClass(UserShop);

export interface UserShopType extends Pick<DocumentType<UserShop>, keyof UserShop> { }
export type UserShopParam = Partial<UserShopType>;
