using AssetBank.Settings;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;

namespace AssetBank.Editor.Tools
{
    /// <summary>
    /// Provides the user interface for managing the component whitelist.
    /// Delegates all heavy lifting to the ComponentWhitelistController.
    /// </summary>
    public class ComponentWhitelisterWindow : EditorWindow
    {
        private ComponentWhitelistController _controller;
        private ComponentWhitelistController.ScanSource _scanSource = ComponentWhitelistController.ScanSource.Both;
        
        private List<string> _componentTypes = new();
        private Dictionary<string, bool> _componentSelection = new();
        private Vector2 _scrollPosition;

        [MenuItem("Tools/GUI/Component Whitelister")]
        public static void ShowWindow()
        {
            GetWindow<ComponentWhitelisterWindow>("Component Whitelister");
        }

        private void OnEnable()
        {
            _controller = new ComponentWhitelistController();
            LoadInitialSelection();
        }

        private void OnGUI()
        {
            EditorGUILayout.LabelField("Component Whitelist Generator", EditorStyles.boldLabel);
            EditorGUILayout.HelpBox("Scan project assets to find all unique component types. Select the components you want to include in the export.", MessageType.Info);

            _scanSource = (ComponentWhitelistController.ScanSource)EditorGUILayout.EnumPopup("Asset Source to Scan", _scanSource);

            if (GUILayout.Button("Scan Project for Components"))
            {
                // Check if this is a fresh scan (no components loaded yet)
                bool isFreshScan = _componentTypes.Count == 0;

                // Delegate scanning to the controller
                var foundComponents = _controller.ScanProject(_scanSource);
                
                // Update UI state with the results
                _componentTypes = foundComponents.ToList();
                _componentTypes.Sort();
                
                if (isFreshScan)
                {
                    // On a fresh scan, select all found components by default
                    _componentSelection.Clear();
                    foreach (var type in _componentTypes)
                    {
                        _componentSelection[type] = true;
                    }
                }
                else
                {
                    // On subsequent scans, preserve existing selections
                    var currentSelection = new HashSet<string>(_componentSelection.Where(kvp => kvp.Value).Select(kvp => kvp.Key));
                    _componentSelection.Clear();
                    foreach (var type in _componentTypes)
                    {
                        _componentSelection[type] = currentSelection.Contains(type);
                    }
                }
                
                Repaint();
            }

            EditorGUILayout.Space();
            EditorGUILayout.LabelField("Found Component Types:", EditorStyles.boldLabel);

            // Scrollable area for the component list
            _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, GUILayout.ExpandHeight(true));
            if (_componentTypes.Count == 0)
            {
                EditorGUILayout.LabelField("No components found. Please run a scan or load existing settings.", EditorStyles.centeredGreyMiniLabel);
            }
            else
            {
                // Create a copy of keys to prevent modification during iteration issues
                var keys = _componentTypes.ToList();
                foreach (var component in keys)
                {
                    if (_componentSelection.ContainsKey(component))
                    {
                        _componentSelection[component] = EditorGUILayout.ToggleLeft(component, _componentSelection[component]);
                    }
                }
            }
            EditorGUILayout.EndScrollView();

            EditorGUILayout.Space();

            if (GUILayout.Button("Save Whitelist"))
            {
                // Delegate saving to the controller
                _controller.SaveWhitelist(_componentSelection);
            }
        }

        /// <summary>
        /// Loads the saved whitelist from the settings asset when the window is opened.
        /// </summary>
        private void LoadInitialSelection()
        {
            var settings = ComponentWhitelistSettings.GetOrCreateSettings();
            _componentTypes = settings.WhitelistedComponents.ToList();
            _componentTypes.Sort();

            _componentSelection.Clear();
            foreach (var type in _componentTypes)
            {
                _componentSelection[type] = true; // All saved components are, by definition, selected
            }
        }
    }
}
