using System.Drawing;
using Gdk;
using Gtk;
using KioskApp.Portal.Platforms.Events;
using KioskApp.Portal.Platforms.Windows;
using Widget = KioskApp.Portal.Widgets.Widget;

namespace KioskApp.Portal.Platforms.Linux;

public class LinuxWindow : Window
{
    public override event EventHandler<WindowClosingEventArgs> Closing;

    private Gtk.Window _nativeWindow;
    
    public LinuxWindow(WindowOptions options) : base(options)
    {
        InternalCreate();   
    }
    
    protected sealed override void InternalCreate()
    {
        Application.Init();
        _nativeWindow = new Gtk.Window(Title);
        _nativeWindow.SetDefaultSize(Width, Height);
        _nativeWindow.DeleteEvent += NativeWindowOnDeleteEvent;
        _nativeWindow.SizeAllocated += (_, _) => InternalResize(_nativeWindow.Allocation.Width, _nativeWindow.Allocation.Height);
    }

    private void NativeWindowOnDeleteEvent(object o, DeleteEventArgs args)
    {
        args.RetVal = !Close();
    }

    protected override void InternalResize(int width, int height)
    {
        Width = width;
        Height = height;
        
        var clientSize = GetClientSize();
        
        var widgets = GetWidgets();
        foreach (var widget in widgets)
        {
            widget.Resize((int)clientSize.Width, (int)clientSize.Height);
        }
    }

    protected override bool Close()
    {
        return false;
        
        var args = new WindowClosingEventArgs();
        Closing?.Invoke(this, args);
        if (args.Cancel) return false;
        
        // Dispose all widgets
        var widgets = GetWidgets();
        foreach (var widget in widgets)
        {
            widget.Dispose();
        }
        
        // TODO: We only need to call it when the last window is closed
        Application.Quit();
        return true;
    }

    public override void Show()
    {
        _nativeWindow.ShowAll();
        
        Application.Run();
    }

    public override T GetNativeWindow<T>()
    {
        return (_nativeWindow as T)!;
    }

    public override IntPtr GetNativeHandle()
    {
        return _nativeWindow.Handle;
    }

    public override SizeF GetClientSize()
    {
        // Get the allocation of the window
        var allocation = _nativeWindow.Allocation;

        // If you have a Container as the direct child of the window (e.g., VBox, HBox),
        // you might want to use its allocation instead for more accurate client area
        if (_nativeWindow.Child is Container container)
        {
            allocation = container.Allocation;
        }

        return new SizeF(allocation.Width, allocation.Height);
    }

    public override void Fullscreen()
    {
        _nativeWindow.KeepAbove = true;
        _nativeWindow.Fullscreen();
    }
}