using Microsoft.Extensions.DependencyInjection;
using System;
using System.IO;
using TodoList.Maui.Services;
using TodoList.Maui.Views;
using TodoList.Maui.Models;
#if WINDOWS
using System.Runtime.InteropServices;
using Windowing = Microsoft.UI.Windowing;
using WinUiWindow = Microsoft.UI.Xaml.Window;
using WinRT.Interop;
#endif

namespace TodoList.Maui;

public partial class App : global::Microsoft.Maui.Controls.Application
{
	private readonly IHotKeySettingsService _settingsService;
	private readonly IGlobalHotKeyService _hotKeyService;
	private readonly ISystemTrayService _trayService;
	private Window? _mainWindow;
	private bool _isHotkeyRegistered;
	private bool _isWindowCentered;

	public App(IServiceProvider serviceProvider)
	{
		InitializeComponent();

		_settingsService = serviceProvider.GetRequiredService<IHotKeySettingsService>();
		_hotKeyService = serviceProvider.GetRequiredService<IGlobalHotKeyService>();
		_trayService = serviceProvider.GetRequiredService<ISystemTrayService>();
	}

protected override Microsoft.Maui.Controls.Window CreateWindow(IActivationState? activationState)
	{
		_mainWindow = new Microsoft.Maui.Controls.Window(new MainPage())
		{
			Width = 450,
			Height = 640,
			Title = AppMetadata.GetWindowTitle()
		};

#if WINDOWS
		_mainWindow.TitleBar = CreateWindowTitleBar();
#endif

		_mainWindow.Destroying += (s, e) =>
		{
			if (_isHotkeyRegistered)
			{
				_hotKeyService.UnregisterHotKey();
				_isHotkeyRegistered = false;
			}
			_trayService.Dispose();
		};

		_mainWindow.Created += (s, e) =>
		{
			_trayService.Initialize(_mainWindow, ShowMainWindow, ExitApplication);
			RegisterHotkeyWhenReady();

#if WINDOWS
			MainThread.BeginInvokeOnMainThread(() =>
			{
				if (_mainWindow.Handler?.PlatformView is WinUiWindow platformWindow)
				{
					// Ensure app doesn't shutdown when main window closes (we hide it)
					platformWindow.AppWindow.Closing += (sender, args) =>
					{
						args.Cancel = true;
						new TodoList.Maui.Platforms.Windows.WindowsWindowService().HideWindow(_mainWindow);
					};

					CenterMainWindow(platformWindow);
					ConfigureWindowsTitleBar(platformWindow);
				}
			});
#endif
		};

		return _mainWindow;
	}

	private void RegisterHotkeyWhenReady(int attempt = 0)
	{
		if (_mainWindow == null) return;

#if WINDOWS
		if (_mainWindow.Handler?.PlatformView is not Window)
		{
			if (attempt < 30)
			{
				_mainWindow.Dispatcher.DispatchDelayed(TimeSpan.FromMilliseconds(100), () => RegisterHotkeyWhenReady(attempt + 1));
			}
			return;
		}
#endif

		RegisterHotkey();
	}

	private void OnHotKeyPressed()
	{
		MainThread.BeginInvokeOnMainThread(() =>
		{
			ShowMainWindow();
		});
	}

	private void ShowMainWindow()
	{
		if (_mainWindow != null)
		{
			_mainWindow.Dispatcher.Dispatch(() =>
		{
#if WINDOWS
			if (_mainWindow.Handler != null)
			{
				new TodoList.Maui.Platforms.Windows.WindowsWindowService().RestoreWindow(_mainWindow);
				var platformWindow = _mainWindow.Handler.PlatformView as WinUiWindow;
				platformWindow?.Activate();
			}
#else
			if (global::Application.Current != null &&
				!global::Application.Current.Windows.Contains(_mainWindow))
			{
				global::Application.Current.OpenWindow(_mainWindow);
			}
#endif
		});
		}
	}

	private void ExitApplication()
	{
		_trayService?.Dispose();
		global::Microsoft.Maui.Controls.Application.Current?.Quit();
	}

