using OpenTK.Graphics.OpenGL;
using Panuon.WPF.UI;
using SWRIS.Core;
using SWRIS.Dtos;
using SWRIS.Extensions;
using SWRIS.Models;
using SWRIS.Models.ViewModel;
using SWRIS.Repository;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace SWRIS.Pages
{
    /// <summary>
    /// DamagesPage.xaml 的交互逻辑
    /// </summary>
    public partial class DamagesPage : Page
    {
        private readonly string[] _colors = new string[] { "#70a1d7", "#a1de93", "#f7f48b", "#f47c7c", "#c264fe", "#00fff5", "#f8b195", "#7a08fa" };
        private readonly IRecordRepository recordRepository;
        public DamagesViewModel DamagesView { get; set; }

        public DamagesPage()
        {
            InitializeComponent();
            DamagesView = new DamagesViewModel
            {
                Record = new RecordDto(),
                Sensors = new ObservableCollection<SensorModel>()
            };
            recordRepository = new RecordRepository();
        }

        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            if (NavigationService != null)
            {
                var query = System.Web.HttpUtility.ParseQueryString(NavigationService.CurrentSource.OriginalString.Split('?')[1]);
                var record = recordRepository.GetRecord(int.Parse(query["id"]));
                if (record != null && record.DataFilePath != null)
                {
                    DamagesView.Record = record;
                    var inUseSensors = record.InUseSensors?.Split(',').Select(s => int.Parse(s.Trim())).ToArray();
                    foreach (var sensorNo in inUseSensors)
                    {
                        var sensor = new SensorModel
                        {
                            Id = sensorNo,
                            Name = $"传感器{sensorNo}",
                            Color = _colors[sensorNo - 1],
                            IsActive = false
                        };
                        sensor.PropertyChanged += (s, arg) =>
                        {
                            if (arg.PropertyName == nameof(SensorModel.IsActive))
                            {
                                if (s is SensorModel sensor1 && sensor1 != null && sensor1.IsActive)
                                {
                                    // 如果有传感器被选中，取消合值的选中状态
                                    DamagesView.IsSummaryActive = false;
                                }
                            }
                        };
                        DamagesView.Sensors.Add(sensor);
                    }
                    var damageData = DatFileHandler.ReadDatFile(record.DataFilePath);
                    if (damageData?.Length > 0)
                    {
                        var parsedData = ParseSensorData(damageData, record.SensorCount, record.StartPoint, record.EndPoint);
                        chartLine.AddDataPoints(parsedData, record.Damages.ToList());
                    }
                }
            }
            DataContext = DamagesView;
        }
        private void Delete_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if ((sender as Image)?.Tag is int id)
            {
                var result = MessageBoxX.Show(Application.Current.MainWindow, "此操作不可恢复，是否确认删除损伤记录？", "警告", MessageBoxButton.YesNo, MessageBoxIcon.Warning, DefaultButton.YesOK);
                if (result == MessageBoxResult.Yes)
                {
                    if (recordRepository.DeleteDamage(id))
                    {
                        DamagesView.Record.Damages.Remove(DamagesView.Record.Damages.FirstOrDefault(d => d.Id == id));
                        recordRepository.UpdateRecordDamageCount(DamagesView.Record.Id.Value, DamagesView.Record.Damages.Count());
                        NoticeBox.Show("损伤数据删除成功", "通知", MessageBoxIcon.Success, false, 3000);
                    }
                }
            }
        }

        private void GoBack_Click(object sender, RoutedEventArgs e)
        {
            NavigationService?.GoBack();
        }
        public (double[] Positions, ushort[,] Damages) ParseSensorData(byte[] data, int sensorCount, double startPosition, double endPosition)
        {
            // 检查数据长度是否能被传感器数量整除
            if (data.Length % sensorCount != 0)
            {
                LogHelper.Error($"数据长度不匹配。数据长度 {data.Length} 字节不能被传感器数量 {sensorCount} 整除。");
                return (null, null);
            }
            // 计算样本数量
            int sampleCount = data.Length / sensorCount;
            // 计算采样步长
            double samplingStep = (endPosition - startPosition) / (sampleCount - 1);
            // 初始化结果列表
            (double[] Positions, ushort[,] Damages) sensorData = (new double[sampleCount], new ushort[sensorCount, sampleCount]);
            // 解析数据
            for (int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
            {
                sensorData.Positions[sampleIndex] = startPosition;
                for (int sensorIndex = 0; sensorIndex < sensorCount; sensorIndex++)
                {
                    // 计算数据在字节数组中的位置
                    int dataIndex = (sampleIndex * sensorCount) + sensorIndex;
                    // 将 byte 转换为 ushort（直接赋值，因为 byte 可以隐式转换为 ushort）
                    sensorData.Damages[sensorIndex, sampleIndex] = data[dataIndex];
                }
                startPosition += samplingStep;
            }

            return sensorData;
        }

        private void Sensor_Checked(object sender, RoutedEventArgs e)
        {
            if (sender is ToggleButton toggleButton && int.TryParse(toggleButton.Tag?.ToString(), out int id))
            {
                chartLine?.SignalPlotVisible(id, true);
            }
        }

        private void Sensor_UnChecked(object sender, RoutedEventArgs e)
        {
            if (sender is ToggleButton toggleButton && int.TryParse(toggleButton.Tag?.ToString(), out int id))
            {
                chartLine?.SignalPlotVisible(id, false);
            }
        }
    }
}
