import moment = require("moment");
import { ACTIVITY_TIME_TYPE, REFRESH_TIME, SHOP_REFRESH_TYPE } from "../../consts";
import { ActivityModelType } from "../../db/Activity";
import { UserShopType } from "../../db/UserShop";
import { UserShopTypeType } from "../../db/UserShopType";
import { gameData } from "../../pubUtils/data";
import { nowSeconds } from "../../pubUtils/timeUtil";
import { ActivityBase } from "../activityField/activityField";

interface ShopInDb {
    shop: number;
    type: number;
    list: ShopItemInDb[];
}

interface ShopItemInDb {
    id: number;
    goodId: number;
    goodName: string;
    num: number;
    guildLvLimit: number;
    lvLimit: number;
    ranklimit: number;
    purchaseLimit: number;
    vipPurchaseLimit: number;
    refreshType: number;
    money: number;
    price: string;
    productID: string;
    chosen: number;
    indirectId: number;
    createTime: number;
    timeType: ACTIVITY_TIME_TYPE;
    days: number;
    beginTime: number;
    endTime: number;
}

export class ShopData extends ActivityBase {
    shop: number;
    type: number;
    roleTime: number;
    serverTime: number;
    list: ShopDicData[] = [];

    constructor(activityData: ActivityModelType, createTime: number, serverTime: number) {
        super(activityData, createTime, serverTime);
        this.roleTime = createTime;
        this.serverTime = serverTime;
        this.initData(activityData.data)
    }

    public initData(data: string) {
        let result: ShopInDb = JSON.parse(data);
        if(result) {
            this.shop = result.shop;
            this.type = result.type;
            for (let obj of result.list) {
                this.list.push(new ShopDicData(obj, this.roleTime, this.serverTime))
            }

        }
    }

    public findByItemId(itemId: number) {
        let item = this.list.find(cur => cur.id == itemId);
        if(!item) return null;
        return <ShopDicExtendData>{...item, shop: this.shop, type: this.type};
    }

    public findByProductID(productID: string) {
        let item = this.list.find(cur => cur.productID == productID);
        if(!item) return null;
        return <ShopDicExtendData>{...item, shop: this.shop, type: this.type};
    }
}

export class ShopDicData {
    isNew: boolean = false;
    id: number;
    goodId: number;
    goodName: string;
    num: number;
    guildLvLimit: number;
    lvLimit: number;
    ranklimit: number;
    purchaseLimit: number;
    vipPurchaseLimit: number;
    refreshType: SHOP_REFRESH_TYPE;
    money: number;
    price: string;
    productID: string = '';
    chosen: number;
    indirectId: number;
    createTime: number = 0;
    isForever: boolean = false;
    beginTime: number = 0;
    endTime: number = 0;

    constructor(obj: ShopItemInDb, roleTime: number, serverTime: number) {
        this.id = obj.id;
        this.goodId = obj.goodId;
        this.goodName = obj.goodName;
        this.num = obj.num;
        this.guildLvLimit = obj.guildLvLimit;
        this.lvLimit = obj.lvLimit;
        this.ranklimit = obj.ranklimit;
        this.purchaseLimit = obj.purchaseLimit;
        this.vipPurchaseLimit = obj.vipPurchaseLimit;
        this.refreshType = obj.refreshType;
        this.money = obj.money;
        this.price = obj.price;
        this.productID = obj.productID;
        this.chosen = obj.chosen;
        this.indirectId = obj.indirectId;
        this.createTime = obj.createTime;
        this.setTime(obj, roleTime, serverTime);
    }

    setTime(obj: ShopItemInDb, roleTime: number, serverTime: number) {
        this.isForever = obj.timeType == ACTIVITY_TIME_TYPE.FOREVER;
        switch (obj.timeType) {
            case ACTIVITY_TIME_TYPE.SERVER_OPEN_TIME: {
                this.beginTime = moment(serverTime * 1000).startOf('d').add(REFRESH_TIME, 'h').unix();
                this.endTime = moment(this.beginTime * 1000).add(obj.days > 0? obj.days: 1, 'd').unix();
                break;
            }
            case ACTIVITY_TIME_TYPE.ROLE_REGISTER_TIME: {
                this.beginTime = moment(roleTime * 1000).startOf('d').add(REFRESH_TIME, 'h').unix();
                this.endTime = moment(this.beginTime * 1000).add(obj.days > 0? obj.days: 1, 'd').unix();
                break;
            }
            case ACTIVITY_TIME_TYPE.DATE_TIME: {
                this.beginTime = obj.beginTime;
                this.endTime = obj.endTime;
                break;
            }
            case ACTIVITY_TIME_TYPE.FOREVER: 
            {
                this.beginTime = obj.beginTime;
                break;
            }
            default: {
                break;
            }
        }
    }

    public setReadRecord(record: UserShopTypeType) {
        let now = nowSeconds();
        if(this.beginTime <= now && this.endTime >= now) {
            let readTime = record?.readTime||0;
            if(this.createTime > readTime) this.isNew = true;
        }
    }
}

export interface ShopDicExtendData extends ShopDicData {
    shop: number;
    type: number;
}

export class ShopReturnData {
    activityId: number = 0;
    shop: number;
    type: number;
    dic: ShopDicData[] = [];
    records: ShopReturnRecordData[] = [];

    constructor(shop: number, type: number) {
        this.shop = shop;
        this.type = type;
    }

    public setDicByActivity(activityData: ShopData) {
        if(!activityData || activityData.shop != this.shop || activityData.type != this.type) return;
        this.activityId = activityData.activityId;
        for(let obj of activityData.list) {
            if(obj) this.dic.push(obj);
        }
    }

    public addUserRecords(record: UserShopType) {
        if(!record || record.shop != this.shop || record.type != this.type) return;
        if(this.activityId > 0) {
            let dic = this.dic.find(cur => cur.id == record.itemId);
            if(!dic || (dic.createTime && dic.createTime != record.createTime)) return;
        } else {
            if(!gameData.shopItem.has(record.itemId)) return;
        }
        let recordResult = new ShopReturnRecordData(record);
        if(recordResult && recordResult.shopItemId && recordResult.buyCount) this.records.push(recordResult)
    }

    public setReadRecord(record: UserShopTypeType) {
        for(let obj of this.dic) {
            obj.setReadRecord(record);
        }
    }
}

export class ShopReturnRecordData {
    shopItemId: number;
    buyCount: number;

    constructor(record: UserShopType) {
        if(!record) return;
        this.shopItemId = record.itemId;
        this.buyCount = record.count;
    }
}