using System;
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using UnityEngine.SceneManagement;

namespace CustomAssetBundleSystem
{
    /// <summary>
    /// Manages AssetBundle downloads during LoadingScreen with UI feedback
    /// Checks cache, downloads if needed, handles offline mode
    /// </summary>
    public class AssetBundleDownloadManager : MonoBehaviour
    {
        [Header("UI References")]
        [SerializeField] private Slider loadingSlider;
        [SerializeField] private TextMeshProUGUI loadingText;
        [SerializeField] private TextMeshProUGUI hintsText;
        [SerializeField] private GameObject noInternetPanel; // Optional: Shows when internet required but not available

        [Header("Download Settings")]
        [SerializeField] private string[] bundlesToPreload = new[] { "gamescene" };
        [SerializeField] private float minDisplayTime = 2f; // Minimum time to show loading (for UX)

        [Header("Hints")]
        [SerializeField] private string[] downloadHints = new[]
        {
            "Downloading game content...",
            "Preparing assets for better performance...",
            "First time setup - this only happens once!",
            "Future launches will be instant!"
        };

        [SerializeField] private string[] cachedHints = new[]
        {
            "Complete Weekly Missions to gain XP",
            "Complete a 20 Wins streak to level up in Rank",
            "Missions change every Week"
        };

        // State
        private bool _isDownloading = false;
        private bool _downloadComplete = false;
        private bool _hasInternet = true;
        private RemoteAssetBundleManager _bundleManager;

        // Events
        public event Action<bool> OnDownloadComplete; // true = success, false = failed

        private void Awake()
        {
            _bundleManager = RemoteAssetBundleManager.Instance;
        }

        /// <summary>
        /// Start the download process - call this from LoadingScreen
        /// </summary>
        public IEnumerator StartDownloadProcess(Action<bool> onComplete = null)
        {
            if (_isDownloading)
            {
                Debug.LogWarning("[DownloadManager] Download already in progress");
                yield break;
            }

            _isDownloading = true;
            _downloadComplete = false;
            float startTime = Time.time;

            Debug.Log("[DownloadManager] Starting AssetBundle download process...");

            // Step 1: Initialize RemoteAssetBundleManager (downloads catalog)
            yield return InitializeBundleSystem();

            if (!_bundleManager.IsInitialized)
            {
                Debug.LogError("[DownloadManager] Failed to initialize bundle system");
                HandleDownloadFailed("Failed to connect to server");
                onComplete?.Invoke(false);
                OnDownloadComplete?.Invoke(false);
                yield break;
            }

            // Step 2: Check if bundles are already cached
            bool allCached = CheckIfBundlesCached();

            if (allCached)
            {
                Debug.Log("[DownloadManager] ✓ All bundles already cached! (Offline play available)");
                UpdateUI(1f, "Ready!", cachedHints);
                
                // Show success for minimum display time
                float elapsed = Time.time - startTime;
                if (elapsed < minDisplayTime)
                {
                    yield return new WaitForSeconds(minDisplayTime - elapsed);
                }

                _downloadComplete = true;
                _isDownloading = false;
                onComplete?.Invoke(true);
                OnDownloadComplete?.Invoke(true);
                yield break;
            }

            // Step 3: Need to download - check internet connectivity
            _hasInternet = Application.internetReachability != NetworkReachability.NotReachable;

            if (!_hasInternet)
            {
                Debug.LogWarning("[DownloadManager] No internet connection and bundles not cached");
                HandleNoInternet();
                onComplete?.Invoke(false);
                OnDownloadComplete?.Invoke(false);
                yield break;
            }

            // Step 4: Download bundles with progress updates
            Debug.Log($"[DownloadManager] Downloading {bundlesToPreload.Length} bundle(s)...");
            UpdateUI(0f, "Downloading game content", downloadHints);

            bool downloadSuccess = true;
            int bundleIndex = 0;

            foreach (string bundleName in bundlesToPreload)
            {
                bundleIndex++;
                Debug.Log($"[DownloadManager] Downloading bundle {bundleIndex}/{bundlesToPreload.Length}: {bundleName}");

                bool bundleLoaded = false;
                float bundleProgress = 0f;

                // Subscribe to progress updates
                void ProgressHandler(string name, float progress)
                {
                    if (name == bundleName)
                    {
                        bundleProgress = progress;
                        float overallProgress = (bundleIndex - 1f + progress) / bundlesToPreload.Length;
                        UpdateUI(overallProgress, $"Downloading {bundleName}", downloadHints);
                    }
                }

                _bundleManager.OnBundleDownloadProgress += ProgressHandler;

                // Start download
                yield return _bundleManager.LoadBundleAsync(bundleName, (bundle) =>
                {
                    bundleLoaded = (bundle != null);
                });

                _bundleManager.OnBundleDownloadProgress -= ProgressHandler;

                if (!bundleLoaded)
                {
                    Debug.LogError($"[DownloadManager] Failed to download bundle: {bundleName}");
                    downloadSuccess = false;
                    break;
                }

                Debug.Log($"[DownloadManager] ✓ Bundle '{bundleName}' ready!");
            }

            if (!downloadSuccess)
            {
                HandleDownloadFailed("Failed to download game content");
                onComplete?.Invoke(false);
                OnDownloadComplete?.Invoke(false);
                yield break;
            }

            // Step 5: Success!
            UpdateUI(1f, "Download complete!", downloadHints);
            Debug.Log("[DownloadManager] ✓ All bundles downloaded and cached successfully!");

            // Show success for minimum display time
            float totalElapsed = Time.time - startTime;
            if (totalElapsed < minDisplayTime)
            {
                yield return new WaitForSeconds(minDisplayTime - totalElapsed);
            }

            _downloadComplete = true;
            _isDownloading = false;
            onComplete?.Invoke(true);
            OnDownloadComplete?.Invoke(true);
        }

