import { ActivityModelType } from '../../db/Activity';
import { ActivityRechargeMoneyModelType } from '../../db/ActivityRechargeMoney';
import { getZeroPointD } from '../../pubUtils/timeUtil';
import { getRandEelmWithWeight, getRandSingleEelm } from '../../pubUtils/util';
import { ActivityBase } from './activityField';

interface RechargeMoneyPoolInDb {
    id: number;      // 奖池项唯一id
    gid: number;
    count: number;
    quality: number; // 物品的品级，相同的品级平分概率，不同品级直接按percent来做概率
}

interface RechargeMoneyWeightInDb {
    quality: number;  // pool中的品级
    weight: number;   // 权重，先随机出这个品级的物品的概率，然后再平均随机出这个品级下的物品
}

interface RechargeMoneyInDb {
    pool: RechargeMoneyPoolInDb[];
    minPrice: number;
    percent: RechargeMoneyWeightInDb[];
}

// 充值记录
export class RechargeMoneyPool {
    id: number;       // 卡池id
    gid: number;
    count: number;
    quality: number;  // 物品的品级

    hasGet: boolean = false; // 是否已经获取过了
    getNumBeforeToday: number = 0; // 获取次数
    getNumToday: number = 0;

    constructor(data: RechargeMoneyPoolInDb) {
        this.id = data.id;
        this.gid = data.gid;
        this.count = data.count;
        this.quality = data.quality;
    }

    setRecord(record: ActivityRechargeMoneyModelType) {
        this.hasGet = true;
        if(record.rewardTime < getZeroPointD()) {
            this.getNumBeforeToday ++;
        } else {
            this.getNumToday ++;
        }
    }

    unsetHasGet() {
        this.hasGet = false;
    }

    setHasGet() {
        this.hasGet = true;
    }
}

export class RechargeMoneyWeight {
    quality: number;
    weight: number;

    constructor(data: RechargeMoneyWeightInDb) {
        this.quality = data.quality;
        this.weight = data.weight;
    }
}

// 累计充值数据
export class RechargeMoneyData extends ActivityBase {
    private map: Map<number, number> = new Map(); // poolId => index
    pool: RechargeMoneyPool[] = [];
    minPrice: number = 0;
    percent: RechargeMoneyWeight[] = [];

    ticketCnt: number = 0;         // 签数
    recordArr: ActivityRechargeMoneyModelType[] = [];

    private findItemFromPool(poolId: number) {
        let index = this.map.get(poolId);
        return this.pool[index];
    }

    public pull() {
        this.ticketCnt --;
        let percent = this.percent;
        let randPercent = percent.filter(cur => {
            let hasAllGet = true;
            for(let { quality, hasGet } of this.pool) {
                if(quality == cur.quality && !hasGet) hasAllGet = false;
            }
            return !hasAllGet;
        });
        if(randPercent.length <=0) return false; // 全部抽完了

        let qualityResult = getRandEelmWithWeight(randPercent);
        if(!qualityResult) return false;

        let elems: RechargeMoneyPool[] = [];
        for(let pool of this.pool) {
            if(pool && !pool.hasGet && pool.quality == qualityResult.dic.quality) {
                elems.push(pool);
            }
        }
        let result = getRandSingleEelm(elems);
        result.setHasGet();
        return result;
    }

    //解析玩家购买记录
    public setPlayerRecords(data: ActivityRechargeMoneyModelType[]) {
        if (!data) return;

        for(let record of data) {
            if(record.RMB >= this.minPrice) {
                if(!record.rewardTime) {
                    this.ticketCnt++;
                    this.recordArr.push(record);
                }
            } 
            if(record.poolId) {
                let pool = this.findItemFromPool(record.poolId);
                if(pool) {
                    pool.setRecord(record);
                }
            }
        }
        this.resetPool();
    }

    private resetPool() {
        let beforeNums = this.pool.map(cur => cur.getNumBeforeToday);
        let max = Math.max(...beforeNums);
        let min = Math.min(...beforeNums);
        // 当所有奖池都抽过一遍的时候，第二天五点，重置
        for(let item of this.pool) {
            if((min == max || item.getNumBeforeToday < max) && item.getNumToday <= 0) item.unsetHasGet();
        }
    }

    public getShowResult() {
        return {
            ...this.getBaseKeys(),
            ticketCnt: this.ticketCnt,
            pool: this.pool,
        }
    }

    public initData(data: string) {
        let dataObj: RechargeMoneyInDb = JSON.parse(data);
        // console.log(dataObj);
        for(let pool of dataObj.pool) {
            let obj = new RechargeMoneyPool(pool);
            this.pool.push(obj);
            this.map.set(obj.id, this.pool.length - 1);
        }
        this.minPrice = dataObj.minPrice;
        for(let percent of dataObj.percent) {
            let obj = new RechargeMoneyWeight(percent);
            this.percent.push(obj);
        }
    }

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