using MainShell.Resources.CustomControl;
using MaxwellFramework.Core.Events;
using Stylet;
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Media;

namespace MainShell.Common
{
    public class HeaderDeviceStatusController : PropertyChangedBase, IHandle<MainViewSelectedPageChangeEvent>
    {
        private enum HeaderDeviceStatusTone
        {
            Auto,
            Manual,
            Maintenance,
            Recipe,
            Settings,
            Calibration,
            Unknown
        }

        private readonly IEventAggregator _eventAggregator;
        private bool _hasLoadingStarted;
        private bool _isVisible;
        private string _labelText = string.Empty;
        private string _statusText = string.Empty;
        private Brush _badgeBackgroundBrush;
        private Brush _badgeBorderBrush;
        private Brush _labelForegroundBrush;
        private Brush _statusForegroundBrush;
        private Brush _indicatorBrush;

        public HeaderDeviceStatusController(IEventAggregator eventAggregator)
        {
            _eventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator));

            _eventAggregator.Subscribe(this);
            LoadingService.Instance.PropertyChanged += OnLoadingServicePropertyChanged;
            UpdateStatusText("Home");
            IsVisible = false;
        }

        public bool IsVisible
        {
            get
            {
                return _isVisible;
            }
            private set
            {
                SetAndNotify(ref _isVisible, value);
            }
        }

        public string LabelText
        {
            get
            {
                return _labelText;
            }
            private set
            {
                SetAndNotify(ref _labelText, value);
            }
        }

        public string StatusText
        {
            get
            {
                return _statusText;
            }
            private set
            {
                SetAndNotify(ref _statusText, value);
            }
        }

        public Brush BadgeBackgroundBrush
        {
            get
            {
                return _badgeBackgroundBrush;
            }
            private set
            {
                SetAndNotify(ref _badgeBackgroundBrush, value);
            }
        }

        public Brush BadgeBorderBrush
        {
            get
            {
                return _badgeBorderBrush;
            }
            private set
            {
                SetAndNotify(ref _badgeBorderBrush, value);
            }
        }

        public Brush LabelForegroundBrush
        {
            get
            {
                return _labelForegroundBrush;
            }
            private set
            {
                SetAndNotify(ref _labelForegroundBrush, value);
            }
        }

        public Brush StatusForegroundBrush
        {
            get
            {
                return _statusForegroundBrush;
            }
            private set
            {
                SetAndNotify(ref _statusForegroundBrush, value);
            }
        }

        public Brush IndicatorBrush
        {
            get
            {
                return _indicatorBrush;
            }
            private set
            {
                SetAndNotify(ref _indicatorBrush, value);
            }
        }

        public void Handle(MainViewSelectedPageChangeEvent message)
        {
            if (message == null)
            {
                return;
            }

            UpdateStatusText(message.SelectePageName);
            if (!LoadingService.Instance.IsBusy)
            {
                IsVisible = true;
            }
        }

        private void OnLoadingServicePropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (!string.Equals(e.PropertyName, nameof(LoadingService.IsBusy), StringComparison.Ordinal))
            {
                return;
            }

            if (LoadingService.Instance.IsBusy)
            {
                _hasLoadingStarted = true;
                IsVisible = false;
                return;
            }

            if (_hasLoadingStarted)
            {
                IsVisible = true;
            }
        }

        private void UpdateStatusText(string pageName)
        {
            string resourceKey;
            HeaderDeviceStatusTone tone;

            ResolveStatusDefinition(pageName, out resourceKey, out tone);

            LabelText = GetResourceText("HeaderDeviceStatusLabel", "当前状态:");
            StatusText = GetResourceText(resourceKey, GetFallbackStatusText(tone));
            ApplyTone(tone);
        }

        private static void ResolveStatusDefinition(string pageName, out string resourceKey, out HeaderDeviceStatusTone tone)
        {
            if (string.Equals(pageName, "Home", StringComparison.OrdinalIgnoreCase))
            {
                resourceKey = "HeaderDeviceModeAuto";
                tone = HeaderDeviceStatusTone.Auto;
                return;
            }

            if (string.Equals(pageName, "ManualOperate", StringComparison.OrdinalIgnoreCase))
            {
                resourceKey = "HeaderDeviceModeManual";
                tone = HeaderDeviceStatusTone.Manual;
                return;
            }

            if (string.Equals(pageName, "MenuDeviceMaint", StringComparison.OrdinalIgnoreCase))
            {
                resourceKey = "HeaderDeviceModeMaintenance";
                tone = HeaderDeviceStatusTone.Maintenance;
                return;
            }

            if (string.Equals(pageName, "Recipe", StringComparison.OrdinalIgnoreCase))
            {
                resourceKey = "HeaderDeviceModeRecipe";
                tone = HeaderDeviceStatusTone.Recipe;
                return;
            }

            if (string.Equals(pageName, "PageSettings", StringComparison.OrdinalIgnoreCase))
            {
                resourceKey = "HeaderDeviceModeSettings";
                tone = HeaderDeviceStatusTone.Settings;
                return;
            }

            if (string.Equals(pageName, "PageCalib", StringComparison.OrdinalIgnoreCase))
            {
                resourceKey = "HeaderDeviceModeCalibration";
                tone = HeaderDeviceStatusTone.Calibration;
                return;
            }

            resourceKey = "HeaderDeviceModeUnknown";
            tone = HeaderDeviceStatusTone.Unknown;
        }

        private static string GetFallbackStatusText(HeaderDeviceStatusTone tone)
        {
            switch (tone)
            {
                case HeaderDeviceStatusTone.Auto:
                    return "自动运行 (AUTO)";

                case HeaderDeviceStatusTone.Manual:
                    return "手动调试 (MANUAL)";

                case HeaderDeviceStatusTone.Maintenance:
                    return "设备维护 (MAINT)";

                case HeaderDeviceStatusTone.Recipe:
                    return "配方编辑 (RECIPE)";

                case HeaderDeviceStatusTone.Settings:
                    return "参数设置 (SETUP)";

                case HeaderDeviceStatusTone.Calibration:
                    return "标定校准 (CALIB)";

                default:
                    return "状态待定 (PENDING)";
            }
        }

        private void ApplyTone(HeaderDeviceStatusTone tone)
        {
            BadgeBackgroundBrush = CreateBackgroundBrush(tone);
            BadgeBorderBrush = CreateBorderBrush(tone);
            LabelForegroundBrush = CreateSolidBrush(198, 221, 255);
            StatusForegroundBrush = Brushes.White;
            IndicatorBrush = CreateIndicatorBrush(tone);
        }

        private static Brush CreateBackgroundBrush(HeaderDeviceStatusTone tone)
        {
            switch (tone)
            {
                case HeaderDeviceStatusTone.Auto:
                    return CreateGradientBrush(Color.FromRgb(42, 111, 84), Color.FromRgb(24, 79, 60));

                case HeaderDeviceStatusTone.Manual:
                    return CreateGradientBrush(Color.FromRgb(148, 103, 37), Color.FromRgb(104, 72, 24));

                case HeaderDeviceStatusTone.Maintenance:
                    return CreateGradientBrush(Color.FromRgb(46, 104, 164), Color.FromRgb(31, 74, 125));

                case HeaderDeviceStatusTone.Recipe:
                    return CreateGradientBrush(Color.FromRgb(95, 76, 153), Color.FromRgb(68, 54, 111));

                case HeaderDeviceStatusTone.Settings:
                    return CreateGradientBrush(Color.FromRgb(88, 103, 124), Color.FromRgb(62, 74, 92));

                case HeaderDeviceStatusTone.Calibration:
                    return CreateGradientBrush(Color.FromRgb(34, 124, 141), Color.FromRgb(23, 90, 102));

                default:
                    return CreateGradientBrush(Color.FromRgb(50, 102, 177), Color.FromRgb(35, 78, 140));
            }
        }

        private static Brush CreateBorderBrush(HeaderDeviceStatusTone tone)
        {
            switch (tone)
            {
                case HeaderDeviceStatusTone.Auto:
                    return CreateSolidBrush(94, 169, 128);

                case HeaderDeviceStatusTone.Manual:
                    return CreateSolidBrush(201, 151, 76);

                case HeaderDeviceStatusTone.Maintenance:
                    return CreateSolidBrush(94, 148, 206);

                case HeaderDeviceStatusTone.Recipe:
                    return CreateSolidBrush(130, 112, 192);

                case HeaderDeviceStatusTone.Settings:
                    return CreateSolidBrush(126, 143, 166);

                case HeaderDeviceStatusTone.Calibration:
                    return CreateSolidBrush(79, 170, 187);

                default:
                    return CreateSolidBrush(96, 145, 214);
            }
        }

        private static Brush CreateIndicatorBrush(HeaderDeviceStatusTone tone)
        {
            switch (tone)
            {
                case HeaderDeviceStatusTone.Auto:
                    return CreateSolidBrush(63, 227, 123);

                case HeaderDeviceStatusTone.Manual:
                    return CreateSolidBrush(255, 183, 66);

                case HeaderDeviceStatusTone.Maintenance:
                    return CreateSolidBrush(72, 196, 255);

                case HeaderDeviceStatusTone.Recipe:
                    return CreateSolidBrush(173, 121, 255);

                case HeaderDeviceStatusTone.Settings:
                    return CreateSolidBrush(158, 172, 196);

                case HeaderDeviceStatusTone.Calibration:
                    return CreateSolidBrush(70, 231, 219);

                default:
                    return CreateSolidBrush(255, 93, 93);
            }
        }

        private static Brush CreateSolidBrush(byte red, byte green, byte blue)
        {
            return new SolidColorBrush(Color.FromRgb(red, green, blue));
        }

        private static Brush CreateGradientBrush(Color startColor, Color endColor)
        {
            return new LinearGradientBrush(startColor, endColor, 0.0);
        }

        private static string GetResourceText(string resourceKey, string fallback)
        {
            Application application = Application.Current;
            if (application == null)
            {
                return fallback;
            }

            object resource = application.TryFindResource(resourceKey);
            string text = resource as string;
            if (!string.IsNullOrWhiteSpace(text))
            {
                return text;
            }

            return fallback;
        }
    }
}