using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;
using System.Linq;

namespace AlterchaseSDK
{
    public class ModLoaderTestHelper : MonoBehaviour
    {
        [Header("Asset Bundle Settings")]
        [Tooltip("Path to the asset bundle file to load")]
        public string assetBundlePath;
        
        [Header("Auto-Load Settings")]
        [Tooltip("Name of the level to auto-load (leave empty to skip)")]
        public string levelToLoad;
        
        [Tooltip("Auto-spawn all models in the package")]
        public bool autoSpawnModels = false;
        
        [Tooltip("Auto-spawn all enemies in the package")]
        public bool autoSpawnEnemies = false;
        
        [Header("Spawn Settings")]
        [Tooltip("Spacing between spawned objects")]
        public float spawnSpacing = 3f;
        
        private AssetBundle loadedBundle;
        private AssetBundle loadedScenesBundle;
        private ModPackage loadedPackage;

        private void Start()
        {
            if (string.IsNullOrEmpty(assetBundlePath))
            {
                Debug.LogWarning("Asset bundle path not set. Please assign a path in the Inspector.");
                return;
            }

            StartCoroutine(LoadAndTestMod());
        }

        private IEnumerator LoadAndTestMod()
        {
            Debug.Log($"Loading asset bundle from: {assetBundlePath}");
            
            AssetBundleCreateRequest bundleRequest = AssetBundle.LoadFromFileAsync(assetBundlePath);
            yield return bundleRequest;

            loadedBundle = bundleRequest.assetBundle;

            if (loadedBundle == null)
            {
                Debug.LogError("Failed to load asset bundle!");
                yield break;
            }

            Debug.Log($"Asset bundle loaded successfully. Contains {loadedBundle.GetAllAssetNames().Length} assets.");
            
            string scenesPath = assetBundlePath.Replace(".mod", "_scenes.mod");
            if (System.IO.File.Exists(scenesPath))
            {
                Debug.Log($"Loading scenes bundle from: {scenesPath}");
                AssetBundleCreateRequest scenesBundleRequest = AssetBundle.LoadFromFileAsync(scenesPath);
                yield return scenesBundleRequest;
                
                loadedScenesBundle = scenesBundleRequest.assetBundle;
                
                if (loadedScenesBundle != null)
                {
                    Debug.Log($"Scenes bundle loaded successfully. Contains {loadedScenesBundle.GetAllScenePaths().Length} scenes.");
                }
                else
                {
                    Debug.LogWarning("Failed to load scenes bundle!");
                }
            }

            string[] assetNames = loadedBundle.GetAllAssetNames();
            string packageAssetName = assetNames.FirstOrDefault(name => name.Contains("modpackage") || name.EndsWith(".asset"));

            if (!string.IsNullOrEmpty(packageAssetName))
            {
                AssetBundleRequest assetRequest = loadedBundle.LoadAssetAsync<ModPackage>(packageAssetName);
                yield return assetRequest;

                loadedPackage = assetRequest.asset as ModPackage;
            }

            if (loadedPackage == null)
            {
                ModPackage[] packages = loadedBundle.LoadAllAssets<ModPackage>();
                if (packages.Length > 0)
                {
                    loadedPackage = packages[0];
                }
            }

            if (loadedPackage == null)
            {
                Debug.LogError("Could not find ModPackage in the asset bundle!");
                yield break;
            }

            Debug.Log($"Loaded mod package: {loadedPackage.PackageName} by {loadedPackage.AuthorName}");

            if (!string.IsNullOrEmpty(levelToLoad))
            {
                LoadLevel(levelToLoad);
            }

            if (autoSpawnModels)
            {
                SpawnAllModels();
            }

            if (autoSpawnEnemies)
            {
                SpawnAllEnemies();
            }
        }

