using OxyPlot;
using OxyPlot.Axes;
using OxyPlot.Series;
using OxyPlot.WindowsForms;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace 全自动水压检测仪
{
    /// <summary>
    /// 图表管理器 - 负责实时曲线图的创建和数据更新
    /// 使用统一Y轴显示实时压力和压力设定值，便于数据对比
    /// </summary>
    public class ChartManager
    {
        private PlotView _plotView;
        private PlotModel _plotModel;
        private LineSeries _pressureSeries;           // 实时压力值（地址3130）
        private LineSeries _pressureSetSeries;        // 压力设定值（地址2400）
        private List<DataPoint> _pressureData;
        private List<DataPoint> _pressureSetData;
        private const int MAX_DATA_POINTS = 3600; // 最多显示3600个数据点（1小时）
        private double _initialMinX = 0; // 记录初始最小X值
        private bool _isUserZooming = false; // 用户是否正在缩放
        private double _maxPressureValue = 0; // 记录最大压力值用于动态调整Y轴

        /// <summary>
        /// 初始化图表并添加到指定面板
        /// </summary>
        public void InitializeChart(Control targetPanel)
        {

            if (targetPanel == null)
                throw new ArgumentNullException(nameof(targetPanel));

            // 清除占位文字
            targetPanel.Text = null;

            // 初始化数据集合
            _pressureData = new List<DataPoint>();
            _pressureSetData = new List<DataPoint>();

            // 创建PlotModel
            _plotModel = new PlotModel
            {
                Title = "",
                Background = OxyColors.White,
                PlotAreaBorderColor = OxyColor.FromRgb(180, 180, 180),
                PlotAreaBorderThickness = new OxyThickness(1.5),
                Padding = new OxyThickness(10, 10, 20, 10)
            };

            // 配置图例 - 放在图表外面顶部
            _plotModel.Legends.Add(new OxyPlot.Legends.Legend
            {
                LegendPosition = OxyPlot.Legends.LegendPosition.TopCenter,
                LegendOrientation = OxyPlot.Legends.LegendOrientation.Horizontal,
                LegendPlacement = OxyPlot.Legends.LegendPlacement.Outside,
                LegendBackground = OxyColor.FromAColor(250, OxyColors.White),
                LegendBorder = OxyColor.FromRgb(200, 200, 200),
                LegendBorderThickness = 1,
                LegendPadding = 10,
                LegendMargin = 8,
                LegendSymbolLength = 30,
                LegendSymbolMargin = 10,
                LegendFontSize = 12,
                LegendItemSpacing = 20
            });

            // 配置X轴（时间轴 - 使用测试时间总秒数）
            var xAxis = new LinearAxis
            {
                Position = AxisPosition.Bottom,
                Title = "测试时间",
                TitleFontSize = 13,
                TitleFontWeight = OxyPlot.FontWeights.Bold,
                FontSize = 11,
                MajorGridlineStyle = LineStyle.Solid,
                MajorGridlineColor = OxyColor.FromRgb(220, 220, 220),
                MajorGridlineThickness = 1,
                MinorGridlineStyle = LineStyle.Dot,
                MinorGridlineColor = OxyColor.FromRgb(240, 240, 240),
                MinorGridlineThickness = 0.5,
                Minimum = 0,
                Maximum = 60,
                IsPanEnabled = true,
                IsZoomEnabled = true,
                // 格式化X轴标签为HH:MM:SS格式
                LabelFormatter = value =>
                {
                    int totalSec = (int)value;
                    int h = totalSec / 3600;
                    int m = (totalSec % 3600) / 60;
                    int s = totalSec % 60;
                    return $"{h:D2}:{m:D2}:{s:D2}";
                }
            };
            
            _plotModel.Axes.Add(xAxis);

            // 配置Y轴（统一显示实时压力和压力设定值）
            var yAxis = new LinearAxis
            {
                Position = AxisPosition.Left,
                Title = "压力 (PSI)",
                TitleFontSize = 13,
                TitleFontWeight = OxyPlot.FontWeights.Bold,
                FontSize = 11,
                MajorGridlineStyle = LineStyle.Solid,
                MajorGridlineColor = OxyColor.FromRgb(220, 220, 220),
                MajorGridlineThickness = 1,
                MinorGridlineStyle = LineStyle.Dot,
                MinorGridlineColor = OxyColor.FromRgb(240, 240, 240),
                MinorGridlineThickness = 0.5,
                StringFormat = "F2",
                Minimum = 0,
                Maximum = 10, // 初始最大值，会动态调整
                Key = "YAxis",
                IsPanEnabled = true,
                IsZoomEnabled = true
            };
            _plotModel.Axes.Add(yAxis);

            // 添加实时压力曲线 - 使用蓝色实线
            _pressureSeries = new LineSeries
            {
                Title = "实时压力",
                Color = OxyColor.FromRgb(30, 144, 255), // 道奇蓝
                StrokeThickness = 2.5,
                MarkerType = MarkerType.Circle,
                MarkerSize = 5,
                MarkerFill = OxyColor.FromRgb(30, 144, 255),
                MarkerStroke = OxyColors.White,
                MarkerStrokeThickness = 1.5,
                LineStyle = LineStyle.Solid,
                YAxisKey = "YAxis"
            };
            _plotModel.Series.Add(_pressureSeries);

            // 添加压力设定值曲线 - 使用红色虚线
            _pressureSetSeries = new LineSeries
            {
                Title = "压力设定值",
                Color = OxyColor.FromRgb(220, 20, 60), // 深红色
                StrokeThickness = 2.5,
                MarkerType = MarkerType.Square,
                MarkerSize = 5,
                MarkerFill = OxyColor.FromRgb(220, 20, 60),
                MarkerStroke = OxyColors.White,
                MarkerStrokeThickness = 1.5,
                LineStyle = LineStyle.Dash,
                YAxisKey = "YAxis"
            };
            _plotModel.Series.Add(_pressureSetSeries);

            // 创建PlotView控件
            _plotView = new PlotView
            {
                Model = _plotModel,
                Dock = DockStyle.Fill,
                BackColor = System.Drawing.Color.White
            };
            
            // 监听鼠标事件，检测用户交互（缩放和平移）
            _plotView.MouseDown += (s, e) => 
            { 
                _isUserZooming = true; 
            };
            
            _plotView.MouseWheel += (s, e) => 
            { 
                _isUserZooming = true; 
            };
            
            // 添加双击重置功能
            _plotView.MouseDoubleClick += (s, e) =>
            {
                if (e.Button == System.Windows.Forms.MouseButtons.Left)
                {
                    ResetZoom();
                }
            };

            // 添加到目标面板
            targetPanel.Controls.Add(_plotView);
        }

        /// <summary>
        /// 添加新的数据点
        /// </summary>
        /// <param name="pressure">实时压力值</param>
        /// <param name="pressureSetValue">压力设定值（来自"压力设置(PSI)"，地址2400）</param>
        /// <param name="totalSeconds">测试时间（总秒数）</param>
        public void AddDataPoint(double pressure, double pressureSetValue, int totalSeconds)
        {
            if (_pressureSeries == null || _pressureSetSeries == null || _plotModel == null)
                return;

            // 添加数据点（使用测试时间总秒数作为X轴值）
            _pressureData.Add(new DataPoint(totalSeconds, pressure));
            _pressureSetData.Add(new DataPoint(totalSeconds, pressureSetValue));

            // 记录初始最小X值（第一个数据点的时间）
            if (_pressureData.Count == 1)
            {
                _initialMinX = totalSeconds;
            }

            // 更新最大压力值（用于动态调整Y轴）
            double currentMaxPressure = Math.Max(pressure, pressureSetValue);
            if (currentMaxPressure > _maxPressureValue)
            {
                _maxPressureValue = currentMaxPressure;
            }

            // 限制数据点数量，保持图表流畅（保留最近3600个点）
            if (_pressureData.Count > MAX_DATA_POINTS)
            {
                _pressureData.RemoveAt(0);
                _pressureSetData.RemoveAt(0);
                // 更新初始最小X值
                if (_pressureData.Count > 0)
                {
                    _initialMinX = _pressureData[0].X;
                }
            }

            // 更新系列数据
            _pressureSeries.Points.Clear();
            _pressureSeries.Points.AddRange(_pressureData);

            _pressureSetSeries.Points.Clear();
            _pressureSetSeries.Points.AddRange(_pressureSetData);

            // 只有在非用户缩放状态下才自动调整轴范围
            if (!_isUserZooming)
            {
                // 调整X轴范围
                if (_pressureData.Count > 0)
                {
                    var xAxis = _plotModel.Axes.FirstOrDefault(a => a.Position == AxisPosition.Bottom);
                    if (xAxis != null)
                    {
                        // 始终从初始时间开始显示
                        double minX = _initialMinX;
                        double maxX = _pressureData.Max(p => p.X);
                        
                        xAxis.Minimum = minX;
                        xAxis.Maximum = maxX + 5; // 留一点余量
                        xAxis.Reset();
                    }
                }

                // 动态调整Y轴范围 - 比实际最大值大20%，确保曲线美观
                var yAxis = _plotModel.Axes.FirstOrDefault(a => a.Key == "YAxis");
                if (yAxis != null && _maxPressureValue > 0)
                {
                    // Y轴最大值设置为实际最大值的1.2倍，最小为10
                    double yMax = Math.Max(_maxPressureValue * 1.2, 10);
                    
                    // 向上取整到合适的刻度
                    if (yMax < 10)
                        yMax = Math.Ceiling(yMax);
                    else if (yMax < 100)
                        yMax = Math.Ceiling(yMax / 5) * 5;
                    else
                        yMax = Math.Ceiling(yMax / 10) * 10;
                    
                    yAxis.Minimum = 0;
                    yAxis.Maximum = yMax;
                    yAxis.Reset();
                }
            }

            // 刷新图表
            _plotModel.InvalidatePlot(true);
        }

        /// <summary>
        /// 清除所有数据
        /// </summary>
        public void ClearData()
        {
            _pressureData?.Clear();
            _pressureSetData?.Clear();

            if (_pressureSeries != null)
            {
                _pressureSeries.Points.Clear();
            }

            if (_pressureSetSeries != null)
            {
                _pressureSetSeries.Points.Clear();
            }

            // 重置X轴范围
            var xAxis = _plotModel?.Axes.FirstOrDefault(a => a.Position == AxisPosition.Bottom);
            if (xAxis != null)
            {
                xAxis.Minimum = 0;
                xAxis.Maximum = 60;
                xAxis.Reset();
            }

            // 重置Y轴范围
            var yAxis = _plotModel?.Axes.FirstOrDefault(a => a.Key == "YAxis");
            if (yAxis != null)
            {
                yAxis.Minimum = 0;
                yAxis.Maximum = 10;
                yAxis.Reset();
            }

            // 重置初始最小X值、用户缩放状态和最大压力值
            _initialMinX = 0;
            _isUserZooming = false;
            _maxPressureValue = 0;

            _plotModel?.InvalidatePlot(true);
        }

        /// <summary>
        /// 重置缩放状态，恢复自动跟随模式
        /// </summary>
        public void ResetZoom()
        {
            _isUserZooming = false;
            
            if (_pressureData.Count > 0)
            {
                // 重置X轴
                var xAxis = _plotModel?.Axes.FirstOrDefault(a => a.Position == AxisPosition.Bottom);
                if (xAxis != null)
                {
                    double minX = _initialMinX;
                    double maxX = _pressureData.Max(p => p.X);
                    xAxis.Minimum = minX;
                    xAxis.Maximum = maxX + 5;
                    xAxis.Reset();
                }

                // 重置Y轴
                var yAxis = _plotModel?.Axes.FirstOrDefault(a => a.Key == "YAxis");
                if (yAxis != null && _maxPressureValue > 0)
                {
                    double yMax = Math.Max(_maxPressureValue * 1.2, 10);
                    
                    if (yMax < 10)
                        yMax = Math.Ceiling(yMax);
                    else if (yMax < 100)
                        yMax = Math.Ceiling(yMax / 5) * 5;
                    else
                        yMax = Math.Ceiling(yMax / 10) * 10;
                    
                    yAxis.Minimum = 0;
                    yAxis.Maximum = yMax;
                    yAxis.Reset();
                }
            }
            
            _plotModel?.InvalidatePlot(true);
        }

        /// <summary>
        /// 更新图表配置（例如切换温度模式时）
        /// </summary>
        /// <param name="isHighTemperatureMode">是否为高温模式</param>
        public void UpdateChartMode(bool isHighTemperatureMode)
        {
            if (_plotModel == null || _plotModel.Series.Count < 2)
                return;

            // 可以根据模式调整显示样式（如果需要）
            _plotModel.InvalidatePlot(true);
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            _plotView?.Dispose();
            _plotModel = null;
            _pressureSeries = null;
            _pressureSetSeries = null;
            _pressureData = null;
            _pressureSetData = null;
        }
    }
}
