import { Prefab } from "cc";
import Singleton from "../../../extensions/ngame/assets/ngame/util/Singleton";
import { Camera } from "cc";
import GBaseMode from "./GBaseMode";
import { Node } from "cc";
import { instantiate } from "cc";
import { TD, app } from "../App";
import { JNFrameInfo, JNSyncFrameEvent } from "../../../extensions/ngame/assets/ngame/sync/frame/JNSyncFrame";
import { CCObject } from "cc";
import { Env, EnvCurrent } from "../Env";
import { TB } from "../config/data/schema";
import BattleResource from "../tools/BattleResource";
import { director } from "cc";
import { game } from "cc";

export enum BattleMode{
    //无尽模式
    OnHook = 0,     
    //PVP 模式
    PVP = 1,
    //阵营守护
    CampGuardian = 2,
}

export interface GBattleModeInfo{
    modes:Prefab[], //模式预制体
    camera:Camera,  //场景相机
    root:Node,      //世界场景Root
}

//事件
export enum GBattleModeEvent{
    //关闭模式
    Close = "GBattleModeEvent_Close",
    StartLoadingResource = "GBattleModeEvent_StartLoadingResource",
    EndLoadingResource = "GBattleModeEvent_EndLoadingResource",
}

//全局战斗模式管理器
export default class GBattleModeManager extends Singleton {

    //模式预制体
    modes:Prefab[] = [];
    //场景相机
    camera:Camera;
    //世界场景Root
    root:Node;

    //是否初始化
    isInit:boolean = false;

    //当前模式
    current:BattleMode = null;

    //是否自动推帧
    isAuto:boolean = false;
    //是否推追帧
    isAutoMaxFrame:boolean = false;

    //自动推帧间隔
    autoTime:number = 0;

    //默认模式
    default:BattleMode = BattleMode.OnHook; //默认无限模式

    //模式数据
    data:any;

    //是否加载资源
    isLoadingResource:boolean = false;

    //加载index
    loadingIndex:number = 0;

    //初始化管理器
    async onInit(info:GBattleModeInfo){

        this.modes = info.modes || [];
        this.camera = info.camera;
        this.root = info.root;
        this.camera.enabled = false;

        //监听帧同步 世界创建逻辑
        app.event.on(JNSyncFrameEvent.CLEAR,this.clear,this);
        app.event.on(JNSyncFrameEvent.CREATE,this.create,this);

        this.isInit = true;

    }

    //打开指定模式
    // isAuto 是否自动推帧
    // data 模式数据
    // res  资源加载列表 (因为是帧同步所以打开模式前必须提前加载可能使用的资源)
    async Open(mode:BattleMode = null,isAuto:boolean = false,data:any = this.data){

        if(!this.current && mode == null){
            //裁决员不允许默认模式
            if(EnvCurrent == Env.Server) return;
            await this.Open(this.default,true,data);
            return;
        }else if(mode == null){
            return;
        }
        
        this.current = mode;
        this.Close();
        this.current = mode;
        this.data = data;
        this.setAuto(isAuto);

        //加载资源
        let loadingIndex = (this.loadingIndex+=1);
        this.isLoadingResource = true;
        app.event.emit(GBattleModeEvent.StartLoadingResource);
        console.log("[GBattleModeManager] 加载资源");
        await BattleResource.loadResource(mode,data);
        console.log("[GBattleModeManager] 加载结束",loadingIndex,this.loadingIndex);
        if(this.loadingIndex == loadingIndex){
            //资源加载完成则显示世界
            app.sync.onReset();
            this.isLoadingResource = false;
            app.event.emit(GBattleModeEvent.EndLoadingResource);
            app.sync.onStart();
        }else{
            //如果加载中途切换了模式则直接返回
            return;
        }

    }

    //重置当前模式
    Reset(){
        app.sync.onReset();
        app.sync.onStart();
    }

    //关闭当前模式
    async Close(data?:any){

        //主动调用场景销毁
        app.sync.onReset();
        let current = this.current;
        this.current = null;

        //结束通知
        app.event.emit(GBattleModeEvent.Close,current,data);
    }

    //设置自动推帧 ( 帧不由addFrame控制 管理器自动推帧)
    setAuto(is:boolean,isAutoMaxFrame:boolean = false){
        this.isAuto = is;
        this.isAutoMaxFrame = isAutoMaxFrame;
        this.autoTime = 0;
    }

    //清除当前模式
    private clear(){
        if(!this.isInit) return;
        this.root.destroyAllChildren();
        //关闭相机
        this.camera.enabled = false;
    }

    //创建当前模式
    private create(){
        
        if(!this.isInit || this.current == null) return;
        let mode = instantiate(this.modes[this.current]);
        //关闭相机
        this.camera.enabled = false;
        mode.getComponent(GBaseMode).camera = this.camera;
        mode.getComponent(GBaseMode).data = this.data;
        this.root.addChild(mode)

    }

    //向场景推帧
    addFrame(info:JNFrameInfo){
        if(this.isAuto) return; //如果是自动推帧则返回
        app.sync.addFrame(info,true);
    }

    //管理器更新
    onUpdate(dt:number){
        //更新帧同步
        app.sync.update(dt);
        //自动推帧
        this.onAutoFrame(dt);

        //如果当前模式是空则默认模式
        if(this.current == null){
            this.Open();
        }

    }
    
    //自动推帧
    private onAutoFrame(dt:number){

        if(!this.isAuto) return;
        
        if(this.isAutoMaxFrame){

            //保持超高频率追帧
            while(app.sync.nFrameQueue.length < (app.sync.nMaxFrameLoopBan * 2)){
                //速度推帧
                app.sync.addFrame({
                    index:app.sync.nLocalFrame + 1
                });
            }

        }else{
            
            //正常追帧

            this.autoTime += dt * 1000;

            //获取当前帧同步的帧数推空帧
            if(app.sync.nSyncTime < this.autoTime){
                //如果事件够则推帧
                this.autoTime -= app.sync.nSyncTime;
                app.sync.addFrame({
                    index:app.sync.nLocalFrame + 1
                });
            }

        }

    }

}