import { BattleBase } from "../base/BattleBase";
import { BattleEventManager } from "../base/BattleEventManager";
import { BattleEventData_Over, BattleEventTarget, BattleEventType } from "../base/BattleEventUtil";
import { ObjectValueType } from "../data/BattleEnum";
import { BattleUtil } from "../data/BattleUtil";
import { MapData } from "../data/MapData";
import { BuffControl } from "./BuffControl";
import { EnemyControl } from "./EnemyControl";
import { HeroControl } from "./HeroControl";
import { SkillControl } from "./SkillControl";

//战斗控制类
export class BattleControl extends BattleBase{
    map:MapData = null

    //英雄控制类
    heroControl:HeroControl = null
    //敌人控制类
    enemyControl:EnemyControl = null

    //buff控制类
    buffControl:BuffControl = null

    battleEventManager:BattleEventManager = null


    private static instance:BattleControl;
    static GetInstance():BattleControl{
        if(!BattleControl.instance){
            BattleControl.instance = new BattleControl();
        }
        return BattleControl.instance;
    }

    //初始化
    init(battleID:number){

        this.battleEventManager = BattleEventManager.instance
        this.map = MapData.GetInstance()
        this.heroControl = new HeroControl()
        this.enemyControl = new EnemyControl()
        this.buffControl = new BuffControl()


        this.map.init(battleID)
        this.buffControl.init()
        this.heroControl.init()
        this.enemyControl.init()
        SkillControl.GetInstance().init()
    
        // for(let i = 0; i < BattleUtil.TurnMax; i++){
        //     this.update()
        //     if(this.map.battleEnd){
        //         break;
        //     }
        // }
        // this.map.battleEnd = true
    }

    reset(battleID:number){
        this.clear()
        this.map.reset(battleID)
        this.buffControl.init()
        this.heroControl.init()
        this.enemyControl.init()
        SkillControl.GetInstance().init()
    }

    clear(){
        this.map.clear()
    }

    //每次加一帧
    update(){
        this.map.curTurn++
        if(this.map.battleEnd){
            return
        }
        //更新操作结果
        this.updateAction()
        //更新子弹
        // this.updateBullet()
        this.updateBuff()
        //更新敌人(基础参数,技能,buff)
        this.updateEnemy()
   
        //更新英雄(基础参数,技能,buff)
        this.updateHero()

        this.buffControl.updateNewBuff()
        //判断是否结束

        if((this.map.enemyDataList.length == 0) && (this.map.bornNeedTime < this.map.curTurn)){
            this.map.battleEnd = true
            this.map.bWin = true
            let eventData:BattleEventData_Over = {
                eventType: BattleEventType.Over,
                bWin: true
            }
            this.battleEventManager.fireEvent(BattleEventTarget.Update,eventData)
        }
    }

    get mapID():number{
        return this.map.typeID
    }

    //敌人总血量
    get allEnemyHP():number{
        return this.map.allEnemyHP
    }

    //初始化操作列表,服务器才用的
    // initAction(actionJson:string){
    //     let actionList = JSON.parse(actionJson)
    //     if(actionList){
    //         this.map.actionMap = actionList
    //     }
    // }

    //更新操作结果
    private updateAction(){
        let actionList = this.map.actionMap.get(this.map.curTurn)
        if(actionList == null){
            return
        }
        for(let i = 0; i < actionList.length; i++){
            let heroDataChange:BattleUtil.HeroDataChange = actionList[i]

            switch(heroDataChange.changeType){
                case ObjectValueType.InBattle:{
                        let startPosID = heroDataChange.changeValueLlist[2] 
                        let startPos = this.map.attackPosDataMap.get(startPosID)
                        if(startPos){
                            let heroData = this.map.addHero(heroDataChange.changeValueLlist[0],heroDataChange.changeValueLlist[1],heroDataChange.changeValueLlist[2])
                            startPos.hero = heroData
                        }
                        break
                    }
                case ObjectValueType.OutBattle:{
                    let startPosID = heroDataChange.changeValueLlist[0] 
                    this.map.removeHero(startPosID)
                    break
                }
                case ObjectValueType.PosID:{
                    let startPosID = heroDataChange.changeValueLlist[0] 
                    let endPosID = heroDataChange.changeValueLlist[1]

                    let startPos = this.map.attackPosDataMap.get(startPosID)
                    let endPos = this.map.attackPosDataMap.get(endPosID)

                    let startHero = startPos?.hero
                    let endHero = endPos?.hero

                    if(startPos){
                        startPos.hero = endHero
                        endHero.position = startPos.pos
                    }
                    if(endPos){
                        endPos.hero = startHero
                        endHero.position = endPos.pos
                    }
                    break;
                }
                case ObjectValueType.Level:{
                        let startPosID = heroDataChange.changeValueLlist[0] 
                        let startPos = this.map.attackPosDataMap.get(startPosID)
                        if(startPos && startPos.hero){
                            startPos.hero.levelUp()
                        }
                        break;
                    }
                
            }
           
        }
    }


    //更新buff计时
    private updateBuff(){
        this.buffControl.update()
    }

    //更新敌人(基础参数,技能,buff)
    private updateEnemy(){
        this.enemyControl.update()
    }

    //更新英雄(基础参数,技能,buff)
    private updateHero(){
        this.heroControl.update()
    }

    //添加操作步骤
    addAction(action:BattleUtil.HeroDataChange){
        if(!this.map.actionMap.get(this.map.curTurn+1)){
            this.map.actionMap.set(this.map.curTurn+1,[])
        }
        this.map.actionMap.get(this.map.curTurn+1).push(action)
        console.log("添加操作步骤",this.map.curTurn,action)
    }

    //上阵
    addHeroInPos(heroID:number,level:number,index:number){
        let posID = this.getPosIDByIndex(index)
        if(posID == BattleUtil.PosID_Init){
            return
        }
        let action:BattleUtil.HeroDataChange = {
            changeType: ObjectValueType.InBattle,
            changeValueLlist: [heroID,level,posID]
        }
        this.addAction(action)
    }
    //下阵
    removeHeroInPos(index:number){
        let posID = this.getPosIDByIndex(index)
        let action:BattleUtil.HeroDataChange = {
            changeType: ObjectValueType.OutBattle,
            changeValueLlist: [posID]
        }
        this.addAction(action)
    }
    //升级
    levelUp(index:number){
        let posID = this.getPosIDByIndex(index)
        let action:BattleUtil.HeroDataChange = {
            changeType: ObjectValueType.Level,
            changeValueLlist: [posID]
        }
        this.addAction(action)
    }

    //判断是否结束
    get isBattleEnd():boolean{
        return this.map.battleEnd
    }


    getPosIDByIndex(index:number){
        return this.map.attackPosition[index] || BattleUtil.PosID_Init
    }

       //根据id获取坐标 取值范围[0,this.length-1]
    getPosition(id:number):BattleUtil.Vector2{
        
        return this.map.getPosition(id);
    }

}