using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;
using Crysome.Common.Network;
using Crysome.Server.Model;
using Crysome.Server.ViewModel;

namespace Crysome.Server.View;

public class ManageClients : UserControl, IComponentConnector
{
	private readonly DispatcherTimer _animTimer = new DispatcherTimer
	{
		Interval = TimeSpan.FromMilliseconds(16L, 0L)
	};

	private readonly DispatcherTimer _statsTimer = new DispatcherTimer
	{
		Interval = TimeSpan.FromMilliseconds(800L, 0L)
	};

	private readonly double[] _dotX = new double[5] { 0.0, 30.0, 60.0, 90.0, 120.0 };

	private readonly double[] _dotSpeed = new double[5] { 2.8, 2.1, 3.3, 1.9, 2.5 };

	private const double CanvasWidth = 170.0;

	private readonly TranslateTransform[] _dotTx;

	internal ManageClients TheControl;

	internal Canvas PacketCanvas;

	internal Ellipse Dot0;

	internal TranslateTransform DotTx0;

	internal Ellipse Dot1;

	internal TranslateTransform DotTx1;

	internal Ellipse Dot2;

	internal TranslateTransform DotTx2;

	internal Ellipse Dot3;

	internal TranslateTransform DotTx3;

	internal Ellipse Dot4;

	internal TranslateTransform DotTx4;

	internal Border ThroughputBar;

	internal TextBlock ThroughputText;

	internal Border QualityBar;

	internal TextBlock QualityBarText;

	internal TextBlock RttText;

	internal TextBlock LossText;

	internal TextBlock TxText;

	internal TextBlock RxText;

	internal TextBlock ClientsCountText;

	internal TextBlock AdaptiveLevelText;

	internal DataGrid ClientsGrid;

	private bool _contentLoaded;

