import SampleManager from "./Sample/SampleManager";
import { Mission } from "./Sample/Mission/Mission";
import { Achievement } from "./Sample/Achievement/Achievement";
import { Consts } from "../Consts";
import EventManager from "../UIFrame/EventManager";
import { FightConsts } from "../Fight/FightConsts";
import { Fighter } from "../Fight/Fighter";
import { Equip } from "./Sample/Prop/Equip/Equip";
import { Prop } from "./Sample/Prop/Prop";
import { Gem } from "./Sample/Prop/Gem";
import { CookBook } from "./Sample/Prop/CookBook";
import { UidManager } from "./UidManager";

/**
 * 玩家数据
 */
export class Player {
    private static playerInstance: Player;

    public static getInstance(): Player {
        return this.playerInstance;
    }

    /**
     * 将数据初始化
     */
    public static init(player: Player) {
        let dailyMissions = new Map<number, Mission>();

        let m = SampleManager.newSample(Mission, 1);
        dailyMissions.set(m.sid, m);

        m = SampleManager.newSample(Mission, 2);
        dailyMissions.set(m.sid, m);
        m.isGetAwarded = true;
        m.updateValue(2);

        m = SampleManager.newSample(Mission, 3);
        dailyMissions.set(m.sid, m);
        m.updateValue(3);

        m = SampleManager.newSample(Mission, 4);
        dailyMissions.set(m.sid, m);
        m.updateValue(1);

        player.setDailyMissionMap(dailyMissions);


        let equipMap = new Map<number, Equip>();

        let e = SampleManager.newSample(Equip, 1);
        equipMap.set(e.sid, e);

        e = SampleManager.newSample(Equip, 2);
        equipMap.set(e.sid, e);
        e = SampleManager.newSample(Equip, 3);
        equipMap.set(e.sid, e);
        e = SampleManager.newSample(Equip, 4);
        equipMap.set(e.sid, e);
        player.equipbpMap = equipMap;

        player.equipMap = equipMap;


        let propMap = new Map<number, Prop>();

        let p = SampleManager.newSample(Prop, 1);
        p.setCount(12);
        propMap.set(p.sid, p);

        p = SampleManager.newSample(Prop, 2);
        propMap.set(p.sid, p);
        p = SampleManager.newSample(Prop, 3);
        propMap.set(p.sid, p);
        p = SampleManager.newSample(Prop, 4);
        propMap.set(p.sid, p);
        player.propsbpMap = propMap;

        player.level = 10;
        player.exp = 1000;
        player.gold = 1;
        player.diamond = 2333;
        player.missionRefreshTime = 1566010216;
        this.playerInstance = player;
        player.fighter = new Fighter();
        player.fighter.init(player);
        EventManager.emit(Consts.PLAYER_DATA_READY, player);
    }
    //玩家uid
    public userID: string = "t123";
    // 等级
    public level: number;
    // 经验
    public exp: number;
    // 金币
    public gold: number;
    // 钻石
    public diamond: number;

    // 当前穿戴的装备
    private equipMap = new Map<number, Equip>();
    // 装备包裹内容
    private equipbpMap = new Map<number, Equip>();
    // 道具包裹内容
    private propsbpMap = new Map<number, Prop>();
    // 宝石包裹内容
    private gembpMap = new Map<number, Gem>();
    // 食谱包裹内容
    private cookbookbpMap = new Map<number, Prop>();
    // 成就完成情况
    private achievementMap = new Map<number, Achievement>();
    // 日常任务完成情况
    private dailyMissionMap = new Map<number, Mission>();

    // 日常任务上次刷新时间点
    public missionRefreshTime: number;
    // 保存时间
    public saveTime: number;
    //uidManager
    public uidManager: UidManager = new UidManager();

    // 内存数据
    fighter: Fighter = null;

    public setAchievementMap(achievementMap: Map<number, Achievement>) {
        this.achievementMap = achievementMap;
    }

    public getAchievementMap(): Map<number, Achievement> {
        return this.achievementMap;
    }

    public setDailyMissionMap(dailyMissionMap: Map<number, Mission>) {
        this.dailyMissionMap = dailyMissionMap;
    }

    public getDailyMissionMap(): Map<number, Mission> {
        return this.dailyMissionMap;
    }

    public getEquipMap(): Map<Number, Equip> {
        return this.equipMap;
    }

    public getPropsbpMap(): Map<number, Prop> {
        return this.propsbpMap;
    }

    public setPropsbpMap(pbpMap: Map<number, Prop>) {
        this.propsbpMap = pbpMap;
    }

    public getEquipbpMap(): Map<number, Equip> {
        return this.equipbpMap;
    }