        /// <summary>
        /// Initialize the bundle system (downloads catalog)
        /// </summary>
        private IEnumerator InitializeBundleSystem()
        {
            Debug.Log("[DownloadManager] Initializing bundle system...");
            UpdateUI(0.05f, "Connecting to server", downloadHints);

            yield return _bundleManager.InitializeAsync();

            if (_bundleManager.IsInitialized)
            {
                Debug.Log("[DownloadManager] ✓ Bundle system initialized");
            }
        }

        /// <summary>
        /// Check if all required bundles are already cached
        /// </summary>
        private bool CheckIfBundlesCached()
        {
            foreach (string bundleName in bundlesToPreload)
            {
                if (!_bundleManager.IsBundleCached(bundleName))
                {
                    Debug.Log($"[DownloadManager] Bundle '{bundleName}' not cached - download required");
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// Update UI elements with progress and hints
        /// </summary>
        private void UpdateUI(float progress, string statusText, string[] hints)
        {
            if (loadingSlider != null)
            {
                loadingSlider.value = progress;
            }

            if (loadingText != null)
            {
                loadingText.text = statusText;
            }

            if (hintsText != null && hints != null && hints.Length > 0)
            {
                // Show random hint or cycle through them
                int hintIndex = Mathf.FloorToInt(progress * hints.Length);
                hintIndex = Mathf.Clamp(hintIndex, 0, hints.Length - 1);
                hintsText.text = hints[hintIndex];
            }
        }

        /// <summary>
        /// Handle no internet connection scenario
        /// </summary>
        private void HandleNoInternet()
        {
            Debug.LogWarning("[DownloadManager] ⚠️ No internet connection!");

            if (loadingText != null)
            {
                loadingText.text = "No Internet Connection";
            }

            if (hintsText != null)
            {
                hintsText.text = "Please connect to the internet to download game content";
            }

            if (noInternetPanel != null)
            {
                noInternetPanel.SetActive(true);
            }

            // Don't proceed - block user until they have internet
            _isDownloading = false;
        }

        /// <summary>
        /// Handle download failure
        /// </summary>
        private void HandleDownloadFailed(string errorMessage)
        {
            Debug.LogError($"[DownloadManager] Download failed: {errorMessage}");

            if (loadingText != null)
            {
                loadingText.text = "Download Failed";
            }

            if (hintsText != null)
            {
                hintsText.text = errorMessage;
            }

            _isDownloading = false;
        }

        /// <summary>
        /// Check if download is complete and successful
        /// </summary>
        public bool IsDownloadComplete()
        {
            return _downloadComplete;
        }

        /// <summary>
        /// Retry button handler (for no internet panel)
        /// </summary>
        public void RetryDownload()
        {
            if (noInternetPanel != null)
            {
                noInternetPanel.SetActive(false);
            }

            // Restart the download process
            StartCoroutine(StartDownloadProcess());
        }

        /// <summary>
        /// Get cache status for UI display
        /// </summary>
        public string GetCacheStatus()
        {
            if (!_bundleManager.IsInitialized)
            {
                return "Not initialized";
            }

            int cachedCount = 0;
            foreach (string bundleName in bundlesToPreload)
            {
                if (_bundleManager.IsBundleCached(bundleName))
                {
                    cachedCount++;
                }
            }

            if (cachedCount == bundlesToPreload.Length)
            {
                return "All content cached (Offline play available)";
            }
            else if (cachedCount > 0)
            {
                return $"{cachedCount}/{bundlesToPreload.Length} bundles cached";
            }
            else
            {
                return "Download required";
            }
        }
    }
}