	public ManageClients()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Expected O, but got Unknown
		InitializeComponent();
		_dotTx = new TranslateTransform[5] { DotTx0, DotTx1, DotTx2, DotTx3, DotTx4 };
		_animTimer.Tick += AnimTimer_Tick;
		_statsTimer.Tick += StatsTimer_Tick;
		_animTimer.Start();
		_statsTimer.Start();
		base.Unloaded += delegate
		{
			_animTimer.Stop();
			_statsTimer.Stop();
		};
	}

	private void AnimTimer_Tick(object sender, EventArgs e)
	{
		for (int i = 0; i < _dotTx.Length; i++)
		{
			_dotX[i] += _dotSpeed[i];
			if (_dotX[i] > 180.0)
			{
				_dotX[i] = -10.0;
			}
			_dotTx[i].X = _dotX[i];
		}
	}

	private void StatsTimer_Tick(object sender, EventArgs e)
	{
		if (!(base.DataContext is ManageClientsViewModel manageClientsViewModel))
		{
			return;
		}
		List<CrysomeClient> clientSnapshot = manageClientsViewModel.GetClientSnapshot();
		ClientsCountText.Text = clientSnapshot.Count.ToString();
		if (clientSnapshot.Count == 0)
		{
			RttText.Text = "— ms";
			LossText.Text = "0.0 %";
			TxText.Text = "0 B";
			RxText.Text = "0 B";
			ThroughputBar.Width = 0.0;
			ThroughputText.Text = "0 KB/s";
			QualityBar.Width = 170.0;
			QualityBarText.Text = "Idle";
			AdaptiveLevelText.Text = " · —";
			return;
		}
		double num = 0.0;
		double num2 = 0.0;
		long num3 = 0L;
		long num4 = 0L;
		foreach (CrysomeClient item in clientSnapshot)
		{
			num += item.RttMs;
			num2 += item.LossRate;
			num3 += item.BytesSent;
			num4 += item.BytesRecv;
		}
		double num5 = num / (double)clientSnapshot.Count;
		double num6 = num2 / (double)clientSnapshot.Count * 100.0;
		RttText.Text = $"{num5:F0} ms";
		LossText.Text = $"{num6:F1} %";
		TxText.Text = FormatBytes(num3);
		RxText.Text = FormatBytes(num4);
		double num7 = (double)(num3 + num4) / 1024.0 / 0.8;
		double val = Math.Min(170.0, num7 / 500.0 * 170.0);
		ThroughputBar.Width = Math.Max(0.0, val);
		ThroughputText.Text = $"{num7:F0} KB/s";
		double num8 = Math.Min(1.0, num6 / 100.0 * 0.6 + num5 / 2000.0 * 0.4);
		double width = Math.Max(10.0, (1.0 - num8) * 170.0);
		QualityBar.Width = width;
		if (num8 < 0.1)
		{
			QualityBar.Background = new SolidColorBrush(Color.FromRgb(129, 199, 132));
			QualityBarText.Text = "Excellent";
			AdaptiveLevelText.Text = " · HD";
		}
		else if (num8 < 0.3)
		{
			QualityBar.Background = new SolidColorBrush(Color.FromRgb(79, 195, 247));
			QualityBarText.Text = "Good";
			AdaptiveLevelText.Text = " · Good";
		}
		else if (num8 < 0.6)
		{
			QualityBar.Background = new SolidColorBrush(Color.FromRgb(byte.MaxValue, 183, 77));
			QualityBarText.Text = "Fair";
			AdaptiveLevelText.Text = " · Fair";
		}
		else
		{
			QualityBar.Background = new SolidColorBrush(Color.FromRgb(239, 83, 80));
			QualityBarText.Text = "Poor";
			AdaptiveLevelText.Text = " · Low";
		}
		LossText.Foreground = ((num6 < 1.0) ? new SolidColorBrush(Color.FromRgb(129, 199, 132)) : ((num6 < 5.0) ? new SolidColorBrush(Color.FromRgb(byte.MaxValue, 183, 77)) : new SolidColorBrush(Color.FromRgb(239, 83, 80))));
		double num9 = 1.0 + Math.Min(2.0, num7 / 100.0);
		for (int i = 0; i < _dotSpeed.Length; i++)
		{
			_dotSpeed[i] = (1.5 + (double)i * 0.4) * num9;
		}
	}

	private static string FormatBytes(long b)
	{
		if (b < 1024)
		{
			return b + " B";
		}
		if (b < 1048576)
		{
			return ((double)b / 1024.0).ToString("F1") + " KB";
		}
		return ((double)b / 1024.0 / 1024.0).ToString("F1") + " MB";
	}

	private void ClientsGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
	{
		if (base.DataContext is ManageClientsViewModel manageClientsViewModel && sender is DataGrid dataGrid)
		{
			List<ClientInfo> items = dataGrid.SelectedItems.Cast<ClientInfo>().ToList();
			manageClientsViewModel.SyncSelectedClients(items);
		}
	}

	private void ClientsGrid_PreviewKeyDown(object sender, KeyEventArgs e)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Invalid comparison between Unknown and I4
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Invalid comparison between Unknown and I4
		if ((int)e.Key == 44 && (int)Keyboard.Modifiers == 2 && sender is DataGrid dataGrid)
		{
			dataGrid.SelectAll();
			e.Handled = true;
		}
	}

	private void ClientsGrid_LostFocus(object sender, RoutedEventArgs e)
	{
	}

	[DebuggerNonUserCode]
	[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
	public void InitializeComponent()
	{
		if (!_contentLoaded)
		{
			_contentLoaded = true;
			Uri resourceLocator = new Uri("/Crysome.Server;component/view/manageclients.xaml", UriKind.Relative);
			Application.LoadComponent(this, resourceLocator);
		}
	}

	[DebuggerNonUserCode]
	[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
	[EditorBrowsable(EditorBrowsableState.Never)]
	void IComponentConnector.Connect(int connectionId, object target)
	{
		switch (connectionId)
		{
		case 1:
			TheControl = (ManageClients)target;
			break;
		case 2:
			PacketCanvas = (Canvas)target;
			break;
		case 3:
			Dot0 = (Ellipse)target;
			break;
		case 4:
			DotTx0 = (TranslateTransform)target;
			break;
		case 5:
			Dot1 = (Ellipse)target;
			break;
		case 6:
			DotTx1 = (TranslateTransform)target;
			break;
		case 7:
			Dot2 = (Ellipse)target;
			break;
		case 8:
			DotTx2 = (TranslateTransform)target;
			break;
		case 9:
			Dot3 = (Ellipse)target;
			break;
		case 10:
			DotTx3 = (TranslateTransform)target;
			break;
		case 11:
			Dot4 = (Ellipse)target;
			break;
		case 12:
			DotTx4 = (TranslateTransform)target;
			break;
		case 13:
			ThroughputBar = (Border)target;
			break;
		case 14:
			ThroughputText = (TextBlock)target;
			break;
		case 15:
			QualityBar = (Border)target;
			break;
		case 16:
			QualityBarText = (TextBlock)target;
			break;
		case 17:
			RttText = (TextBlock)target;
			break;
		case 18:
			LossText = (TextBlock)target;
			break;
		case 19:
			TxText = (TextBlock)target;
			break;
		case 20:
			RxText = (TextBlock)target;
			break;
		case 21:
			ClientsCountText = (TextBlock)target;
			break;
		case 22:
			AdaptiveLevelText = (TextBlock)target;
			break;
		case 23:
			ClientsGrid = (DataGrid)target;
			ClientsGrid.SelectionChanged += ClientsGrid_SelectionChanged;
			ClientsGrid.PreviewKeyDown += ClientsGrid_PreviewKeyDown;
			ClientsGrid.LostFocus += ClientsGrid_LostFocus;
			break;
		default:
			_contentLoaded = true;
			break;
		}
	}
}
