using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using NavisworksTransport.Core.Models;

namespace NavisworksTransport.UI.WPF.Controls
{
    /// <summary>
    /// 事件时间线可视化控件
    /// </summary>
    public partial class EventTimelineControl : UserControl
    {
        // 固定参数
        private const double PADDING = 50;           // 左右边距
        private const double NODE_Y = 40;            // 节点Y坐标（基线位置）
        private const double MIN_NODE_SPACING = 100; // 最小节点间距
        private const double MIN_CANVAS_WIDTH = 600; // 最小画布宽度

        public EventTimelineControl()
        {
            InitializeComponent();
            Loaded += OnLoaded;
            SizeChanged += OnSizeChanged;
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            AttachCollectionChanged();
            DrawTimeline();
        }

        private void OnSizeChanged(object sender, SizeChangedEventArgs e)
        {
            DrawTimeline();
        }

        #region 依赖属性

        public static readonly DependencyProperty EventsProperty =
            DependencyProperty.Register(nameof(Events), typeof(IEnumerable<TimeTagEvent>), 
                typeof(EventTimelineControl), 
                new PropertyMetadata(null, OnEventsChanged));

        public IEnumerable<TimeTagEvent> Events
        {
            get => (IEnumerable<TimeTagEvent>)GetValue(EventsProperty);
            set => SetValue(EventsProperty, value);
        }

        private static void OnEventsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var control = (EventTimelineControl)d;
            control.DetachCollectionChanged(e.OldValue as INotifyCollectionChanged);
            control.AttachCollectionChanged();
            control.DrawTimeline();
        }

        /// <summary>
        /// 附加集合变更监听
        /// </summary>
        private void AttachCollectionChanged()
        {
            if (Events is INotifyCollectionChanged notifyCollection)
            {
                notifyCollection.CollectionChanged += OnCollectionChanged;
            }
        }

        /// <summary>
        /// 移除集合变更监听
        /// </summary>
        private void DetachCollectionChanged(INotifyCollectionChanged oldCollection)
        {
            if (oldCollection != null)
            {
                oldCollection.CollectionChanged -= OnCollectionChanged;
            }
        }