	private void RegisterHotkey()
	{
		if (_hotKeyService == null || _settingsService == null) return;

		var config = _settingsService.GetConfig();
		if (_hotKeyService.IsSupported && config.IsEnabled)
		{
			_hotKeyService.RegisterHotKey(config.Modifiers, config.Key, OnHotKeyPressed);
			_isHotkeyRegistered = true;

			config.PropertyChanged += (s, args) =>
			{
				if (args.PropertyName == nameof(HotKeyConfig.Modifiers) ||
					args.PropertyName == nameof(HotKeyConfig.Key) ||
					args.PropertyName == nameof(HotKeyConfig.IsEnabled))
				{
					if (config.IsEnabled && _hotKeyService.IsSupported)
					{
						_hotKeyService.UpdateHotKey(config.Modifiers, config.Key);
					}
					else
					{
						_hotKeyService.UnregisterHotKey();
						_isHotkeyRegistered = false;
					}
				}
			};
		}
	}

#if WINDOWS
	private void ConfigureWindowsTitleBar(WinUiWindow platformWindow)
	{
		var title = AppMetadata.GetWindowTitle();

		platformWindow.Title = title;
		if (_mainWindow != null)
		{
			_mainWindow.Title = title;
		}

		var appWindow = platformWindow.AppWindow;
		if (appWindow != null)
		{
			appWindow.Title = title;

			var hWnd = WindowNative.GetWindowHandle(platformWindow);
			if (hWnd != IntPtr.Zero)
			{
				SetWindowText(hWnd, title);
			}

			var iconPath = Path.Combine(AppContext.BaseDirectory, "icon.ico");
			if (File.Exists(iconPath))
			{
				appWindow.SetIcon(iconPath);
			}

            var titleBar = appWindow.TitleBar;
			titleBar.IconShowOptions = Windowing.IconShowOptions.ShowIconAndSystemMenu;

			titleBar.BackgroundColor = Microsoft.UI.Colors.Transparent;
			titleBar.InactiveBackgroundColor = Microsoft.UI.Colors.Transparent;
			titleBar.ButtonBackgroundColor = Microsoft.UI.Colors.Transparent;
			titleBar.ButtonInactiveBackgroundColor = Microsoft.UI.Colors.Transparent;
			titleBar.ButtonHoverBackgroundColor = Microsoft.UI.Colors.Transparent;
			titleBar.ButtonPressedBackgroundColor = Microsoft.UI.Colors.Transparent;
			titleBar.ButtonForegroundColor = Microsoft.UI.Colors.Black;
			titleBar.ButtonInactiveForegroundColor = Microsoft.UI.Colors.Black;
			titleBar.ButtonHoverForegroundColor = Microsoft.UI.Colors.Black;
			titleBar.ButtonPressedForegroundColor = Microsoft.UI.Colors.Black;
		}
	}

	[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "SetWindowTextW")]
	private static extern bool SetWindowText(IntPtr hWnd, string lpString);

	private static TitleBar CreateWindowTitleBar()
	{
		return new TitleBar
		{
			BackgroundColor = Microsoft.Maui.Graphics.Color.FromArgb("#F5F5F5"),
			Icon = string.Empty,
			Title = string.Empty,
			ForegroundColor = Microsoft.Maui.Graphics.Color.FromArgb("#333333"),
			LeadingContent = new HorizontalStackLayout
			{
				Spacing = 4,
				Padding = new Microsoft.Maui.Thickness(10, 0, 0, 0),
				VerticalOptions = LayoutOptions.Center,
				Children =
				{
					new Image
					{
						Source = "icon.jpg",
						WidthRequest = 22,
						HeightRequest = 22,
						VerticalOptions = LayoutOptions.Center
					},
					new Label
					{
						Text = AppMetadata.GetTitleBarVersionText(),
						FontFamily = "Microsoft YaHei UI",
						TextColor = Microsoft.Maui.Graphics.Color.FromArgb("#333333"),
						VerticalTextAlignment = Microsoft.Maui.TextAlignment.Center,
						VerticalOptions = LayoutOptions.Center,
						FontSize = 14
					}
				}
			}
		};
	}

	private void CenterMainWindow(WinUiWindow platformWindow)
	{
		if (_isWindowCentered) return;

		var appWindow = platformWindow.AppWindow;
		if (appWindow == null) return;

		var displayArea = Windowing.DisplayArea.GetFromWindowId(
			appWindow.Id,
			Windowing.DisplayAreaFallback.Primary);

		var workArea = displayArea.WorkArea;

		var windowWidthPx = appWindow.Size.Width;
		var windowHeightPx = appWindow.Size.Height;

		if (windowWidthPx <= 0 || windowHeightPx <= 0)
		{
			var scale = platformWindow.Content?.XamlRoot?.RasterizationScale ?? 1.0;
			windowWidthPx = windowWidthPx <= 0 ? (int)Math.Round((_mainWindow?.Width ?? 450) * scale) : windowWidthPx;
			windowHeightPx = windowHeightPx <= 0 ? (int)Math.Round((_mainWindow?.Height ?? 640) * scale) : windowHeightPx;
		}

		if (windowWidthPx <= 0 || windowHeightPx <= 0) return;

		var x = workArea.X + (workArea.Width - windowWidthPx) / 2;
		var y = workArea.Y + (workArea.Height - windowHeightPx) / 2;

		if (windowWidthPx >= workArea.Width) x = workArea.X;
		if (windowHeightPx >= workArea.Height) y = workArea.Y;

		x = Math.Max(workArea.X, Math.Min(x, workArea.X + workArea.Width - windowWidthPx));
		y = Math.Max(workArea.Y, Math.Min(y, workArea.Y + workArea.Height - windowHeightPx));

		appWindow.Move(new Windows.Graphics.PointInt32(x, y));
		_isWindowCentered = true;
	}
#endif
}
