using System.Collections.Generic;
using AssetBank.DockableWindow.UIHelper;
using AssetBank.Editor.DockableWindow;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

namespace AssetBank.DockableWindow
{
    public class ProjectExporterWindow : EditorWindow
    {
        private ProjectExporterController _controller;
        private VisualElement _rootElement;
        private VisualElement _contentContainer;
        private Dictionary<string, AssetModel> _assetTrees;
        private string _currentTab = "General"; // Default to General tab

        // Checkbox states for the General tab
        private bool _exportScenes = true;
        private bool _exportPrefabs = true;
        private bool _exportScriptableObjects = true;
        private bool _exportMetaFiles = true;
        private bool _exportSettings = true;

        [MenuItem("Tools/GUI/Project Exporter")]
        public static void ShowWindow()
        {
            var wnd = GetWindow<ProjectExporterWindow>();
            wnd.titleContent = new GUIContent("Project Exporter", EditorGUIUtility.IconContent("d_Profiler.GlobalIllumination").image);
            wnd.minSize = new Vector2(400, 300);
        }

        private void OnEnable()
        {
            _controller = new ProjectExporterController();
            _assetTrees = new Dictionary<string, AssetModel>();
            _rootElement = rootVisualElement;
            
            BuildUI();
            RefreshContent(_currentTab);
        }

        private void BuildUI()
        {
            _rootElement.Clear();

            var tabContainer = new VisualElement { style = { flexDirection = FlexDirection.Row } };
            tabContainer.Add(ProjectExporterUI.CreateTab("General")); // New General tab
            tabContainer.Add(ProjectExporterUI.CreateTab("Scenes"));
            tabContainer.Add(ProjectExporterUI.CreateTab("Prefabs"));
            tabContainer.Add(ProjectExporterUI.CreateTab("Scriptable Objects"));
            tabContainer.Add(ProjectExporterUI.CreateTab("Meta Files"));
            tabContainer.Add(ProjectExporterUI.CreateTab("Settings"));
            _rootElement.Add(tabContainer);

            var scrollView = new ScrollView(ScrollViewMode.Vertical);
            _rootElement.Add(scrollView);

            _contentContainer = ProjectExporterUI.CreateMainContainer();
            scrollView.Add(_contentContainer);

            var generateButton = ProjectExporterUI.CreateGenerateButton(_currentTab == "General");
            _rootElement.Add(generateButton);
            
            // The button's action will depend on the current tab
            generateButton.clicked += () => {
                if (_currentTab == "General")
                {
                    PerformBulkExport();
                }
                else if (_assetTrees.ContainsKey(_currentTab))
                {
                    _controller.ExportAssets(_assetTrees[_currentTab]);
                }
            };

            var tabs = tabContainer.Query<Button>().ToList();
            tabs[0].clicked += () => RefreshContent("General");
            tabs[1].clicked += () => RefreshContent("Scenes");
            tabs[2].clicked += () => RefreshContent("Prefabs");
            tabs[3].clicked += () => RefreshContent("Scriptable Objects");
            tabs[4].clicked += () => RefreshContent("Meta Files");
            tabs[5].clicked += () => RefreshContent("Settings");
        }

        private void RefreshContent(string tabName)
        {
            _currentTab = tabName;
            _contentContainer.Clear();

            if (tabName == "General")
            {
                DrawGeneralTab();
                return;
            }

            if (!_assetTrees.ContainsKey(tabName))
            {
                ProjectExporterDataHelper.LoadAssetTree(_assetTrees, _controller, tabName);
            }

            var rootModel = _assetTrees[tabName];
            if (rootModel != null)
            {
                foreach (var child in rootModel.Children)
                {
                    _contentContainer.Add(CreateAssetView(child, 0));
                }
            }
        }

        private void DrawGeneralTab()
        {
            var title = new Label("Select Export Types") { style = { unityFontStyleAndWeight = FontStyle.Bold } };
            _contentContainer.Add(title);

            var scenesToggle = ProjectExporterUI.CreateToggle("Export Scenes", _exportScenes, evt => _exportScenes = evt.newValue);
            var prefabsToggle = ProjectExporterUI.CreateToggle("Export Prefabs", _exportPrefabs, evt => _exportPrefabs = evt.newValue);
            var soToggle = ProjectExporterUI.CreateToggle("Export Scriptable Objects", _exportScriptableObjects, evt => _exportScriptableObjects = evt.newValue);
            var metaToggle = ProjectExporterUI.CreateToggle("Export Meta Files", _exportMetaFiles, evt => _exportMetaFiles = evt.newValue);
            var settingsToggle = ProjectExporterUI.CreateToggle("Export Settings", _exportSettings, evt => _exportSettings = evt.newValue);

            _contentContainer.Add(scenesToggle);
            _contentContainer.Add(prefabsToggle);
            _contentContainer.Add(soToggle);
            _contentContainer.Add(metaToggle);
            _contentContainer.Add(settingsToggle);
        }

        private void PerformBulkExport()
        {
            if (_exportScenes) ExportAllOfType("Scenes");
            if (_exportPrefabs) ExportAllOfType("Prefabs");
            if (_exportScriptableObjects) ExportAllOfType("Scriptable Objects");
            if (_exportMetaFiles) ExportAllOfType("Meta Files");
            if (_exportSettings) ExportAllOfType("Settings");
            
            EditorUtility.DisplayDialog("Bulk Export", "Bulk export process finished.", "OK");
        }

        private void ExportAllOfType(string type)
        {
            if (!_assetTrees.ContainsKey(type))
            {
                ProjectExporterDataHelper.LoadAssetTree(_assetTrees, _controller, type);
            }
            
            var rootModel = _assetTrees[type];
            if (rootModel != null)
            {
                ProjectExporterDataHelper.SetChildrenSelection(rootModel, true); // Select all assets
                _controller.ExportAssets(rootModel);
            }
        }

        private VisualElement CreateAssetView(AssetModel model, int indentLevel)
        {
            const int indentWidth = 20;

            if (model.Children.Count > 0)
            {
                var row = new VisualElement { style = { flexDirection = FlexDirection.Row, alignItems = Align.Center, marginLeft = indentLevel * indentWidth } };
                var foldout = ProjectExporterUI.CreateFoldout(model.Name);
                foldout.style.flexGrow = 1;
                var toggle = new Toggle { value = model.IsSelected, text = "" };
                
                toggle.RegisterValueChangedCallback(evt => {
                    model.IsSelected = evt.newValue;
                    ProjectExporterDataHelper.SetChildrenSelection(model, evt.newValue);
                    UpdateChildTogglesUI(foldout, evt.newValue);
                });

                row.Add(toggle);
                row.Add(foldout);

                foreach (var child in model.Children)
                {
                    foldout.Add(CreateAssetView(child, indentLevel + 1));
                }
                return row;
            }
            else
            {
                var toggle = ProjectExporterUI.CreateToggle(model.Name);
                toggle.style.marginLeft = (indentLevel + 1) * indentWidth;
                toggle.value = model.IsSelected;
                toggle.RegisterValueChangedCallback(evt => model.IsSelected = evt.newValue);
                return toggle;
            }
        }
        
        private void UpdateChildTogglesUI(VisualElement container, bool isSelected)
        {
            container.Query<Toggle>().ForEach(childToggle => {
                childToggle.SetValueWithoutNotify(isSelected);
            });
        }
    }
}
