using UnityEngine;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using Streamingle.Debug;
using System.Linq;

namespace Streamingle
{
    public class StreamingleAvatarImport : MonoBehaviour
    {
        private Dictionary<string, GameObject> loadedAvatars = new Dictionary<string, GameObject>();
        private StreamingleDebugWindow debugWindow;

        [SerializeField]
        public bool createDebugUI = false;

        /// <summary>
        /// 스트리밍글 아바타 파일을 비동기적으로 로드합니다.
        /// </summary>
        /// <param name="filePath">로드할 .streamingle 파일의 전체 경로</param>
        /// <param name="parentTransform">로드된 아바타가 배치될 부모 Transform (null인 경우 월드 좌표계에 생성)</param>
        /// <returns></returns>
        public IEnumerator LoadAvatarAsync(string filePath, Transform parentTransform = null)
        {
            if (!File.Exists(filePath))
            {
                UpdateDebugText($"파일을 찾을 수 없음: {filePath}");
                UnityEngine.Debug.LogError($"파일을 찾을 수 없습니다: {filePath}");
                yield break;
            }

            string avatarKey = Path.GetFileNameWithoutExtension(filePath);
            UpdateDebugText($"아바타 로드 중: {avatarKey}");

            if (loadedAvatars.ContainsKey(avatarKey))
            {
                Destroy(loadedAvatars[avatarKey]);
                loadedAvatars.Remove(avatarKey);
            }

            AssetBundle avatarBundle = null;

            // AssetBundle 로드
            AssetBundleCreateRequest bundleRequest = null;
            try
            {
                bundleRequest = AssetBundle.LoadFromFileAsync(filePath);
            }
            catch (System.Exception e)
            {
                UpdateDebugText($"AssetBundle 로드 실패: {e.Message}");
                UnityEngine.Debug.LogError($"AssetBundle 로드 실패: {e.Message}");
                yield break;
            }

            yield return bundleRequest;

            if (bundleRequest.assetBundle == null)
            {
                UpdateDebugText("AssetBundle 로드 실패");
                UnityEngine.Debug.LogError("AssetBundle 로드 실패");
                yield break;
            }

            avatarBundle = bundleRequest.assetBundle;

            // 아바타 프리팹 로드
            AssetBundleRequest prefabRequest = null;
            try
            {
                string[] assetNames = avatarBundle.GetAllAssetNames();
                UnityEngine.Debug.Log($"번들 내 에셋 목록: {string.Join(", ", assetNames)}");
                
                // 번들 내 첫 번째 프리팹을 로드하거나, 특정 이름 패턴을 가진 프리팹을 찾아서 로드
                string prefabPath = assetNames.FirstOrDefault(name => name.EndsWith(".prefab"));
                if (string.IsNullOrEmpty(prefabPath))
                {
                    UpdateDebugText("프리팹을 찾을 수 없습니다.");
                    UnityEngine.Debug.LogError("번들 내에서 프리팹을 찾을 수 없습니다.");
                    if (avatarBundle != null)
                        avatarBundle.Unload(false);
                    yield break;
                }
                
                prefabRequest = avatarBundle.LoadAssetAsync<GameObject>(prefabPath);
                if (prefabRequest == null)
                {
                    UpdateDebugText("프리팹 로드 요청 생성 실패");
                    UnityEngine.Debug.LogError("프리팹 로드 요청을 생성할 수 없습니다.");
                    if (avatarBundle != null)
                        avatarBundle.Unload(false);
                    yield break;
                }
            }
            catch (System.Exception e)
            {
                UpdateDebugText($"프리팹 로드 실패: {e.Message}");
                UnityEngine.Debug.LogError($"프리팹 로드 실패: {e.Message}");
                if (avatarBundle != null)
                    avatarBundle.Unload(false);
                yield break;
            }

            yield return prefabRequest;

            if (prefabRequest.asset == null)
            {
                UpdateDebugText("아바타 프리팹 로드 실패");
                UnityEngine.Debug.LogError("아바타 프리팹 로드 실패");
                if (avatarBundle != null)
                    avatarBundle.Unload(false);
                yield break;
            }

            try
            {
                // 아바타 인스턴스화
                GameObject avatarPrefab = prefabRequest.asset as GameObject;
                GameObject avatar = Instantiate(avatarPrefab, parentTransform);
                avatar.name = avatarKey;
                loadedAvatars.Add(avatarKey, avatar);

                UpdateDebugText($"아바타 로드 완료: {avatarKey}");
            }
            catch (System.Exception e)
            {
                UpdateDebugText($"아바타 생성 실패: {e.Message}");
                UnityEngine.Debug.LogError($"아바타 생성 실패: {e.Message}");
            }
            finally
            {
                if (avatarBundle != null)
                    avatarBundle.Unload(false);
            }
        }

