using System;
using System.Collections.Generic;
using System.Threading;
using Cysharp.Threading.Tasks;
using MotionFramework;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace Framework.Scripts.Runtime.Engine.Scene
{
    /// <summary>
    /// 场景管理器
    /// </summary>
    public class SceneManager : ModuleSingleton<SceneManager>, IModule
    {
        private string _currentSceneName;
        private string _nextSceneName;
        private bool _isLoading;
        private float _loadingProgress;
        private Action<float> _onLoadingProgressCallback;
        private Action _onLoadingCompleteCallback;
        private HashSet<string> _preloadedScenes = new HashSet<string>();
        private CancellationTokenSource _loadingCancellation;
        private bool _isProcessingScene;

        public string CurrentSceneName => _currentSceneName;
        public bool IsLoading => _isLoading;
        public float LoadingProgress => _loadingProgress;

        public void OnCreate(object createParam)
        {
            _currentSceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
            _loadingCancellation = new CancellationTokenSource();
        }

        public void OnUpdate()
        {
        }

        public void OnDestroy()
        {
            _loadingCancellation?.Cancel();
            _loadingCancellation?.Dispose();
            _loadingCancellation = null;
        }

        public void OnGUI()
        {
        }

        /// <summary>
        /// 重置加载状态
        /// </summary>
        private void ResetLoadingState()
        {
            _isLoading = false;
            _loadingProgress = 0f;
            _onLoadingProgressCallback = null;
            _onLoadingCompleteCallback = null;
            
            // 取消之前的加载操作
            if (_loadingCancellation != null)
            {
                if (!_loadingCancellation.IsCancellationRequested)
                    _loadingCancellation.Cancel();
                _loadingCancellation.Dispose();
            }
            _loadingCancellation = new CancellationTokenSource();
        }

        /// <summary>
        /// 加载场景并等待初始化完成
        /// </summary>
        /// <param name="sceneName">场景名称</param>
        /// <param name="onSceneInitialized">场景初始化完成后的回调，在这里执行场景加载后的初始化逻辑</param>
        /// <param name="onProgress">加载进度回调</param>
        /// <param name="onComplete">场景加载完成的回调</param>
        public async UniTask LoadSceneAndWaitAsync(
            string sceneName,
            Action<float> onProgress = null,
            Action onComplete = null)
        {
            if (string.IsNullOrEmpty(sceneName))
            {
                Debug.LogError("场景名称不能为空!");
                return;
            }

            if (_isProcessingScene)
            {
                Debug.LogError("已有场景正在处理中，请等待完成!");
                return;
            }

            _isProcessingScene = true;

            try
            {
                // 创建一个TaskCompletionSource来等待场景加载完成
                var tcs = new UniTaskCompletionSource();

                // 加载场景
                LoadSceneAsync(sceneName, onProgress, () => tcs.TrySetResult());

                // 等待场景加载完成
                await tcs.Task;

                // 等待一帧确保场景已经完全准备好
                await UniTask.NextFrame();


                onComplete?.Invoke();
            }
            finally
            {
                _isProcessingScene = false;
            }
        }

        /// <summary>
        /// 异步加载场景
        /// </summary>
        /// <param name="sceneName">场景名称</param>
        /// <param name="onProgress">加载进度回调</param>
        /// <param name="onComplete">加载完成回调</param>
        public async UniTaskVoid LoadSceneAsync(string sceneName, Action<float> onProgress = null, Action onComplete = null)
        {
            if (string.IsNullOrEmpty(sceneName))
            {
                Debug.LogError("场景名称不能为空!");
                return;
            }

            // 如果正在加载，先重置状态
            if (_isLoading)
            {
                Debug.LogWarning("上一个场景加载被中断!");
                ResetLoadingState();
            }

            _nextSceneName = sceneName;
            _onLoadingProgressCallback = onProgress;
            _onLoadingCompleteCallback = onComplete;
            _isLoading = true;

            try 
            {
                await LoadSceneAsyncInternal().AttachExternalCancellation(_loadingCancellation.Token);
            }
            catch (OperationCanceledException)
            {
                Debug.LogWarning($"场景 {sceneName} 加载已取消");
                ResetLoadingState();
            }
            catch (Exception e)
            {
                Debug.LogError($"加载场景 {sceneName} 失败: {e}");
                ResetLoadingState();
            }
        }

        /// <summary>
        /// 预加载场景
        /// </summary>
        /// <param name="sceneName">场景名称</param>
        public async UniTask PreloadSceneAsync(string sceneName)
        {
            if (string.IsNullOrEmpty(sceneName))
            {
                Debug.LogError("场景名称不能为空!");
                return;
            }

            if (_preloadedScenes.Contains(sceneName))
            {
                return;
            }

            var operation = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
            if (operation != null)
            {
                operation.allowSceneActivation = false;
                await operation.ToUniTask(Progress.Create<float>(progress => 
                {
                    Debug.Log($"预加载场景 {sceneName}: {progress}");
                }));
                _preloadedScenes.Add(sceneName);
            }
        }

        /// <summary>
        /// 卸载预加载的场景
        /// </summary>
        /// <param name="sceneName">场景名称</param>
        public async UniTask UnloadPreloadedSceneAsync(string sceneName)
        {
            if (_preloadedScenes.Contains(sceneName))
            {
                await UnityEngine.SceneManagement.SceneManager.UnloadSceneAsync(sceneName).ToUniTask();
                _preloadedScenes.Remove(sceneName);
            }
        }

        private async UniTask LoadSceneAsyncInternal()
        {
            try
            {
                // 开始加载前等待一帧，让UI有时间更新
                await UniTask.Yield(_loadingCancellation.Token);

                // 开始异步加载场景
                var operation = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(_nextSceneName);
                if (operation == null)
                {
                    throw new Exception($"开始加载场景失败: {_nextSceneName}");
                }

                operation.allowSceneActivation = false;

                // 等待加载完成
                while (operation.progress < 0.9f)
                {
                    _loadingProgress = operation.progress;
                    _onLoadingProgressCallback?.Invoke(_loadingProgress);
                    await UniTask.Yield(_loadingCancellation.Token);
                }

                // 当进度达到0.9时，场景已经加载完成，等待激活
                operation.allowSceneActivation = true;

                // 等待场景完全加载完成
                await operation.ToUniTask(Progress.Create<float>(progress =>
                {
                    _loadingProgress = progress;
                    _onLoadingProgressCallback?.Invoke(progress);
                }), PlayerLoopTiming.Update, _loadingCancellation.Token);

                // 确保新场景已经被激活
                await UniTask.WaitUntil(() => 
                    UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == _nextSceneName, 
                    PlayerLoopTiming.Update, _loadingCancellation.Token);

                // 更新当前场景名称
                _currentSceneName = _nextSceneName;
                _loadingProgress = 1f;
                
                // 调用加载完成回调
                _onLoadingProgressCallback?.Invoke(1f);
                _onLoadingCompleteCallback?.Invoke();
            }
            finally
            {
                _isLoading = false;
                // 清理回调
                _onLoadingProgressCallback = null;
                _onLoadingCompleteCallback = null;
            }
        }
    }
} 