using System.Linq;
using Avalonia;
using Avalonia.Animation;
using Avalonia.Animation.Easings;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.Styling;
using Avalonia.VisualTree;
using ClaudeDo.Data.Models;
using ClaudeDo.Ui.ViewModels.Islands;
using TaskStatus = ClaudeDo.Data.Models.TaskStatus;

namespace ClaudeDo.Ui.Views.Islands;

public partial class TaskRowView : UserControl
{
    private TaskRowViewModel? _pendingScheduleRow;

    public TaskRowView() { InitializeComponent(); }

    private TasksIslandViewModel? FindTasksVm() =>
        this.GetVisualAncestors().OfType<ItemsControl>()
            .Select(ic => ic.DataContext).OfType<TasksIslandViewModel>().FirstOrDefault();

    private async void OnSendToQueueClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)
            await vm.SendToQueueCommand.ExecuteAsync(row);
    }

    private async void OnRemoveFromQueueClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)
            await vm.RemoveFromQueueCommand.ExecuteAsync(row);
    }

    private async void OnCancelExecutionClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)
            await vm.CancelRunningTaskCommand.ExecuteAsync(row);
    }

    private async void OnClearScheduleClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)
            await vm.ClearScheduleCommand.ExecuteAsync(row);
    }

    private async void OnAddToMyDayClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)
            await vm.AddToMyDayCommand.ExecuteAsync(row);
    }

    private async void OnRemoveFromMyDayClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)
            await vm.RemoveFromMyDayCommand.ExecuteAsync(row);
    }

    private async void OnOpenPlanningSessionClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)
            await vm.OpenPlanningSessionCommand.ExecuteAsync(row);
    }

    private async void OnRunInteractivelyClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)
            await vm.RunInteractivelyCommand.ExecuteAsync(row);
    }

    private async void OnResumePlanningSessionClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)
            await vm.ResumePlanningSessionCommand.ExecuteAsync(row);
    }

    private async void OnDiscardPlanningSessionClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)
            await vm.DiscardPlanningSessionCommand.ExecuteAsync(row);
    }

    private async void OnFinalizePlanningSessionClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is TaskRowViewModel row && FindTasksVm() is { } vm)
            await vm.FinalizePlanningSessionCommand.ExecuteAsync(row);
    }

    private async void OnSetStatusClick(object? sender, RoutedEventArgs e)
    {
        if (sender is not MenuItem mi) return;
        if (DataContext is not TaskRowViewModel row) return;
        if (FindTasksVm() is not { } vm) return;
        if (mi.Tag is not string tag) return;
        if (!System.Enum.TryParse<TaskStatus>(tag, ignoreCase: true, out var status)) return;
        await vm.SetStatusOnRowAsync(row, status);
    }

    private void OnScheduleForClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is not TaskRowViewModel row) return;
        _pendingScheduleRow = row;
        ScheduleDate.SelectedDate = row.ScheduledFor ?? DateTime.Now.AddHours(1);
        ScheduleAnchor.Flyout?.ShowAt(ScheduleAnchor);
    }

    private async void OnScheduleSetClick(object? sender, RoutedEventArgs e)
    {
        ScheduleAnchor.Flyout?.Hide();
        if (_pendingScheduleRow is null || ScheduleDate.SelectedDate is null) return;
        var when = ScheduleDate.SelectedDate.Value;
        if (FindTasksVm() is { } tvm)
            await tvm.SetScheduledForAsync(_pendingScheduleRow, when);
        _pendingScheduleRow = null;
    }

    private void OnScheduleCancelClick(object? sender, RoutedEventArgs e)
    {
        ScheduleAnchor.Flyout?.Hide();
        _pendingScheduleRow = null;
    }

    protected override async void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
    {
        base.OnAttachedToVisualTree(e);
        RenderTransform = new TranslateTransform(0, 8);
        Opacity = 0;
        var anim = new Avalonia.Animation.Animation
        {
            Duration = TimeSpan.FromMilliseconds(300),
            Easing = new CubicEaseOut(),
            Children =
            {
                new KeyFrame { Cue = new Cue(0), Setters = { new Setter(OpacityProperty, 0d) } },
                new KeyFrame { Cue = new Cue(1), Setters = { new Setter(OpacityProperty, 1d) } },
            }
        };
        await anim.RunAsync(this);
        Opacity = 1;
        RenderTransform = null;
    }
}