        private void LoadLevel(string levelName)
        {
            LevelModAsset[] levels = loadedBundle.LoadAllAssets<LevelModAsset>();
            LevelModAsset level = levels.FirstOrDefault(l => l.AssetName == levelName);

            if (level == null)
            {
                Debug.LogError($"Level '{levelName}' not found in the asset bundle!");
                return;
            }

            Debug.Log($"Loading level: {level.AssetName}");
            
            if (!string.IsNullOrEmpty(level.ScenePath))
            {
                string sceneName = System.IO.Path.GetFileNameWithoutExtension(level.ScenePath);
                
                Debug.Log($"Attempting to load scene '{sceneName}' from asset bundle...");
                
                if (loadedScenesBundle != null && System.Array.Exists(loadedScenesBundle.GetAllScenePaths(), path => path.Contains(sceneName)))
                {
                    SceneManager.LoadScene(sceneName, LoadSceneMode.Additive);
                    Debug.Log($"Level scene loaded successfully: {sceneName}");
                }
                else
                {
                    Debug.LogError($"Scene '{sceneName}' is not included in the asset bundle. Make sure the scene is added to the bundle during build.");
                    Debug.Log($"Scenes in scenes bundle: {string.Join(", ", loadedScenesBundle != null ? loadedScenesBundle.GetAllScenePaths() : new string[0])}");
                }
            }
            else
            {
                Debug.LogWarning($"Level '{levelName}' does not have a valid scene path.");
            }
        }

        private void SpawnAllModels()
        {
            ModelModAsset[] models = loadedBundle.LoadAllAssets<ModelModAsset>();
            
            if (models.Length == 0)
            {
                Debug.Log("No models found in the asset bundle.");
                return;
            }

            Debug.Log($"Spawning {models.Length} models...");

            Vector3 spawnPosition = transform.position;

            for (int i = 0; i < models.Length; i++)
            {
                if (models[i].ModelPrefab != null)
                {
                    Vector3 offset = new Vector3(i * spawnSpacing, 0, 0);
                    GameObject instance = Instantiate(models[i].ModelPrefab, spawnPosition + offset, Quaternion.identity);
                    instance.name = $"{models[i].AssetName} (Spawned)";
                    Debug.Log($"Spawned model: {models[i].AssetName}");
                }
            }
        }

        private void SpawnAllEnemies()
        {
            EnemyModAsset[] enemies = loadedBundle.LoadAllAssets<EnemyModAsset>();
            
            if (enemies.Length == 0)
            {
                Debug.Log("No enemies found in the asset bundle.");
                return;
            }

            Debug.Log($"Spawning {enemies.Length} enemies...");

            Vector3 spawnPosition = transform.position + Vector3.forward * 5f;

            for (int i = 0; i < enemies.Length; i++)
            {
                if (enemies[i].EnemyPrefab != null)
                {
                    Vector3 offset = new Vector3(i * spawnSpacing, 0, 0);
                    GameObject instance = Instantiate(enemies[i].EnemyPrefab, spawnPosition + offset, Quaternion.identity);
                    instance.name = $"{enemies[i].AssetName} (Spawned)";
                    Debug.Log($"Spawned enemy: {enemies[i].AssetName}");
                }
            }
        }

        public void SpawnModel(string modelName)
        {
            if (loadedBundle == null)
            {
                Debug.LogError("No asset bundle loaded!");
                return;
            }

            ModelModAsset[] models = loadedBundle.LoadAllAssets<ModelModAsset>();
            ModelModAsset model = models.FirstOrDefault(m => m.AssetName == modelName);

            if (model == null || model.ModelPrefab == null)
            {
                Debug.LogError($"Model '{modelName}' not found or has no prefab!");
                return;
            }

            GameObject instance = Instantiate(model.ModelPrefab, transform.position, Quaternion.identity);
            instance.name = $"{model.AssetName} (Spawned)";
            Debug.Log($"Spawned model: {model.AssetName}");
        }

        public void SpawnEnemy(string enemyName)
        {
            if (loadedBundle == null)
            {
                Debug.LogError("No asset bundle loaded!");
                return;
            }

            EnemyModAsset[] enemies = loadedBundle.LoadAllAssets<EnemyModAsset>();
            EnemyModAsset enemy = enemies.FirstOrDefault(e => e.AssetName == enemyName);

            if (enemy == null || enemy.EnemyPrefab == null)
            {
                Debug.LogError($"Enemy '{enemyName}' not found or has no prefab!");
                return;
            }

            GameObject instance = Instantiate(enemy.EnemyPrefab, transform.position, Quaternion.identity);
            instance.name = $"{enemy.AssetName} (Spawned)";
            Debug.Log($"Spawned enemy: {enemy.AssetName}");
        }

        private void OnDestroy()
        {
            if (loadedBundle != null)
            {
                loadedBundle.Unload(true);
                Debug.Log("Asset bundle unloaded.");
            }
            
            if (loadedScenesBundle != null)
            {
                loadedScenesBundle.Unload(true);
                Debug.Log("Scenes bundle unloaded.");
            }
        }
    }
}
