using XGame.Editor.Asset;
using XGame.Framework.Asset;
using XGame.Framework.Asset.Addressable;
using XGame.Framework.Asset.Addressable.Data;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using XGame.Framework.Json;

namespace XGame.Editor.Build.AssetBundles
{
    internal class DeserializeABManifestWindow : EditorWindow
    {
        internal static void CreateWindow()
        {
            var window = EditorWindow.GetWindow<DeserializeABManifestWindow>(true, "DeserializeABManifest");
            window.Show();
        }

        private string _manifestName;
        private string _manifestFilePath;
        private string _outpuPath;
        private string _tempPath;
        private bool _isToJson;

        private void OnEnable()
        {
            _manifestName = $"{Define.MANIFEST_BUNDLE_NAME}.{Define.BUNDLE_VARIANT}";
            _manifestFilePath = $"{PathDefine.AssetBundleOutputPath}/{_manifestName}";
            _outpuPath = PathDefine.DefaultOutputPath;
            _tempPath = "Assets/TempManifest";
            _isToJson = true;
        }
        private void OnDisable()
        {

        }
        private void OnGUI()
        {
            _isToJson = EditorGUILayout.Toggle("导出为Json格式", _isToJson);
            EditorGUILayout.LabelField($"Manifest文件路径: {_manifestFilePath}");
            if (GUILayout.Button("选择Manifest"))
            {
                SelectManifestFile();
            }
            EditorGUILayout.LabelField($"导出路径: {_outpuPath}");
            if (GUILayout.Button("选择导出目录"))
            {
                SelectOutputPath();
            }
            if (GUILayout.Button("开始反序列化"))
            {
                Deserialize();
            }
        }
        private void SelectManifestFile()
        {
            var filePath = EditorUtility.OpenFilePanel($"选择Menifest文件，文件名:{_manifestName}", _manifestFilePath, Define.BUNDLE_VARIANT);
            if (!string.IsNullOrEmpty(filePath) && filePath.EndsWith(_manifestName))
            {
                _manifestFilePath = filePath;
            }
        }
        private void SelectOutputPath()
        {
            var output = EditorUtility.OpenFolderPanel("选择导出文件夹", _outpuPath, "manifest");
            if (!string.IsNullOrEmpty(output))
            {
                _outpuPath = output;
            }
        }
        private void Deserialize()
        {
            var bundle = AssetBundle.LoadFromFile(_manifestFilePath, 0, Define.MANIFEST_BUNDLE_OFFSET);
            if (bundle == null)
            {
                //先按加密读取，读不到再使用无加密方式读取
                bundle = AssetBundle.LoadFromFile(_manifestFilePath);
            }
            if (bundle == null)
            {
                BuildLog.Error($"读取Assetbundle失败，请确认bundle是否正确。ManifestPath:{_manifestFilePath}");
            }
            else
            {
                if (!System.IO.Directory.Exists(_tempPath))
                {
                    System.IO.Directory.CreateDirectory(_tempPath);
                }

                CreateAsset<AssetBundleInfosSo, AssetBundleInfo>(bundle, Define.ASSET_BUNDLE_MANIFEST, "bundleInfos");
                CreateAsset<SceneInfosSo, SceneAssetInfo>(bundle, Define.SCENE_BUNDLE_MANIFEST, "sceneInfos");
                CreateAsset<AssetReferenceInfosSo, AssetReferenceInfo>(bundle, Define.ASSET_REFERENCE_MANIFEST, "references");
                CreateAsset<AddressableInfosSo, AssetInfo>(bundle, Define.BUILTIN_ASSET_MANIFEST, "assetInfos");
                CreateAsset<AddressableInfosSo, AssetInfo>(bundle, Define.PRODUCT_ASSET_MANIFEST, "assetInfos");
                bundle.Unload(true);
                Resources.UnloadUnusedAssets();

                UnityEditor.FileUtil.DeleteFileOrDirectory(_tempPath);
                AssetDatabase.Refresh();
                BuildLog.Log("Manifest反序列化结束. ");
            }
        }
        private void CreateAsset<TManifest, TfileType>(AssetBundle bundle, string assetName, string fieldName) where TManifest : ScriptableObject
        {
            var manifest = bundle.LoadAsset<TManifest>(assetName);
            if (manifest == null)
            {
                BuildLog.Log($"没有该类型文件. Type:{typeof(TManifest)} Name:{assetName}");
                return;
            }
            var fieldInfo = manifest.GetType().GetField(fieldName, BindingFlags.Public | BindingFlags.Instance);
            var fieldValue = fieldInfo.GetValue(manifest);

            var instance = ScriptableObject.CreateInstance<TManifest>();
            fieldInfo.SetValue(instance, fieldValue);

            var outputFile = $"{_outpuPath}/{assetName}.asset";
            if (System.IO.File.Exists(outputFile))
            {
                UnityEditor.FileUtil.DeleteFileOrDirectory(outputFile);
            }
            if (_isToJson)
            {
                var json = XJson.ToJson(instance);
                System.IO.File.WriteAllText(outputFile, json);
            }
            else
            {
                var _tempFile = $"{_tempPath}/{assetName}.asset";
                AssetDatabase.CreateAsset(instance, _tempFile);

                UnityEditor.FileUtil.MoveFileOrDirectory(_tempFile, $"{_outpuPath}/{assetName}.asset");
            }
            
        }
    }
}
