using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Interop;
using PSLauncher.App.ViewModels;
using PSLauncher.Core.Localization;

namespace PSLauncher.App.Views;

public partial class MainWindow : Window
{
    private static readonly int WM_PSLAUNCHER_BRING = RegisterWindowMessage("PSLAUNCHER_BRING_TO_FRONT");

    [DllImport("user32.dll")]
    private static extern int RegisterWindowMessage(string lpString);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    private const int SW_RESTORE = 9;

    public MainWindow()
    {
        InitializeComponent();
        SourceInitialized += MainWindow_SourceInitialized;
        Closing += MainWindow_Closing;
    }

    /// <summary>
    /// Si un DL est en cours, demande confirmation avant de fermer le launcher.
    /// La progression est de toute façon préservée pour reprise au prochain lancement,
    /// mais on évite à l'utilisateur de cliquer ✕ par accident en plein milieu d'un 14 Go.
    /// </summary>
    private void MainWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
    {
        if (DataContext is MainViewModel vm && vm.HasActiveDownload)
        {
            var version = vm.ActiveDownloadVersion ?? "?";
            var result = ThemedMessageBox.Show(
                Strings.MsgQuitWhileDownloadingConfirm(version),
                Strings.MsgBoxQuit,
                MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);
            if (result != MessageBoxResult.Yes) e.Cancel = true;
        }
    }

    /// <summary>
    /// Hook le pump de messages Windows pour réagir au broadcast envoyé par une
    /// seconde instance qui veut nous mettre au premier plan.
    /// </summary>
    private void MainWindow_SourceInitialized(object? sender, EventArgs e)
    {
        var helper = new WindowInteropHelper(this);
        var source = HwndSource.FromHwnd(helper.Handle);
        source?.AddHook(WndProc);
    }

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg == WM_PSLAUNCHER_BRING)
        {
            if (WindowState == WindowState.Minimized)
                WindowState = WindowState.Normal;
            else
                ShowWindow(hwnd, SW_RESTORE);
            Activate();
            SetForegroundWindow(hwnd);
            handled = true;
        }
        return IntPtr.Zero;
    }

    /// <summary>
    /// Le bouton "..." ouvre son ContextMenu sur clic gauche.
    /// </summary>
    private void OnMoreMenuClick(object sender, RoutedEventArgs e)
    {
        if (sender is Button btn && btn.ContextMenu is { } menu)
        {
            menu.PlacementTarget = btn;
            menu.Placement = PlacementMode.Bottom;
            menu.IsOpen = true;
        }
    }

    private void OnMinimizeClick(object sender, RoutedEventArgs e)
    {
        WindowState = WindowState.Minimized;
    }

    private void OnMaxRestoreClick(object sender, RoutedEventArgs e)
    {
        WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
    }

    private void OnCloseClick(object sender, RoutedEventArgs e)
    {
        Close();
    }
}
