import { _decorator, Component, director, Node, Size, sys } from 'cc';
import { State, StateMachine } from './StateMachine';
const { ccclass, property } = _decorator;

// 随机生成一个指定范围内的整数
function randRange_Int (param1: number, param2: number): number {
    const loc: number = Math.random() * (param2 - param1 + 1) + param1;
    return Math.floor(loc);
}

const FAILED_FACTOR = 10; // 模拟失败的概率

enum eLauncherState {
    INIT = 1, //初始化
    FETCH_NATIVE, //获取启动信息
    FETCH_SERVER, //获取服务器相关信息
    UPDATE_RES, //更新资源
    LOGIN, //登陆
    GET_USER, //获取用户信息
    GAMING, //游戏中
    EXIT, //退出游戏
}

class InitState extends State {
    public enter (preState: State = null): boolean {
        console.log("初始化");
        this._owner.changeState(eLauncherState.FETCH_NATIVE);
        return true
    }
    public update(dt: number) {
        console.log("初始化中...");
    }
    public exit() {
        console.log("初始化完成");
    }
}
class FetchNativeState extends State {
    public parseLaunchParams() {
        console.log("解析启动参数");
        // 在这部分解析你的启动参数，注意，这里的实现会根据平台的不同而有不同的处理方式
        // 示例中，我们只是简单地输出信息
        console.log("示例参数解析");
    }
    public getDeviceInfo() {
        console.log("获取设备信息");
        // 获取并打印出屏幕大小
        let screenSize: Size = sys.windowPixelResolution;
        console.log(`屏幕大小：宽=${screenSize.width}, 高=${screenSize.height}`);
        // 这里可以根据需要获取更多的设备信息，例如平台、操作系统等
       
    }
    public enter (preState: State = null): boolean {
        console.log("获取启动信息");
        this.parseLaunchParams();
        this.getDeviceInfo();
        this._owner.changeState(eLauncherState.FETCH_SERVER);
        return true
    }
    public update(dt: number) {
        console.log("获取启动信息中...");
    }
    public exit() {
        console.log("获取启动信息完成");
    }
}

class FetchServerState extends State {
    public fetchConfig() {
        return new Promise((resolve) => {
            console.log("获取游戏配置");
            setTimeout(() => resolve(randRange_Int(0,100)>FAILED_FACTOR), 500); // 延迟模拟
        });
    }
    public fetchResVersion(){
        return new Promise((resolve) => {
            console.log("获取资源版本");
            setTimeout(() => resolve(randRange_Int(0,100)>FAILED_FACTOR), 500); // 延迟模拟
        });
    }

    public enter (preState: State = null): boolean {
        console.log("获取服务器相关信息");
        Promise.all([this.fetchConfig(),this.fetchResVersion()]).then(v=>{
            if(v[0] && v[1]){
                this._owner.setData("retryFetchServerCount",0);
                this._owner.changeState(eLauncherState.UPDATE_RES);
            }else{
                const count = this._owner.getData("retryFetchServerCount") || 0;
                if(count < 2){ //重试2次
                    console.log("获取服务器相关信息重试",count+1,"次");
                    this._owner.setData("retryFetchServerCount",count+1);
                    this._owner.changeState(eLauncherState.FETCH_SERVER)
                }else{
                    console.log("获取服务器相关信息失败");
                    this._owner.setData('exit',eLauncherState.FETCH_SERVER)
                    this._owner.changeState(eLauncherState.EXIT);
                }
            }
        })
        return true
    }
    public update(dt: number) {
        console.log("获取服务器相关信息中...");
    }
    public exit() {
        console.log("获取服务器相关信息完成");
    }
}
class UpdateResState extends State {

    public updateResources() {
        return new Promise((resolve) => {
            console.log("更新资源");
            setTimeout(() => resolve(randRange_Int(0,100)>FAILED_FACTOR), 500); // 延迟模拟
        });
    }
    public enter (preState: State = null): boolean {
        console.log("更新资源");
        this.updateResources().then((res)=>{
            if(res){
                this._owner.setData("retryUpdateResCount",0);
                this._owner.changeState(eLauncherState.LOGIN);
            }else{
                const count = this._owner.getData("retryUpdateResCount") || 0;
                if(count < 3){ //重试3次,退回去获取信息
                    console.log("更新资源重试",count+1,"次");
                    this._owner.setData("retryUpdateResCount",count+1);
                    this._owner.changeState(eLauncherState.FETCH_SERVER)
                }else{
                    console.log("更新资源失败");
                    this._owner.setData('exit',eLauncherState.UPDATE_RES)
                    this._owner.changeState(eLauncherState.EXIT);
                }
            }
        });
        return true
    }
    public update(dt: number) {
        console.log("更新资源中...");
    }
    public exit() {
        console.log("更新资源完成");
    }
}

