using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UIElements;

namespace UVC.Twin.MonitoringUI
{
    [RequireComponent(typeof(UIDocument))]
    public class MonitoringUIController : MonoBehaviour
    {
        [SerializeField] private MonitoringUIConfig _config;

        private UIDocument _uiDocument;
        private VisualElement _rootElement;

        private TopNavBarController _topNavBar;
        private LeftSidebarController _leftSidebar;
        private CuttingOverviewPanelController _cuttingOverviewPanel;

        private List<SideMenuItem> _menuItems;
        private Dictionary<string, List<EquipmentCardData>> _bayEquipmentMap = new();
        private int _currentMenuIndex = -1;
        private bool _isInProcessCardsView = true;

        public MonitoringUIEvents Events { get; } = new MonitoringUIEvents();

        private void OnEnable()
        {
            _uiDocument = GetComponent<UIDocument>();
            _rootElement = _uiDocument.rootVisualElement;

            if (!InitializeControllers())
            {
                Debug.LogError("[MonitoringUI] Initialization failed, controller disabled");
                return;
            }

            WireEvents();
            LoadConfig();
            Debug.Log("[MonitoringUI] Initialized successfully");
        }

        private void OnDisable()
        {
            _topNavBar = null;
            _leftSidebar = null;
            _cuttingOverviewPanel = null;
            _menuItems = null;
            _currentMenuIndex = -1;
            _bayEquipmentMap.Clear();
        }

        private bool InitializeControllers()
        {
            var topNavRoot = _rootElement.Q<VisualElement>(ElementIds.TopNavBar);
            if (topNavRoot == null)
            {
                Debug.LogError($"[MonitoringUI] Required element '{ElementIds.TopNavBar}' not found");
                return false;
            }
            _topNavBar = new TopNavBarController(topNavRoot);

            var sidebarRoot = _rootElement.Q<VisualElement>(ElementIds.LeftSidebar);
            if (sidebarRoot == null)
            {
                Debug.LogError($"[MonitoringUI] Required element '{ElementIds.LeftSidebar}' not found");
                return false;
            }
            _leftSidebar = new LeftSidebarController(sidebarRoot);

            var panelContainer = _rootElement.Q<VisualElement>(ElementIds.MainContentPanelContainer);
            if (panelContainer != null)
            {
                _cuttingOverviewPanel = new CuttingOverviewPanelController(panelContainer);

                _cuttingOverviewPanel.OnProcessCardClicked += tabName =>
                {
                    Debug.Log($"[MonitoringUI] Process card clicked: {tabName}");
                    DrillIntoBay(tabName);
                    Events.RaiseProcessCardSelected(tabName);
                    Events.RaiseBayViewChange(tabName);
                };

                _cuttingOverviewPanel.OnEquipmentCardClicked += cardId =>
                {
                    Debug.Log($"[MonitoringUI] Equipment card clicked: {cardId}");
                    Events.RaiseEquipmentCardSelected(cardId);
                };

                if (_cuttingOverviewPanel.ScheduleInfo != null)
                {
                    _cuttingOverviewPanel.ScheduleInfo.OnToggleChanged += mode =>
                    {
                        Debug.Log($"[MonitoringUI] Schedule toggle: {mode}");
                        Events.RaiseScheduleToggleChanged(mode);
                    };
                    _cuttingOverviewPanel.ScheduleInfo.OnDateOffsetChanged += offset =>
                    {
                        Debug.Log($"[MonitoringUI] Schedule date nav: {offset}");
                        Events.RaiseScheduleDateNavigated(offset);
                    };
                    _cuttingOverviewPanel.ScheduleInfo.OnEquipmentFilterChanged += name =>
                    {
                        Debug.Log($"[MonitoringUI] Schedule equipment filter: {name}");
                        Events.RaiseScheduleEquipmentFilterChanged(name);
                    };
                    _cuttingOverviewPanel.ScheduleInfo.OnDateFilterChanged += date =>
                    {
                        Debug.Log($"[MonitoringUI] Schedule date filter: {date}");
                        Events.RaiseScheduleDateFilterChanged(date);
                    };
                }
            }
            else
            {
                Debug.LogWarning("[MonitoringUI] MainContent panel container not found, content panels disabled");
            }

            return true;
        }

