
import { pick } from 'underscore';
import { TASK_PASS_TYPE } from '../../consts';
import { ActivityModelType } from '../../db/Activity';
import { ActivityTaskPassModelType } from '../../db/ActivityTaskPass';
import { ActivityBase } from './activityField';

interface TaskPassProgressInDb {      // 进度
    lv: number;         // 等级
    point: number;      // 到达下一级所需的积分
}

interface TaskPassRewardItemInDb {
    lv: number;
    reward: string;
    needShow: boolean;
}

interface TaskPassSpecialRewardInDb {
    hid: number;
    lv: number;
}

interface TaskPassRewardsInDb {
    pageIndex: number;
    type: number;       // 1-标准版 2-豪华版
    price: number;      // 花多少钱
    productID: string; // 商品id，如果是标准版这里填&
    items: TaskPassRewardItemInDb[];
    specialReward: TaskPassSpecialRewardInDb;
}

interface TaskPassSpdUpInDb {
    cost: string;
    point: number;
}

interface TaskPassDataInDb {
    progress: TaskPassProgressInDb[];
    rewards: TaskPassRewardsInDb[];
    spdUp: TaskPassSpdUpInDb;
}

export class TaskPassProgress {
    lv: number;
    point: number;

    constructor(data: TaskPassProgressInDb) {
        this.lv = data.lv;
        this.point = data.point;
    }
}

export class TaskPassRewardItem {
    lv: number;
    reward: string;
    needShow: boolean;
    pageIndex: number;

    hasReceived: boolean = false;

    constructor(item: TaskPassRewardItemInDb) {
        this.lv = item.lv;
        this.reward = item.reward;
        this.needShow = item.needShow;
    }

    setHasReceived(hasReceived: boolean) {
        this.hasReceived = hasReceived;
    }
}

export class TaskPassSpecialReward {
    hid: number;
    lv: number;

    constructor(data: TaskPassSpecialRewardInDb) {
        if(data) {
            this.hid = data.hid;
            this.lv = data.lv;
        }
    }
}

export class TaskPassReward {
    pageIndex: number;   // 第几页
    type: number;        // 1-标准版 2-豪华版
    price: number;       // 花多少钱
    productID: string;   // 商品id，如果是标准版这里填&
    items: TaskPassRewardItem[] = [];
    specialReward: TaskPassSpecialReward;

    hasBuy: boolean = false;     // 是否购买了
    map: Map<number, number> = new Map(); // lv => index

    constructor(reward: TaskPassRewardsInDb) {
        this.pageIndex = reward.pageIndex;
        this.type = reward.type;
        this.price = reward.price;
        this.productID = reward.productID;
        for(let item of reward.items) {
            let obj = new TaskPassRewardItem(item);
            this.items.push(obj);
            this.map.set(obj.lv, this.items.length - 1);
        }
        this.specialReward = new TaskPassSpecialReward(reward.specialReward);
    }

    findItemByLv(lv: number) {
        let index = this.map.get(lv);
        return this.items[index];
    }

    setPlayerRecord(record: ActivityTaskPassModelType) {
        if(record.productIDs && record.productIDs.indexOf(this.productID) != -1) {
            this.hasBuy = true;
        }
        if(record.receivedReward) {
            for(let { pageIndex, lv } of record.receivedReward) {
                if(pageIndex == this.pageIndex) {
                    let item = this.findItemByLv(lv);
                    item.setHasReceived(true);
                }
            }
        }
    }

    getShowResult() {
        return pick(this, ['pageIndex', 'type', 'price', 'productID', 'items', 'hasBuy', 'specialReward']);
    }

    canReceiveItems() {
        if(this.type == TASK_PASS_TYPE.VIP) {
            if(!this.hasBuy) return false;
        } 
        return true;
    }
}

export class TaskPassSpdUp {
    cost: string;
    point: number;

    spdUpCnt: number = 0;    // 加速过的次数

    constructor(obj: TaskPassSpdUpInDb) {
        this.cost = obj.cost;
        this.point = obj.point;
    }

    setSpdUpCnt(cnt: number) {
        this.spdUpCnt = cnt;
    }

    addSpdUpCnt(cnt: number) {
        this.spdUpCnt += cnt;
    }
}

// 战令活动数据
export class TaskPassData extends ActivityBase {
    progress: TaskPassProgress[] = [];
    rewards: TaskPassReward[] = [];
    spdUp: TaskPassSpdUp;
    
    lv: number = 1;
    totalPoint: number = 0;
    map: Map<number, number> = new Map(); // pageIndex => rewards的index

    constructor(activityData: ActivityModelType, createTime: number, serverTime: number) {
        super(activityData, createTime, serverTime)
        this.initData(activityData.data)
    }
    
    public initData(data: string) {
        let dataObj: TaskPassDataInDb = JSON.parse(data);
        for(let obj of dataObj.progress) {
            this.progress.push(new TaskPassProgress(obj));
        }
        for(let obj of dataObj.rewards) {
            let reward = new TaskPassReward(obj);
            this.rewards.push(reward);
            this.map.set(reward.pageIndex, this.rewards.length - 1);
        }
        this.spdUp = new TaskPassSpdUp(dataObj.spdUp);
    }


    public setPlayerRecord(record: ActivityTaskPassModelType) {
        if(!record) return null;
        this.setLvByPoint(record.totalPoint||0);
        for(let reward of this.rewards) {
            reward.setPlayerRecord(record);
        }
        this.spdUp.setSpdUpCnt(record.spdUpCnt);
    }

    public getShowResult() {
        return {
            ...this.getBaseKeys(),
            progress: this.progress,
            rewards: this.rewards.map(reward => reward.getShowResult()),
            spdUp: this.spdUp,
            lv: this.lv,
            totalPoint: this.totalPoint,
        }
    }

    private setLvByPoint(totalPoint: number) {
        this.totalPoint = totalPoint;
        for(let { lv, point } of this.progress) {
            this.lv = lv;
            totalPoint -= point;
            if(totalPoint < 0) break;
        }
    }

    public findRewardByPageIndex(pageIndex: number) {
        let index = this.map.get(pageIndex);
        return this.rewards[index];
    }

    // 领取道具
    public receiveItems(pageIndex: number, lv: number) {
        let rewards: TaskPassReward[] = [];
        if(pageIndex == 0) {
            rewards = this.rewards;
        } else {
            let reward = this.findRewardByPageIndex(pageIndex);
            rewards.push(reward)
        }

        let items: TaskPassRewardItem[] = [];
        for(let reward of rewards) {
            if(!reward) continue;
            if(!reward.canReceiveItems()) continue;

            if(lv == 0) {
                for(let item of reward.items) {
                    if(item.lv <= this.lv && !item.hasReceived) {
                        item.setHasReceived(true);
                        item.pageIndex = reward.pageIndex;
                        items.push(item);
                    }
                }
            } else {
                let item = reward.findItemByLv(lv);
                if(!item.hasReceived) {
                    item.setHasReceived(true);
                    item.pageIndex = reward.pageIndex;
                    items.push(item);
                }
            }
        }

        if(items.length <= 0) return false;
        return items
    }

    // 加速
    public addPoint(point: number, count: number) {
        this.spdUp.addSpdUpCnt(count)
        this.setLvByPoint(this.totalPoint + point);
        return {
            curLv: this.lv,
            totalPoint: this.totalPoint,
            spdUpCnt: this.spdUp.spdUpCnt
        }
    }
}