class LoginState extends State {
    public login() {
        return new Promise((resolve) => {
            console.log("登录游戏服务器");
            setTimeout(() => resolve(randRange_Int(0,100)>FAILED_FACTOR), 500); // 延迟模拟
        });
    }

   
    public enter (preState: State = null): boolean {
        console.log("登陆");
        this.login().then((res)=>{
            if(res){
                this._owner.setData("retryLoginCount",0);
                this._owner.changeState(eLauncherState.GET_USER);
            }else{
                const count = this._owner.getData("retryLoginCount") || 0;
                if(count < 3){ //重试3次
                    console.log("登陆失败重试",count+1,"次");
                    this._owner.setData("retryLoginCount",count+1);
                    this._owner.changeState(eLauncherState.LOGIN)
                }else{
                    console.log("登陆失败");
                    this._owner.setData('exit',eLauncherState.LOGIN)
                    this._owner.changeState(eLauncherState.EXIT);
                }
            }
        });
        return true
    }
    public update(dt: number) {
        console.log("登陆中...");
    }
    public exit() {
        console.log("登陆完成");
    }
}

class GetUserState extends State {
    public fetchUserInfo() {
        return new Promise((resolve) => {
            console.log("拉取用户信息");
            setTimeout(() => resolve(randRange_Int(0,100)>FAILED_FACTOR), 500); // 延迟模拟
        });
    }

    public enter (preState: State = null): boolean {
        console.log("获取用户信息");
        this.fetchUserInfo().then((res)=>{
            if(res){
                this._owner.setData("retryGetUserCount",0);
                this._owner.changeState(eLauncherState.GAMING);
            }else{
                const count = this._owner.getData("retryGetUserCount") || 0;
                if(count < 2){ //重试2次，退回登陆
                    console.log("获取用户失败重试",count+1,"次");
                    this._owner.setData("retryGetUserCount",count+1);
                    this._owner.changeState(eLauncherState.LOGIN)
                }else{
                    console.log("获取用户失败");
                    this._owner.setData('exit',eLauncherState.LOGIN)
                    this._owner.changeState(eLauncherState.EXIT);
                }
            }
        });
        return true
    }
    public update(dt: number) {
        console.log("获取用户信息中...");
    }
    public exit() {
        console.log("获取用户信息完成");
    }
}

class GamingState extends State {
    public enterGame() {
        console.log("进入游戏");
        // 示例：加载主场景
        director.loadScene("main");
    }
    public enter (preState: State = null): boolean {
        console.log("进入游戏");
        this.enterGame();
        return true
    }
    public update(dt: number) {
        console.log("游戏中...");
    }
    public exit() {
        console.log("退出游戏");
    }
}

class ExitState extends State {
    public enter (preState: State = null): boolean {
        console.log("弹框或者退出游戏");
        return true
    }
    public update(dt: number) {
        console.log("退出游戏中...");
    }
    public exit() {
        console.log("退出游戏完成");
    }
}

@ccclass('Launcher4')
export class Launcher4 extends Component {
    private _lanuncherSM = new StateMachine();
    start() {
        this.launchGame();
    }

    launchGame() {
        console.log("启动游戏");
        this._lanuncherSM.registerState(eLauncherState.INIT, new InitState());
        this._lanuncherSM.registerState(eLauncherState.FETCH_NATIVE, new FetchNativeState());
        this._lanuncherSM.registerState(eLauncherState.FETCH_SERVER, new FetchServerState());
        this._lanuncherSM.registerState(eLauncherState.UPDATE_RES, new UpdateResState());
        this._lanuncherSM.registerState(eLauncherState.LOGIN, new LoginState());
        this._lanuncherSM.registerState(eLauncherState.GET_USER, new GetUserState());
        this._lanuncherSM.registerState(eLauncherState.GAMING, new GamingState());
        this._lanuncherSM.registerState(eLauncherState.EXIT, new ExitState());
        this._lanuncherSM.changeState(eLauncherState.INIT);
       
    }
    protected update(dt: number): void {
        this._lanuncherSM?.tick(dt);
    }
}