        private void WireEvents()
        {
            _topNavBar.OnBayTabSelected += tabName =>
            {
                Debug.Log($"[MonitoringUI] Bay tab selected: {tabName}");
                DrillIntoBay(tabName);
                Events.RaiseBayViewChange(tabName);
            };

            _topNavBar.OnActiveTabReselected += tabName =>
            {
                Debug.Log($"[MonitoringUI] Active tab re-selected: {tabName}");

                if (!_isInProcessCardsView)
                {
                    var currentItem = GetCurrentMenuItem();
                    if (currentItem != null)
                        BuildAndShowProcessCards(currentItem.NavigationTabs);
                }
            };

            _topNavBar.OnSettingsClicked += () =>
            {
                Debug.Log("[MonitoringUI] Settings clicked");
                Events.RaiseSettingsRequest();
            };
            _topNavBar.OnVisibilityClicked += () =>
            {
                Debug.Log("[MonitoringUI] Visibility clicked");
                Events.RaiseVisibilityToggle("default");
            };
            _topNavBar.OnUserClicked += () =>
            {
                Debug.Log("[MonitoringUI] User clicked");
                Events.RaiseUserProfileRequest();
            };
            _topNavBar.OnExportClicked += () =>
            {
                Debug.Log("[MonitoringUI] Export clicked");
                Events.RaiseExportRequest();
            };

            _leftSidebar.OnMenuItemSelected += OnMenuItemSelected;

            _leftSidebar.OnSidebarToggled += expanded =>
            {
                Debug.Log($"[MonitoringUI] Sidebar toggled: {(expanded ? "expanded" : "collapsed")}");
            };

        }

        private void LoadConfig()
        {
            if (_config == null)
            {
                Debug.LogWarning("[MonitoringUI] No config assigned, using defaults");
                SetupDefaultData();
                return;
            }

            _menuItems = _config.SideMenuItems;

            _leftSidebar.SetMenuItems(_menuItems);

            SetupDefaultOverviewData();

            if (_menuItems.Count > 0)
            {
                _leftSidebar.SetActiveButton(0);
                ApplyMenuItem(0);
            }
        }

        private void OnMenuItemSelected(int index)
        {
            if (_menuItems == null || index < 0 || index >= _menuItems.Count) return;

            _currentMenuIndex = index;
            var item = _menuItems[index];
            Debug.Log($"[MonitoringUI] Menu item selected: {item.DisplayName}");
            Events.RaiseInfoPanelRequest(item.DisplayName);
            ApplyMenuItem(index);
        }

        private void ApplyMenuItem(int index)
        {
            if (_menuItems == null || index < 0 || index >= _menuItems.Count) return;

            _currentMenuIndex = index;
            var item = _menuItems[index];
            _topNavBar.SetTabs(item.NavigationTabs, item.DefaultTabIndex);
            ApplyViewState(item.ViewState);
            BuildAndShowProcessCards(item.NavigationTabs);
        }

        private void ApplyViewState(UIViewState viewState)
        {
            switch (viewState)
            {
                case UIViewState.CuttingOverview:
                    _cuttingOverviewPanel?.Show();
                    break;
                default:
                    _cuttingOverviewPanel?.Hide();
                    break;
            }
        }

        private void BuildAndShowProcessCards(IReadOnlyList<string> tabNames)
        {
            if (_cuttingOverviewPanel == null) return;

            var processCards = new List<(string TabName, EquipmentCardData Data)>();

            foreach (var tabName in tabNames)
            {
                if (_bayEquipmentMap.TryGetValue(tabName, out var cards))
                {
                    var summaryCard = cards.FirstOrDefault(c => c.IsSummaryCard);
                    if (summaryCard != null)
                        processCards.Add((tabName, summaryCard));
                }
            }

            _cuttingOverviewPanel.SetProcessCards(processCards);
            _cuttingOverviewPanel.ShowProcessCardsView();
            _isInProcessCardsView = true;
        }