        /// <summary>
        /// 集合内容变化时重绘
        /// </summary>
        private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            // 使用 Dispatcher 确保在 UI 线程执行
            Dispatcher.BeginInvoke(new Action(DrawTimeline));
        }

        public static readonly DependencyProperty TotalDistanceProperty =
            DependencyProperty.Register(nameof(TotalDistance), typeof(double), 
                typeof(EventTimelineControl), 
                new PropertyMetadata(100.0, (d, e) => ((EventTimelineControl)d).DrawTimeline()));

        public double TotalDistance
        {
            get => (double)GetValue(TotalDistanceProperty);
            set => SetValue(TotalDistanceProperty, value);
        }

        public static readonly DependencyProperty SelectedEventProperty =
            DependencyProperty.Register(nameof(SelectedEvent), typeof(TimeTagEvent), 
                typeof(EventTimelineControl), 
                new PropertyMetadata(null, (d, e) => ((EventTimelineControl)d).HighlightSelectedEvent()));

        public TimeTagEvent SelectedEvent
        {
            get => (TimeTagEvent)GetValue(SelectedEventProperty);
            set => SetValue(SelectedEventProperty, value);
        }

        #endregion

        /// <summary>
        /// 获取实际可用的画布宽度
        /// </summary>
        private double GetCanvasWidth()
        {
            if (TimelineCanvas == null) return MIN_CANVAS_WIDTH;

            var events = Events?.ToList();
            int eventCount = events?.Count ?? 0;

            // 基于事件数量计算所需宽度
            double requiredWidth = PADDING * 2 + Math.Max(eventCount - 1, 1) * MIN_NODE_SPACING;
            requiredWidth = Math.Max(requiredWidth, MIN_CANVAS_WIDTH);

            // 获取ScrollViewer的实际宽度
            var scrollViewer = GetParentScrollViewer();
            double availableWidth = scrollViewer?.ActualWidth ?? TimelineCanvas.ActualWidth;
            
            // 如果可用宽度大于所需宽度，使用可用宽度（让基线填满空间）
            // 如果可用宽度小于所需宽度，使用所需宽度（启用滚动）
            return Math.Max(availableWidth, requiredWidth);
        }

        /// <summary>
        /// 获取父级ScrollViewer
        /// </summary>
        private ScrollViewer GetParentScrollViewer()
        {
            DependencyObject parent = TimelineCanvas;
            while (parent != null)
            {
                if (parent is ScrollViewer sv) return sv;
                parent = VisualTreeHelper.GetParent(parent);
            }
            return null;
        }

        /// <summary>
        /// 绘制时间线
        /// </summary>
        private void DrawTimeline()
        {
            if (TimelineCanvas == null) return;

            // 清除动态添加的元素（保留基线）
            ClearDynamicElements();

            var events = Events?.OrderBy(e => e.Distance).ToList();
            if (events == null || events.Count == 0)
            {
                // 没有事件时画一条简单的基线
                DrawBaseLineOnly();
                return;
            }

            // 计算画布宽度并设置
            double canvasWidth = GetCanvasWidth();
            TimelineCanvas.Width = canvasWidth;

            // 计算可用绘图区域
            double availableWidth = canvasWidth - PADDING * 2;

            // 更新基线
            UpdateBaseLine(PADDING, canvasWidth - PADDING);

            // 绘制所有事件节点
            for (int i = 0; i < events.Count; i++)
            {
                var evt = events[i];
                
                // 计算位置：基于距离比例
                double positionRatio = TotalDistance > 0 ? evt.Distance / TotalDistance : 0;
                double x = PADDING + positionRatio * availableWidth;
                
                // 确保第一个点在起点，最后一个点在终点
                if (i == 0) x = PADDING;
                else if (i == events.Count - 1) x = canvasWidth - PADDING;
                
                DrawEventNode(evt, x, NODE_Y, i);
            }

            HighlightSelectedEvent();
        }

        /// <summary>
        /// 清除动态元素
        /// </summary>
        private void ClearDynamicElements()
        {
            var toRemove = TimelineCanvas.Children.OfType<FrameworkElement>()
                .Where(c => c != BaseLine)
                .ToList();
            
            foreach (var child in toRemove)
            {
                TimelineCanvas.Children.Remove(child);
            }
        }

        /// <summary>
        /// 仅绘制基线（无事件时）
        /// </summary>
        private void DrawBaseLineOnly()
        {
            double canvasWidth = Math.Max(TimelineCanvas.ActualWidth, MIN_CANVAS_WIDTH);
            if (double.IsNaN(canvasWidth) || canvasWidth <= 0) canvasWidth = MIN_CANVAS_WIDTH;
            
            TimelineCanvas.Width = canvasWidth;
            UpdateBaseLine(PADDING, canvasWidth - PADDING);
        }

        /// <summary>
        /// 更新基线位置
        /// </summary>
        private void UpdateBaseLine(double x1, double x2)
        {
            BaseLine.X1 = x1;
            BaseLine.Y1 = NODE_Y;
            BaseLine.X2 = x2;
            BaseLine.Y2 = NODE_Y;
        }

        /// <summary>
        /// 绘制单个事件节点
        /// </summary>
        private void DrawEventNode(TimeTagEvent evt, double x, double y, int index)
        {
            var color = GetEventColor(evt.Type);
            
            // 节点圆形（直径14）
            var ellipse = new Ellipse
            {
                Width = 14,
                Height = 14,
                Fill = new SolidColorBrush(color),
                Stroke = Brushes.White,
                StrokeThickness = 2,
                Tag = evt
            };
            
            // 居中定位
            Canvas.SetLeft(ellipse, x - 7);
            Canvas.SetTop(ellipse, y - 7);
            
            // 鼠标事件
            ellipse.MouseLeftButtonDown += (s, e) => 
            {
                SelectedEvent = evt;
                e.Handled = true;
            };
            
            ellipse.MouseEnter += (s, e) =>
            {
                ellipse.Width = 18;
                ellipse.Height = 18;
                Canvas.SetLeft(ellipse, x - 9);
                Canvas.SetTop(ellipse, y - 9);
                ellipse.Cursor = System.Windows.Input.Cursors.Hand;
            };
            
            ellipse.MouseLeave += (s, e) =>
            {
                ellipse.Width = 14;
                ellipse.Height = 14;
                Canvas.SetLeft(ellipse, x - 7);
                Canvas.SetTop(ellipse, y - 7);
            };
            
            TimelineCanvas.Children.Add(ellipse);
            
            // 交替上下显示标签，避免重叠
            bool showAbove = (index % 2) == 1;
            DrawEventLabel(evt, x, y, showAbove, color);
        }

        /// <summary>
        /// 绘制事件标签
        /// </summary>
        private void DrawEventLabel(TimeTagEvent evt, double x, double y, bool showAbove, Color color)
        {
            // 连接线起点和终点
            double lineStartY = showAbove ? y - 7 : y + 7;
            double lineEndY = showAbove ? y - 20 : y + 20;
            double textY = showAbove ? y - 35 : y + 22;
            
            // 垂直连接线
            var line = new Line
            {
                Stroke = new SolidColorBrush(color),
                StrokeThickness = 1,
                StrokeDashArray = new DoubleCollection { 2, 2 },
                X1 = x,
                Y1 = lineStartY,
                X2 = x,
                Y2 = lineEndY,
                Tag = evt
            };
            TimelineCanvas.Children.Add(line);
            
            // 事件名称
            var nameText = new TextBlock
            {
                Text = evt.Name,
                FontSize = 10,
                Foreground = Brushes.Black,
                TextAlignment = TextAlignment.Center,
                Tag = evt
            };
            
            // 计算文本宽度并居中
            nameText.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
            double textWidth = nameText.DesiredSize.Width;
            Canvas.SetLeft(nameText, x - textWidth / 2);
            Canvas.SetTop(nameText, textY);
            TimelineCanvas.Children.Add(nameText);
            
            // 累计时间（在名称下方/上方）
            var timeText = new TextBlock
            {
                Text = $"{evt.CumulativeTime:F1}s",
                FontSize = 9,
                Foreground = Brushes.Gray,
                TextAlignment = TextAlignment.Center,
                Tag = evt
            };
            
            timeText.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
            textWidth = timeText.DesiredSize.Width;
            Canvas.SetLeft(timeText, x - textWidth / 2);
            Canvas.SetTop(timeText, textY + (showAbove ? -13 : 13));
            TimelineCanvas.Children.Add(timeText);
        }

        /// <summary>
        /// 高亮选中事件
        /// </summary>
        private void HighlightSelectedEvent()
        {
            if (TimelineCanvas == null) return;

            foreach (var ellipse in TimelineCanvas.Children.OfType<Ellipse>()
                .Where(e => e.Tag is TimeTagEvent))
            {
                var evt = ellipse.Tag as TimeTagEvent;
                if (evt == SelectedEvent)
                {
                    ellipse.Stroke = new SolidColorBrush(Colors.Red);
                    ellipse.StrokeThickness = 3;
                    Canvas.SetZIndex(ellipse, 100);
                }
                else
                {
                    ellipse.Stroke = Brushes.White;
                    ellipse.StrokeThickness = 2;
                    Canvas.SetZIndex(ellipse, 0);
                }
            }
        }

        /// <summary>
        /// 获取事件类型对应的颜色
        /// </summary>
        private Color GetEventColor(EventType type)
        {
            switch (type)
            {
                case EventType.Start:
                    return Color.FromRgb(76, 175, 80);    // Green
                case EventType.End:
                    return Color.FromRgb(96, 125, 139);   // Blue Gray
                case EventType.Turn:
                    return Color.FromRgb(255, 152, 0);    // Orange
                case EventType.Wait:
                    return Color.FromRgb(156, 39, 176);   // Purple
                case EventType.Load:
                case EventType.Unload:
                    return Color.FromRgb(244, 67, 54);    // Red
                case EventType.Pass:
                    return Color.FromRgb(33, 150, 243);   // Blue
                default:
                    return Colors.Gray;
            }
        }
    }
}
