using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
using Crysome.Common.Network.Packets.Client;
using Crysome.Server.Model;
using Crysome.Server.ViewModel;
using Wpf.Ui.Controls;

namespace Crysome.Server.View;

public class ProcessManagerWindow : FluentWindow, IComponentConnector, IStyleConnector
{
	private readonly ClientInfo _client;

	private readonly ManageClientsViewModel _vm;

	private readonly ObservableCollection<ProcessItemViewModel> _processes = new ObservableCollection<ProcessItemViewModel>();

	private readonly ICollectionView _processView;

	internal TextBlock TitleText;

	internal Button RefreshBtn;

	internal Button CloseBtn;

	internal TextBox SearchBox;

	internal ListView ProcessList;

	internal TextBlock StatusText;

	private bool _contentLoaded;

	public ProcessManagerWindow(ClientInfo client, ManageClientsViewModel vm)
	{
		InitializeComponent();
		_client = client;
		_vm = vm;
		((Window)this).Title = "Process Manager — " + (client?.Address ?? "?");
		TitleText.Text = ((Window)this).Title;
		_processView = CollectionViewSource.GetDefaultView(_processes);
		ProcessList.ItemsSource = (IEnumerable)_processView;
		((FrameworkElement)this).Loaded += delegate
		{
			Refresh();
		};
	}

	private void Refresh()
	{
		_processes.Clear();
		StatusText.Text = "Loading...";
		_vm.RequestProcessList(_client, delegate(GetProcessListResponsePacket packet)
		{
			if (((packet != null) ? packet.Processes : null) != null)
			{
				foreach (ProcessListEntry process in packet.Processes)
				{
					ImageSource icon = LoadIcon(process.IconData);
					_processes.Add(new ProcessItemViewModel
					{
						Name = process.Name,
						Pid = process.Pid,
						Icon = icon
					});
				}
				((DispatcherObject)Application.Current).Dispatcher.Invoke((Action)delegate
				{
					ApplySearchFilter();
				});
			}
		});
	}

	private void SearchBox_TextChanged(object sender, TextChangedEventArgs e)
	{
		ApplySearchFilter();
	}

	private void ApplySearchFilter()
	{
		string q = (SearchBox?.Text ?? "").Trim().ToLowerInvariant();
		_processView.Filter = (string.IsNullOrEmpty(q) ? null : ((Predicate<object>)((object o) => o is ProcessItemViewModel processItemViewModel && ((processItemViewModel.Name ?? "").ToLowerInvariant().Contains(q) || processItemViewModel.Pid.ToString().Contains(q)))));
		int num = (string.IsNullOrEmpty(q) ? _processes.Count : ((IEnumerable)_processView).Cast<object>().Count());
		StatusText.Text = (string.IsNullOrEmpty(q) ? (_processes.Count + " processes") : (num + " of " + _processes.Count + " processes"));
	}

	private static ImageSource LoadIcon(byte[] data)
	{
		if (data == null || data.Length == 0)
		{
			return null;
		}
		try
		{
			BitmapImage bitmapImage = new BitmapImage();
			bitmapImage.BeginInit();
			bitmapImage.StreamSource = new MemoryStream(data);
			bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
			bitmapImage.EndInit();
			((Freezable)bitmapImage).Freeze();
			return bitmapImage;
		}
		catch
		{
			return null;
		}
	}

	private void RefreshBtn_Click(object sender, RoutedEventArgs e)
	{
		Refresh();
	}

	private void CloseBtn_Click(object sender, RoutedEventArgs e)
	{
		((Window)this).Close();
	}

	private void Header_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
	{
		try
		{
			((Window)this).DragMove();
		}
		catch
		{
		}
	}

	private void KillBtn_Click(object sender, RoutedEventArgs e)
	{
		if ((sender as FrameworkElement)?.DataContext is ProcessItemViewModel processItemViewModel)
		{
			_vm.KillProcessOnClient(_client, processItemViewModel.Pid);
			_processes.Remove(processItemViewModel);
			StatusText.Text = "Kill sent for PID " + processItemViewModel.Pid;
		}
	}

	private void ProcessList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
	{
		if (ProcessList.SelectedItem is ProcessItemViewModel processItemViewModel)
		{
			_vm.KillProcessOnClient(_client, processItemViewModel.Pid);
			_processes.Remove(processItemViewModel);
			StatusText.Text = "Kill sent for PID " + processItemViewModel.Pid;
		}
	}

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

	[DebuggerNonUserCode]
	[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
	[EditorBrowsable(EditorBrowsableState.Never)]
	void IComponentConnector.Connect(int connectionId, object target)
	{
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Expected O, but got Unknown
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Expected O, but got Unknown
		switch (connectionId)
		{
		case 1:
			((Border)target).MouseLeftButtonDown += Header_MouseLeftButtonDown;
			break;
		case 2:
			TitleText = (TextBlock)target;
			break;
		case 3:
			RefreshBtn = (Button)target;
			((ButtonBase)(object)RefreshBtn).Click += RefreshBtn_Click;
			break;
		case 4:
			CloseBtn = (Button)target;
			((ButtonBase)(object)CloseBtn).Click += CloseBtn_Click;
			break;
		case 5:
			SearchBox = (TextBox)target;
			SearchBox.TextChanged += SearchBox_TextChanged;
			break;
		case 6:
			ProcessList = (ListView)target;
			ProcessList.MouseDoubleClick += ProcessList_MouseDoubleClick;
			break;
		case 8:
			StatusText = (TextBlock)target;
			break;
		default:
			_contentLoaded = true;
			break;
		}
	}

	[DebuggerNonUserCode]
	[GeneratedCode("PresentationBuildTasks", "9.0.14.0")]
	[EditorBrowsable(EditorBrowsableState.Never)]
	void IStyleConnector.Connect(int connectionId, object target)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		if (connectionId == 7)
		{
			((ButtonBase)(Button)target).Click += KillBtn_Click;
		}
	}
}