        private void DrillIntoBay(string tabName)
        {
            _topNavBar.SetActiveTabVisual(tabName);
            ApplyBayEquipmentCards(tabName);
            _cuttingOverviewPanel?.ShowEquipmentDetailView();
            _isInProcessCardsView = false;
        }

        private SideMenuItem GetCurrentMenuItem()
        {
            if (_menuItems != null && _currentMenuIndex >= 0 && _currentMenuIndex < _menuItems.Count)
                return _menuItems[_currentMenuIndex];
            return null;
        }

        private void ApplyBayEquipmentCards(string tabName)
        {
            if (!_bayEquipmentMap.TryGetValue(tabName, out var cards)) return;
            _cuttingOverviewPanel?.SetEquipmentCards(cards);
        }

        private void SetupDefaultData()
        {
            _menuItems = MonitoringUIDefaultData.BuildSideMenuItems();

            _leftSidebar.SetMenuItems(_menuItems);
            _leftSidebar.SetActiveButton(0);

            SetupDefaultOverviewData();

            if (_menuItems.Count > 0)
                ApplyMenuItem(0);
        }

        public void SetBayTabs(List<string> tabNames, int activeTabIndex = -1)
        {
            _topNavBar.SetTabs(tabNames, activeTabIndex);
        }

        public void SetBayEquipmentCards(string tabName, List<EquipmentCardData> cards)
        {
            _bayEquipmentMap[tabName] = cards;
            RefreshEquipmentChoicesFromAllBays();

            if (_isInProcessCardsView)
            {
                var currentItem = GetCurrentMenuItem();
                if (currentItem != null)
                    BuildAndShowProcessCards(currentItem.NavigationTabs);
            }
        }

        public void SetSideMenuItems(List<SideMenuItem> items)
        {
            _menuItems = items;
            _leftSidebar.SetMenuItems(items);
        }

        private void SetupDefaultOverviewData()
        {
            if (_cuttingOverviewPanel == null) return;

            _bayEquipmentMap = MonitoringUIDefaultData.BuildBayEquipmentMap();

            _cuttingOverviewPanel.SetScheduleRows(MonitoringUIDefaultData.BuildScheduleRows());
            _cuttingOverviewPanel.SetCurrentDate(MonitoringUIDefaultData.DefaultCurrentDate);

            RefreshEquipmentChoicesFromAllBays();
            _cuttingOverviewPanel.ScheduleInfo?.SetDateChoices(
                MonitoringUIDefaultData.BuildDefaultDateChoices(),
                MonitoringUIDefaultData.DefaultCurrentDate);
        }

        public void SetScheduleData(List<ScheduleRowData> rows)
        {
            _cuttingOverviewPanel?.SetScheduleRows(rows);
        }

        public void SetScheduleEquipmentChoices(List<string> names, string defaultValue = null)
        {
            _cuttingOverviewPanel?.ScheduleInfo?.SetEquipmentChoices(names, defaultValue);
        }

        public void SetScheduleDateChoices(List<string> dates, string defaultValue = null)
        {
            _cuttingOverviewPanel?.ScheduleInfo?.SetDateChoices(dates, defaultValue);
        }

        private void RefreshEquipmentChoicesFromAllBays()
        {
            if (_cuttingOverviewPanel == null) return;

            var equipmentNames = new HashSet<string>();
            foreach (var cards in _bayEquipmentMap.Values)
            {
                foreach (var card in cards)
                {
                    if (!card.IsSummaryCard)
                        equipmentNames.Add(card.Title);
                }
            }

            var sorted = equipmentNames.OrderBy(n => n).ToList();
            _cuttingOverviewPanel.ScheduleInfo?.SetEquipmentChoices(sorted);
        }

        public void ExpandSidebar() => _leftSidebar.Expand();

        public void CollapseSidebar() => _leftSidebar.Collapse();
    }
}
