using AssetBank.Editor.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;

namespace AssetBank.Settings
{
    /// <summary>
    /// Hosts the Component Stats UI within the Project Settings window.
    /// </summary>
    internal class ComponentStatsSettingsProvider : SettingsProvider
    {
        private ComponentStatsController _controller;
        private ComponentStatsController.ScanSource _scanSource = ComponentStatsController.ScanSource.Both;
        
        private Dictionary<string, ComponentStats> _stats = new();
        private Vector2 _scrollPosition;
        private GUIStyle _alternatingRowStyle;
        private ComponentStatsSettings _statsSettings;

        const string k_SettingsPath = "Project/Project AssetDatabase/Component Stats";

        public ComponentStatsSettingsProvider(string path, SettingsScope scope = SettingsScope.Project)
            : base(path, scope) {}

        public override void OnActivate(string searchContext, UnityEngine.UIElements.VisualElement rootElement)
        {
            _controller = new ComponentStatsController();
            _statsSettings = ComponentStatsSettings.GetOrCreateSettings();
            LoadStatsFromSettings();
            
            // Create a style for alternating row colors
            _alternatingRowStyle = new GUIStyle();
            var texture = new Texture2D(1, 1);
            var color = EditorGUIUtility.isProSkin 
                ? new Color(1f, 1f, 1f, 0.05f) 
                : new Color(0f, 0f, 0f, 0.05f);
            texture.SetPixel(0, 0, color);
            texture.Apply();
            _alternatingRowStyle.normal.background = texture;
        }

        public override void OnGUI(string searchContext)
        {
            EditorGUILayout.LabelField("Component Stats Generator", EditorStyles.boldLabel);
            
            EditorGUILayout.Space();
            
            EditorGUILayout.HelpBox("Scan project assets to find all unique component types and their statistics.", MessageType.Info);

            if (!string.IsNullOrEmpty(_statsSettings.LastScanTime))
            {
                EditorGUILayout.HelpBox($"Last Scan: {_statsSettings.LastScanTime}", MessageType.None);
            }

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

            if (GUILayout.Button("Scan Project for Components"))
            {
                var newStats = _controller.ScanProject(_scanSource);
                
                _stats = newStats;
                
                // Immediately save the new scan results and update the timestamp
                _controller.UpdateAndSaveScanResults(_stats);
            }

            EditorGUILayout.Space();
            
            DrawHeader();
            DrawComponentList();

            EditorGUILayout.Space();

            if (GUILayout.Button("Save Stats"))
            {
                _controller.SaveStats(_stats);
            }
            
            if (GUI.changed)
            {
                EditorUtility.SetDirty(_statsSettings);
                AssetDatabase.SaveAssets();
            }
        }

        private void DrawHeader()
        {
            EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
            GUILayout.Label("Component Name", GUILayout.MinWidth(150), GUILayout.ExpandWidth(true));
            GUILayout.Label("Occurrences", GUILayout.Width(80));
            GUILayout.Label("Max Props", GUILayout.Width(70));
            GUILayout.Label("Total Props", GUILayout.Width(80));
            EditorGUILayout.EndHorizontal();
        }

        private void DrawComponentList()
        {
            _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition, GUILayout.ExpandHeight(true));
            if (_stats.Count == 0)
            {
                EditorGUILayout.LabelField("No components found. Please run a scan.", EditorStyles.centeredGreyMiniLabel);
            }
            else
            {
                var sortedStats = _stats.Values.OrderBy(s => s.Name).ToList();
                int i = 0;
                foreach (var stat in sortedStats)
                {
                    var style = (i++ % 2 == 0) ? GUIStyle.none : _alternatingRowStyle;
                    EditorGUILayout.BeginHorizontal(style);
                    
                    EditorGUILayout.LabelField(stat.Name, GUILayout.MinWidth(150), GUILayout.ExpandWidth(true));
                    EditorGUILayout.LabelField(stat.TotalOccurrences.ToString(), GUILayout.Width(80));
                    EditorGUILayout.LabelField(stat.MaxProperties.ToString(), GUILayout.Width(70));
                    EditorGUILayout.LabelField(stat.TotalProperties.ToString(), GUILayout.Width(80));
                    
                    EditorGUILayout.EndHorizontal();
                }
            }
            EditorGUILayout.EndScrollView();
        }

        private void LoadStatsFromSettings()
        {
            _stats = _statsSettings.ComponentStats.ToDictionary(s => s.Name, s => s);
        }

        [SettingsProvider]
        public static SettingsProvider CreateSettingsProvider()
        {
            var provider = new ComponentStatsSettingsProvider(k_SettingsPath, SettingsScope.Project);
            return provider;
        }
    }
}

