using System.Windows.Input;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Input;

namespace ClaudeDo.Ui.Views.Controls;

/// <summary>Reusable modal chrome: titlebar (drag + close) wrapping a body and optional footer.</summary>
public class ModalShell : ContentControl
{
    public static readonly StyledProperty<string?> TitleProperty =
        AvaloniaProperty.Register<ModalShell, string?>(nameof(Title));

    public static readonly StyledProperty<object?> FooterProperty =
        AvaloniaProperty.Register<ModalShell, object?>(nameof(Footer));

    public static readonly StyledProperty<ICommand?> CloseCommandProperty =
        AvaloniaProperty.Register<ModalShell, ICommand?>(nameof(CloseCommand));

    public string? Title { get => GetValue(TitleProperty); set => SetValue(TitleProperty, value); }
    public object? Footer { get => GetValue(FooterProperty); set => SetValue(FooterProperty, value); }
    public ICommand? CloseCommand { get => GetValue(CloseCommandProperty); set => SetValue(CloseCommandProperty, value); }

    private Window? _window;
    private PixelPoint _dragStartScreen;
    private PixelPoint _dragStartPos;
    private bool _dragging;

    protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
    {
        base.OnApplyTemplate(e);
        if (e.NameScope.Find<Border>("PART_TitleBar") is { } bar)
        {
            bar.PointerPressed += OnTitleBarPressed;
            bar.PointerMoved += OnTitleBarMoved;
            bar.PointerReleased += OnTitleBarReleased;
        }
    }

    // VisualRoot is a TopLevelHost (not the Window) in Avalonia 12, so resolve the
    // owning Window via TopLevel.GetTopLevel and drive the move manually — BeginMoveDrag
    // and a VisualRoot-as-Window cast both fail here.
    private void OnTitleBarPressed(object? sender, PointerPressedEventArgs e)
    {
        if (!e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) return;
        _window = TopLevel.GetTopLevel(this) as Window;
        if (_window is null) return;
        _dragStartScreen = _window.PointToScreen(e.GetPosition(_window));
        _dragStartPos = _window.Position;
        _dragging = true;
        e.Pointer.Capture(sender as IInputElement);
    }

    private void OnTitleBarMoved(object? sender, PointerEventArgs e)
    {
        if (!_dragging || _window is null
            || !e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) return;
        var cur = _window.PointToScreen(e.GetPosition(_window));
        _window.Position = new PixelPoint(
            _dragStartPos.X + (cur.X - _dragStartScreen.X),
            _dragStartPos.Y + (cur.Y - _dragStartScreen.Y));
    }

    private void OnTitleBarReleased(object? sender, PointerReleasedEventArgs e)
    {
        _dragging = false;
        e.Pointer.Capture(null);
    }
}