        /// <summary>
        /// 특정 아바타를 제거합니다.
        /// </summary>
        public void UnloadAvatar(string avatarKey)
        {
            if (loadedAvatars.ContainsKey(avatarKey))
            {
                Destroy(loadedAvatars[avatarKey]);
                loadedAvatars.Remove(avatarKey);
                UpdateDebugText($"아바타 언로드됨: {avatarKey}");
            }
        }

        /// <summary>
        /// 모든 아바타를 제거합니다.
        /// </summary>
        public void UnloadAllAvatars()
        {
            foreach (var avatar in loadedAvatars.Values)
            {
                if (avatar != null)
                {
                    Destroy(avatar);
                }
            }
            loadedAvatars.Clear();
            UpdateDebugText("모든 아바타가 언로드됨");
        }

        /// <summary>
        /// 특정 아바타 게임오브젝트를 반환합니다.
        /// </summary>
        public GameObject GetLoadedAvatar(string avatarKey)
        {
            return loadedAvatars.ContainsKey(avatarKey) ? loadedAvatars[avatarKey] : null;
        }

        /// <summary>
        /// 현재 로드된 모든 아바타의 목록을 반환합니다.
        /// </summary>
        public Dictionary<string, GameObject> GetLoadedAvatars()
        {
            return new Dictionary<string, GameObject>(loadedAvatars);
        }

        private void Start()
        {
            if (createDebugUI)
            {
                debugWindow = StreamingleDebugWindow.Create(this, () => OpenFileBrowser());
            }
        }

        private void OnDestroy()
        {
            if (debugWindow != null)
            {
                debugWindow.UnregisterImporter(this);
            }
            // 먼저 모든 아바타를 언로드
            foreach (var avatar in loadedAvatars.Values)
            {
                if (avatar != null)
                {
                    Destroy(avatar);
                }
            }
            loadedAvatars.Clear();
        }

        private void UpdateDebugText(string status)
        {
            if (createDebugUI && debugWindow != null)
            {
                debugWindow.UpdateDebugStatus();
            }
        }

        private void OpenFileBrowser()
        {
            #if UNITY_EDITOR
                string path = UnityEditor.EditorUtility.OpenFilePanel("아바타 로드", "", "streamingle");
                if (!string.IsNullOrEmpty(path))
                {
                    StartCoroutine(LoadAvatarAsync(path));
                }
            #else
                // 빌드된 게임에서는 StandaloneFileBrowser 등의 써드파티 에셋을 사용하거나
                // 특정 폴더에서만 로드하도록 구현해야 합니다.
                UnityEngine.Debug.LogWarning("빌드된 게임에서는 파일 브라우저가 지원되지 않습니다.");
            #endif
        }

        /// <summary>
        /// 파일 경로를 통해 아바타를 직접 로드합니다.
        /// </summary>
        public void LoadAvatarFromPath(string path)
        {
            if (!string.IsNullOrEmpty(path))
            {
                StartCoroutine(LoadAvatarAsync(path));
            }
        }
    }

    // 사용 편의성을 위한 정적 클래스
    public static class StreamingleAvatarLoader
    {
        /// <summary>
        /// 간단한 아바타 로드를 위한 정적 메서드
        /// </summary>
        public static StreamingleAvatarImport CreateLoader(bool withDebugUI = false)
        {
            GameObject loaderObject = new GameObject("StreamingleAvatarLoader");
            var loader = loaderObject.AddComponent<StreamingleAvatarImport>();
            loader.createDebugUI = withDebugUI;
            return loader;
        }

        /// <summary>
        /// 파일 브라우저를 통해 아바타를 로드합니다.
        /// </summary>
        public static void LoadAvatarWithFileBrowser(StreamingleAvatarImport loader)
        {
            #if UNITY_EDITOR
                string path = UnityEditor.EditorUtility.OpenFilePanel("아바타 로드", "", "streamingle");
                if (!string.IsNullOrEmpty(path))
                {
                    loader.LoadAvatarFromPath(path);
                }
            #else
                UnityEngine.Debug.LogWarning("빌드된 게임에서는 파일 브라우저가 지원되지 않습니다.");
            #endif
        }
    }
}
