using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using AxCopilot.SDK;

namespace AxCopilot.Handlers;

public class MonitorHandler : IActionHandler
{
	private struct MEMORYSTATUSEX
	{
		public uint dwLength;

		public uint dwMemoryLoad;

		public ulong ullTotalPhys;

		public ulong ullAvailPhys;

		public ulong ullTotalPageFile;

		public ulong ullAvailPageFile;

		public ulong ullTotalVirtual;

		public ulong ullAvailVirtual;

		public ulong ullAvailExtendedVirtual;
	}

	public string? Prefix => "monitor";

	public PluginMetadata Metadata => new PluginMetadata("Monitor", "시스템 리소스 모니터 — monitor", "1.0", "AX");

	[DllImport("kernel32.dll")]
	[return: MarshalAs(UnmanagedType.Bool)]
	private static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX lpBuffer);

	public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
	{
		string text = query.Trim().ToLowerInvariant();
		List<LauncherItem> list = new List<LauncherItem>();
		bool flag = string.IsNullOrWhiteSpace(text);
		if (flag || text.Contains("cpu") || text.Contains("프로세서"))
		{
			int processorCount = Environment.ProcessorCount;
			int value = Process.GetProcesses().Length;
			int value2 = 0;
			try
			{
				value2 = Process.GetProcesses().Sum(delegate(Process p)
				{
					try
					{
						return p.Threads.Count;
					}
					catch
					{
						return 0;
					}
				});
			}
			catch
			{
			}
			list.Add(new LauncherItem($"CPU: {processorCount}코어  ·  프로세스 {value}개  ·  스레드 {value2:N0}개", "Enter로 클립보드 복사", null, $"CPU: {processorCount}코어, 프로세스 {value}개, 스레드 {value2:N0}개", null, "\ue950"));
		}
		if (flag || text.Contains("mem") || text.Contains("ram") || text.Contains("메모리"))
		{
			MEMORYSTATUSEX lpBuffer = new MEMORYSTATUSEX
			{
				dwLength = (uint)Marshal.SizeOf<MEMORYSTATUSEX>()
			};
			GlobalMemoryStatusEx(ref lpBuffer);
			double value3 = (double)lpBuffer.ullTotalPhys / 1073741824.0;
			double value4 = (double)(lpBuffer.ullTotalPhys - lpBuffer.ullAvailPhys) / 1073741824.0;
			uint dwMemoryLoad = lpBuffer.dwMemoryLoad;
			list.Add(new LauncherItem($"메모리: {value4:F1}GB / {value3:F1}GB ({dwMemoryLoad}% 사용)", $"사용 가능: {(double)lpBuffer.ullAvailPhys / 1073741824.0:F1}GB  ·  Enter로 복사", null, $"메모리: {value4:F1}GB / {value3:F1}GB ({dwMemoryLoad}% 사용)", null, "\ue950"));
		}
		if (flag || text.Contains("disk") || text.Contains("디스크") || text.Contains("저장"))
		{
			DriveInfo[] drives = DriveInfo.GetDrives();
			foreach (DriveInfo driveInfo in drives)
			{
				if (driveInfo.IsReady && driveInfo.DriveType == DriveType.Fixed)
				{
					double num2 = (double)driveInfo.TotalSize / 1073741824.0;
					double num3 = (double)driveInfo.AvailableFreeSpace / 1073741824.0;
					double num4 = num2 - num3;
					int value5 = (int)(num4 / num2 * 100.0);
					list.Add(new LauncherItem($"디스크 {driveInfo.Name.TrimEnd('\\')}  {num4:F0}GB / {num2:F0}GB ({value5}%)", $"여유: {num3:F1}GB  ·  {driveInfo.DriveFormat}  ·  Enter로 복사", null, $"디스크 {driveInfo.Name}: {num4:F0}GB / {num2:F0}GB ({value5}%), 여유 {num3:F1}GB", null, "\ueda2"));
				}
			}
		}
		if (flag || text.Contains("uptime") || text.Contains("가동"))
		{
			TimeSpan timeSpan = TimeSpan.FromMilliseconds(Environment.TickCount64);
			string text2 = ((timeSpan.Days > 0) ? $"{timeSpan.Days}일 {timeSpan.Hours}시간 {timeSpan.Minutes}분" : $"{timeSpan.Hours}시간 {timeSpan.Minutes}분");
			list.Add(new LauncherItem("가동 시간: " + text2, "마지막 재시작 이후 경과  ·  Enter로 복사", null, "가동 시간: " + text2, null, "\ue823"));
		}
		if (flag || text.Contains("top") || text.Contains("프로세스"))
		{
			try
			{
				IEnumerable<string> values = Process.GetProcesses().Where(delegate(Process p)
				{
					try
					{
						return p.WorkingSet64 > 0;
					}
					catch
					{
						return false;
					}
				}).OrderByDescending(delegate(Process p)
				{
					try
					{
						return p.WorkingSet64;
					}
					catch
					{
						return 0L;
					}
				})
					.Take(5)
					.Select(delegate(Process p)
					{
						try
						{
							return $"{p.ProcessName} ({p.WorkingSet64 / 1048576}MB)";
						}
						catch
						{
							return p.ProcessName;
						}
					});
				list.Add(new LauncherItem("메모리 상위 프로세스", string.Join(", ", values), null, "메모리 상위: " + string.Join(", ", values), null, "\ue7f4"));
			}
			catch
			{
			}
		}
		if (list.Count == 0)
		{
			list.Add(new LauncherItem("'" + text + "'에 해당하는 리소스 항목 없음", "cpu / mem / disk / uptime / top", null, null, null, "\ue7ba"));
		}
		return Task.FromResult((IEnumerable<LauncherItem>)list);
	}

	public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
	{
		object data = item.Data;
		string text = data as string;
		if (text != null && !string.IsNullOrWhiteSpace(text))
		{
			try
			{
				Application current = Application.Current;
				if (current != null)
				{
					((DispatcherObject)current).Dispatcher.Invoke((Action)delegate
					{
						Clipboard.SetText(text);
					});
				}
			}
			catch
			{
			}
		}
		return Task.CompletedTask;
	}
}
