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

namespace UVC.Twin.MonitoringUI
{
    public class ScheduleInfoController
    {
        private readonly VisualElement _root;
        private readonly Button _toggleDaily;
        private readonly Button _toggleEquipment;
        private readonly ScrollView _tableBody;
        private readonly Label _currentDateLabel;
        private readonly VisualElement _dateNav;
        private readonly VisualElement _equipmentFilter;
        private readonly DropdownField _equipmentDropdown;
        private readonly DropdownField _dateDropdown;
        private string _activeToggle = ScheduleToggleModes.Daily;
        private bool _isValid;

        public string ActiveToggle => _activeToggle;

        public event Action<string> OnToggleChanged;
        public event Action<int> OnDateOffsetChanged;
        public event Action OnInfoClicked;
        public event Action<string> OnEquipmentFilterChanged;
        public event Action<string> OnDateFilterChanged;

        public ScheduleInfoController(VisualElement root)
        {
            _root = root;
            _toggleDaily = root.Q<Button>(ElementIds.ScheduleToggleDaily);
            _toggleEquipment = root.Q<Button>(ElementIds.ScheduleToggleEquipment);
            _tableBody = root.Q<ScrollView>(ElementIds.ScheduleTableBody);
            _currentDateLabel = root.Q<Label>(ElementIds.ScheduleCurrentDate);
            _dateNav = root.Q<VisualElement>(ElementIds.ScheduleDateNav);
            _equipmentFilter = root.Q<VisualElement>(ElementIds.ScheduleEquipmentFilter);
            _equipmentDropdown = root.Q<DropdownField>(ElementIds.ScheduleEquipmentDropdown);
            _dateDropdown = root.Q<DropdownField>(ElementIds.ScheduleDateDropdown);

            if (_tableBody == null)
            {
                Debug.LogError("[MonitoringUI] ScheduleInfo: table body not found");
                return;
            }

            _isValid = true;
            BindToolbar();
        }

        private void BindToolbar()
        {
            if (_toggleDaily != null)
            {
                _toggleDaily.clicked += () =>
                {
                    SetActiveToggle(ScheduleToggleModes.Daily);
                    OnToggleChanged?.Invoke(ScheduleToggleModes.Daily);
                };
            }

            if (_toggleEquipment != null)
            {
                _toggleEquipment.clicked += () =>
                {
                    SetActiveToggle(ScheduleToggleModes.Equipment);
                    OnToggleChanged?.Invoke(ScheduleToggleModes.Equipment);
                };
            }

            BindNavButton(NavButtonNames.DatePrevFar, -7);
            BindNavButton(NavButtonNames.DatePrev, -1);
            BindNavButton(NavButtonNames.DateNext, 1);
            BindNavButton(NavButtonNames.DateNextFar, 7);

            if (_equipmentDropdown != null)
            {
                _equipmentDropdown.RegisterValueChangedCallback(evt =>
                    OnEquipmentFilterChanged?.Invoke(evt.newValue));
            }

            if (_dateDropdown != null)
            {
                _dateDropdown.RegisterValueChangedCallback(evt =>
                    OnDateFilterChanged?.Invoke(evt.newValue));
            }

            var infoBtn = _root.Q<Button>(className: CssClasses.PanelInfoButton);
            if (infoBtn != null)
                infoBtn.clicked += () => OnInfoClicked?.Invoke();
        }

        private void BindNavButton(string name, int offset)
        {
            var btn = _root.Q<Button>(name);
            if (btn != null)
                btn.clicked += () => OnDateOffsetChanged?.Invoke(offset);
        }

        private void SetActiveToggle(string mode)
        {
            _activeToggle = mode;

            _toggleDaily?.RemoveFromClassList(CssClasses.ScheduleToggleBtnActive);
            _toggleEquipment?.RemoveFromClassList(CssClasses.ScheduleToggleBtnActive);

            if (mode == ScheduleToggleModes.Daily)
            {
                _toggleDaily?.AddToClassList(CssClasses.ScheduleToggleBtnActive);
                if (_dateNav != null) _dateNav.style.display = DisplayStyle.Flex;
                if (_equipmentFilter != null) _equipmentFilter.style.display = DisplayStyle.None;
            }
            else
            {
                _toggleEquipment?.AddToClassList(CssClasses.ScheduleToggleBtnActive);
                if (_dateNav != null) _dateNav.style.display = DisplayStyle.None;
                if (_equipmentFilter != null) _equipmentFilter.style.display = DisplayStyle.Flex;
            }
        }

        public void SetScheduleRows(IReadOnlyList<ScheduleRowData> rows)
        {
            if (!_isValid) return;

            _tableBody.Clear();

            foreach (var row in rows)
            {
                var rowElement = BuildTableRow(row);
                _tableBody.Add(rowElement);
            }
        }

        public void SetCurrentDate(string dateText)
        {
            if (_currentDateLabel != null)
                _currentDateLabel.text = dateText;
        }

        public void SetEquipmentChoices(List<string> equipmentNames, string defaultValue = null)
        {
            if (_equipmentDropdown == null) return;
            _equipmentDropdown.choices = equipmentNames;
            if (defaultValue != null && equipmentNames.Contains(defaultValue))
                _equipmentDropdown.SetValueWithoutNotify(defaultValue);
            else if (equipmentNames.Count > 0)
                _equipmentDropdown.SetValueWithoutNotify(equipmentNames[0]);
        }

        public void SetDateChoices(List<string> dates, string defaultValue = null)
        {
            if (_dateDropdown == null) return;
            _dateDropdown.choices = dates;
            if (defaultValue != null && dates.Contains(defaultValue))
                _dateDropdown.SetValueWithoutNotify(defaultValue);
            else if (dates.Count > 0)
                _dateDropdown.SetValueWithoutNotify(dates[0]);
        }

        public void SelectEquipment(string name)
        {
            if (_equipmentDropdown == null) return;
            if (_equipmentDropdown.choices.Contains(name))
                _equipmentDropdown.SetValueWithoutNotify(name);
        }

        public void SelectDate(string date)
        {
            if (_dateDropdown == null) return;
            if (!_dateDropdown.choices.Contains(date))
            {
                var choices = new List<string>(_dateDropdown.choices) { date };
                _dateDropdown.choices = choices;
            }
            _dateDropdown.SetValueWithoutNotify(date);
        }

        private VisualElement BuildTableRow(ScheduleRowData data)
        {
            var row = new VisualElement();
            row.AddToClassList(CssClasses.ScheduleTableRow);

            AddCell(row, data.WorkOrder);
            AddCell(row, data.StartDate);
            AddCell(row, data.EndDate);
            AddCell(row, data.Series);
            AddCell(row, data.CuttingLength);
            AddCell(row, data.Equipment);

            return row;
        }

        private void AddCell(VisualElement row, string text)
        {
            var cell = new Label { text = text };
            cell.AddToClassList(CssClasses.ScheduleTableCell);
            row.Add(cell);
        }
    }
}
