using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using OxyPlot.Series;
using OxyPlot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using OxyPlot.Axes;

namespace GettingStarted.ViewModels
{
    internal partial class MainViewModel3 : ObservableObject
    {
        [ObservableProperty]
        private PlotModel _myModel;


        [ObservableProperty]
        private LineSeries _lineSeries;


        [ObservableProperty]
        private double _cutOffSecond;



        public MainViewModel3()
        {
            MyModel = new PlotModel() { Title = "Getting Started with RT Plot", PlotMargins = new OxyThickness(50, 10, 50, 50) };
            LineSeries = new LineSeries() { Title = "Dynamic Data" };

            DateTimeAxis timeAxis = new DateTimeAxis()
            {
                Position = AxisPosition.Bottom,
                StringFormat = "HH:mm:ss",
                Title = "Time",
                IntervalType = DateTimeIntervalType.Seconds,
                IntervalLength = 60,
                IsZoomEnabled = false,
                IsPanEnabled = false,
            };
            MyModel.Axes.Add(timeAxis);

            LinearAxis linearAxis = new LinearAxis()
            {
                Position = AxisPosition.Left,
                Title = "Value"
            };
            MyModel.Axes.Add(linearAxis);

            MyModel.Series.Add(LineSeries);

            CutOffSecond = 10d;

            _timer = new System.Timers.Timer();
            _timer.Interval = 10;
            _timer.Elapsed -= _timer_Elapsed;
            _timer.Elapsed += _timer_Elapsed;
        }

        private int _lastX = 0;
        private Random _rand = new Random();
        private double _noiseLevel = 0.3;
        private void _timer_Elapsed(object? sender, ElapsedEventArgs e)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                DateTime now = DateTime.Now;

                double noise = (_rand.NextDouble() - 0.5) * _noiseLevel;
                //LineSeries.Points.Add(new DataPoint(_lastX, Math.Sin(_lastX * 0.1) + noise));
                LineSeries.Points.Add(new DataPoint(DateTimeAxis.ToDouble(DateTime.Now), Math.Sin(_lastX * 0.1) + noise));
                
                DateTime cutOff = now.AddSeconds(-1 * CutOffSecond);
                LineSeries.Points.RemoveAll(d => DateTimeAxis.ToDateTime(d.X) < cutOff);

                if (MyModel.Axes[0] is DateTimeAxis timeAxis)
                {
                    timeAxis.Minimum = DateTimeAxis.ToDouble(cutOff);
                    timeAxis.Maximum = DateTimeAxis.ToDouble(now);
                }

                MyModel.InvalidatePlot(true);
                _lastX++;
            });
        }

        private bool _isTimerStarted = false;
        private System.Timers.Timer _timer;

        [RelayCommand]
        private void FlipTimer()
        {
            if (!_isTimerStarted)
            {
                _timer.Start();
                _isTimerStarted = true;
            }
            else
            {
                _timer.Stop();
                _isTimerStarted = false;
            }
        }

        public void OnClosing()
        {
            _timer.Stop();
            _timer.Dispose();
        }
    }
}
