using LiveCharts;
using LiveCharts.Configurations;
using LiveCharts.Wpf;
using Newtonsoft.Json;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace FastGithub.UI
{
    /// 
    /// FlowChart.xaml 的交互逻辑
    /// 
    public partial class FlowChart : UserControl
    {
        private readonly LineSeries readSeries = new LineSeries
        {
            Title = "上行速率",
            PointGeometry = null,
            LineSmoothness = 1D,
            Values = new ChartValues()
        };
        private readonly LineSeries writeSeries = new LineSeries()
        {
            Title = "下行速率",
            PointGeometry = null,
            LineSmoothness = 1D,
            Values = new ChartValues()
        };
        private static DateTime GetDateTime(double timestamp) => new DateTime(1970, 1, 1).Add(TimeSpan.FromMilliseconds(timestamp)).ToLocalTime();
        private static double GetTimestamp(DateTime dateTime) => dateTime.ToUniversalTime().Subtract(new DateTime(1970, 1, 1)).TotalMilliseconds;
        public SeriesCollection Series { get; } = new SeriesCollection(Mappers.Xy().X(item => item.Timestamp).Y(item => item.Rate));
        public Func XFormatter { get; } = timestamp => GetDateTime(timestamp).ToString("HH:mm:ss");
        public Func YFormatter { get; } = value => $"{FlowStatistics.ToNetworkSizeString((long)value)}/s";
        public FlowChart()
        {
            InitializeComponent();
            this.Series.Add(this.readSeries);
            this.Series.Add(this.writeSeries);
            this.DataContext = this;
            this.InitFlowChartAsync();
        }
        private async void InitFlowChartAsync()
        {
            using var httpClient = new HttpClient();
            while (this.Dispatcher.HasShutdownStarted == false)
            {
                try
                {
                    await this.FlushFlowStatisticsAsync(httpClient);
                }
                catch (Exception)
                {
                }
                finally
                {
                    await Task.Delay(TimeSpan.FromSeconds(1d));
                }
            }
        }
        private async Task FlushFlowStatisticsAsync(HttpClient httpClient)
        {
            var response = await httpClient.GetAsync("http://localhost/flowStatistics");
            var json = await response.EnsureSuccessStatusCode().Content.ReadAsStringAsync();
            var flowStatistics = JsonConvert.DeserializeObject(json);
            if (flowStatistics == null)
            {
                return;
            }
            this.textBlockRead.Text = FlowStatistics.ToNetworkSizeString(flowStatistics.TotalRead);
            this.textBlockWrite.Text = FlowStatistics.ToNetworkSizeString(flowStatistics.TotalWrite);
            var timestamp = GetTimestamp(DateTime.Now);
            this.readSeries.Values.Add(new RateTick(flowStatistics.ReadRate, timestamp));
            this.writeSeries.Values.Add(new RateTick(flowStatistics.WriteRate, timestamp));
            if (this.readSeries.Values.Count > 60)
            {
                this.readSeries.Values.RemoveAt(0);
                this.writeSeries.Values.RemoveAt(0);
            }
        }
        private class RateTick
        {
            public double Rate { get; }
            public double Timestamp { get; }
            public RateTick(double rate, double timestamp)
            {
                this.Rate = rate;
                this.Timestamp = timestamp;
            }
        }
    }
}