import { _decorator, Component, Label, Tween, tween, v3 } from "cc";
import { Logger } from "./Logger";
const { ccclass, property } = _decorator;

/*初始化加载界面*/

interface LoadingTask {
    progress: number;
    tips?: string;
    callback?: () => void | Promise<void>;
}

@ccclass("LoadingUI")
export class LoadingUI extends Component {
    @property(Label)
    public progressLabel: Label = null!;
    
    @property(Label)
    public tipLabel: Label = null!;
    
    private _currentProgress = 0;
    private _isLoading = false;
    private _progressTween: Tween<any> | null = null;
    private _taskQueue: LoadingTask[] = [];
    private _currentTaskIndex = 0;

    /**
     * 开始加载流程
     * @param initialProgress 初始进度 (0-100)
     * @example 调用事例:
     *  this.loadingUI.startLoading();
        //添加所有加载任务
        this.loadingUI.addTask(10, '资源加载中...', () => {
            PlayerData.ins().initialize();
            PlatformSystem.initialize();
            SettingData.ins().initialize();
        });
        this.loadingUI.addTask(30, '加载音乐资源...', async () => {
            await AudioManager.initialize();
        });
        this.loadingUI.addTask(40, '加载关卡数据...', async () => {
            await LevelsResData.ins().initialize();
            await LevelsResData.instance.preLoadAllMap();
        });
        this.loadingUI.addTask(20, '预加载场景...', async () => {
            await SceneManager.initialize();
        });
        //执行所有任务完成后会自动调用finishLoading()
        await this.loadingUI.executeTasks();
     */
    public startLoading(initialProgress: number = 0) {
        if (this._isLoading) {
            Logger.warn("Loading is already in progress");
            return;
        }
        this.node.active = true;
        this._isLoading = true;
        this._currentProgress = initialProgress;
        this._updateProgressDisplay(this._currentProgress);
    }

    /**
     * 添加一个加载任务
     * @param progress 该任务增加的进度值 (0-100)
     * @param tips 提示文本
     * @param callback 任务回调函数，可以是异步的
     */
    public addTask(progress: number, tips?: string, callback?: () => void | Promise<void>) {
        this._taskQueue.push({ progress, tips, callback });
    }

    /**
     * 执行所有加载任务
     */
    public async executeTasks() {
        if (!this._isLoading) {
            Logger.warn("Loading has not started yet");
            return;
        }
        for (this._currentTaskIndex = 0; this._currentTaskIndex < this._taskQueue.length; this._currentTaskIndex++) {
            const task = this._taskQueue[this._currentTaskIndex];
            //更新提示文本
            if (task.tips) {
                this.tipLabel.string = task.tips;
            }
            //执行任务回调
            if (task.callback) {
                try {
                    const result = task.callback();
                    if (result instanceof Promise) {
                        await result;
                    }
                } catch (error) {
                    Logger.error("Loading task failed:", error);
                }
            }
            //更新进度
            await this._updateProgress(this._currentProgress + task.progress);
        }
        //所有任务完成后自动完成加载
        await this.finishLoading();
    }

    /**
     * 直接设置进度（带动画）
     * @param targetProgress 目标进度 (0-100)
     * @param duration 动画持续时间 (秒)
     */
    public async setProgress(targetProgress: number, duration: number = 0.3) {
        if(!this._isLoading) {
            Logger.warn("Loading has not started yet");
            return;
        }
        await this._updateProgress(targetProgress, duration);
    }

    /**
     * 完成加载（自动跳转到100%）
     */
    public async finishLoading(isHide: boolean = false) {
        if(!this._isLoading) {
            Logger.warn("Loading has not started yet");
            return;
        }
        await this._updateProgress(100, 0.5);
        this._isLoading = false;
        //延迟隐藏
        await new Promise(resolve => setTimeout(resolve, 500));
        if(isHide){this.node.active = false;}
        //重置状态
        this._reset();
    }

    private _reset() {
        this._currentProgress = 0;
        this._taskQueue = [];
        this._currentTaskIndex = 0;
        if (this._progressTween) {
            this._progressTween.stop();
            this._progressTween = null;
        }
    }

    private async _updateProgress(targetProgress: number, duration: number = 0.3) {
        //确保进度在0-100范围内
        targetProgress = Math.min(100, Math.max(0, targetProgress));
        // 如果不需要动画，直接设置
        if (duration <= 0) {
            this._currentProgress = targetProgress;
            this._updateProgressDisplay(this._currentProgress);
            return;
        }
        //使用Tween实现平滑过渡
        return new Promise<void>((resolve) => {
            if (this._progressTween) {
                this._progressTween.stop();
            }
            const startProgress = this._currentProgress;
            this._progressTween = tween({ progress: startProgress })
                .to(duration, { progress: targetProgress }, {
                    onUpdate: (target) => {
                        this._currentProgress = Math.floor(target.progress);
                        this._updateProgressDisplay(this._currentProgress);
                    },
                    onComplete: () => {
                        this._currentProgress = targetProgress;
                        this._updateProgressDisplay(this._currentProgress);
                        this._progressTween = null;
                        resolve();
                    }
                })
                .start();
        });
    }

    private _updateProgressDisplay(progress: number) {
        this.progressLabel.string = `${progress}%`;
    }
}