    public getGembpMap(): Map<number, Gem> {
        return this.gembpMap;
    }
    public getCookbookbpMap(): Map<number, CookBook> {
        return this.cookbookbpMap;
    }
    /**
     * 初始化战斗数据
     */
    public initFighter(): Fighter {
        this.fighter = new Fighter();
        this.fighter.init(this);
        return this.fighter;
    }

    /**
     * 获得某类型的装备
     * @returns 
     */
    public getEquiped(equipType: number): Equip {
        let e = null;
        this.equipMap.forEach(equip => {
            if (equip.getEquipType() == equipType) {
                e = equip;
            }
        })
        return e;
    }

    /**
     * 获得某属性的值
     */
    private getAttValue(baseValue: number, type: number, perType: number): number {
        let l = baseValue;
        let addPer: number;
        // 基础属性
        this.equipMap.forEach(e => {
            l += e.getBaseAttr(type);
            addPer += e.getRandomAttr(perType);
        });
        // 加成
        let addValue = l * addPer;
        return l + addValue;
    }


    /**
     * 获得最大血量
     * @returns life
     */
    public getLife(): number {
        return Math.floor(this.getAttValue(FightConsts.BASE_LIFE, FightConsts.LIFE, FightConsts.LIFE_ADD_PER));
    }

    /**
     * 获得当前总攻击力
     * @returns attack
     */
    public getAttack(): number {
        return Math.floor(this.getAttValue(FightConsts.BASE_ATTACK, FightConsts.ATTACK, FightConsts.ATTACK_ADD_PER));
    }

    /**
    * 获得防御力
    * @returns def
    */
    public getDef(): number {
        return Math.floor(this.getAttValue(FightConsts.BASE_DEF, FightConsts.DEF, FightConsts.DEF_ADD_PER));
    }

    /**
     * 获得暴击率
     * @returns critRate
     */
    public getCritRate(): number {
        return this.getAttValue(FightConsts.BASE_CRITRATE, FightConsts.CRITRATE, FightConsts.CRIT_ADD_PER);
    }

    /**
    * 获得爆伤
    * @returns critDamage
    */
    public getCritDamage(): number {
        return this.getAttValue(FightConsts.BASE_CRITDAMAGE, FightConsts.CRITDAMAGE, FightConsts.CRITDAMAGE_ADD_PER);
    }

    /**
     * 获得闪避
     * @returns dodge
     */
    public getDodge(): number {
        return this.getAttValue(FightConsts.BASE_DODGE, FightConsts.DODGE, FightConsts.DODGE_ADD_PER);
    }

    /**
     * 获得json格式的玩家完整数据
     */
    public getJsonData(): string {
        let jsData: Object = {};
        jsData["userID"] = this.userID;
        jsData["level"] = this.level;
        jsData["exp"] = this.exp;
        jsData["gold"] = this.gold;
        jsData["missionRefreshTime"] = this.missionRefreshTime;
        jsData["saveTime"] = this.saveTime;


        // 已穿装备

        // 包裹内容


        // 成就
        let achData: Array<Object> = new Array<Object>();
        let i: number = 0;
        // for (var key in this.achievements) {
        //     if (this.achievements.hasOwnProperty(key)) {
        //         var element = this.achievements[key] as Achievement;
        //         achData[i++] = element.getStorageData();
        //     }
        // }
        // jsData["achievements"] = achData;

        // 任务
        let missionsData: Array<Object> = new Array<Object>();
        i = 0;
        for (var key in this.dailyMissionMap) {
            if (this.dailyMissionMap.hasOwnProperty(key)) {
                var element = this.dailyMissionMap[key] as Mission;
                missionsData[i++] = element.getStorageData();
            }
        }
        jsData["dailyMissions"] = missionsData;
        return JSON.stringify(jsData);
    }

    /**
     * 将json 格式数据读取到当前对象中
     */
    public fillData(js: Object) {
        this.userID = js["userID"];
        this.level = js["level"];
        this.exp = js["exp"];
        this.gold = js["gold"];
        this.missionRefreshTime = js["missionRefreshTime"];
        // let achData = js["achievements"];
        // if (achData) {
        //     achData.forEach(element => {
        //         let sid: number = element["sid"];
        //         let value: number = element["value"];
        //         let ach = SampleManager.GetSample(Achievement, sid) as Achievement;
        //         ach.value = value;
        //         this.achievements[sid] = ach;
        //     });
        // }

        let missionsData = js["dailyMissions"];
        if (missionsData) {
            missionsData.forEach(element => {
                let sid: number = element["sid"];
                let value: number = element["value"];
                let mission = SampleManager.getSample(Mission, sid) as Mission;
                mission.updateValue(value);
                this.dailyMissionMap[sid] = mission;
            });
        }
    }

}