using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using ClaudeDo.Ui.Services;

namespace ClaudeDo.Ui.ViewModels.Planning;

public sealed partial class PlanningDiffViewModel : ObservableObject
{
    private readonly IWorkerClient _worker;
    private readonly string _planningTaskId;
    private readonly string _targetBranch;

    public ObservableCollection<SubtaskDiffRow> Subtasks { get; } = new();

    [ObservableProperty] private SubtaskDiffRow? _selectedSubtask;
    [ObservableProperty] private string _displayedDiff = "";
    [ObservableProperty] private bool _isCombinedMode;
    [ObservableProperty] private string? _combinedWarning;
    [ObservableProperty] private bool _isLoadingCombined;

    public Action? CloseAction { get; set; }

    public PlanningDiffViewModel(IWorkerClient worker, string planningTaskId, string targetBranch)
    {
        _worker = worker;
        _planningTaskId = planningTaskId;
        _targetBranch = targetBranch;
    }

    [RelayCommand]
    private void Close() => CloseAction?.Invoke();

    public async Task InitializeAsync()
    {
        var items = await _worker.GetPlanningAggregateAsync(_planningTaskId);
        Subtasks.Clear();
        foreach (var i in items)
            Subtasks.Add(new SubtaskDiffRow(i.SubtaskId, i.Title, i.DiffStat, i.UnifiedDiff));
        SelectedSubtask = Subtasks.FirstOrDefault();
    }

    partial void OnSelectedSubtaskChanged(SubtaskDiffRow? value)
    {
        if (!IsCombinedMode)
            DisplayedDiff = value?.UnifiedDiff ?? "";
    }

    [RelayCommand]
    private async Task ToggleCombinedAsync()
    {
        if (IsCombinedMode)
        {
            IsLoadingCombined = true;
            try
            {
                var result = await _worker.BuildPlanningIntegrationBranchAsync(_planningTaskId, _targetBranch);

                if (result is null)
                {
                    DisplayedDiff = "";
                    CombinedWarning = "Could not build combined preview (hub error).";
                }
                else if (result.Success)
                {
                    DisplayedDiff = result.UnifiedDiff ?? "";
                    CombinedWarning = null;
                }
                else
                {
                    var files = result.ConflictedFiles?.Count ?? 0;
                    CombinedWarning = $"Cannot build combined preview: subtask {result.FirstConflictSubtaskId} conflicts with an earlier subtask ({files} files).";
                    DisplayedDiff = "";
                }
            }
            finally
            {
                IsLoadingCombined = false;
            }
        }
        else
        {
            DisplayedDiff = SelectedSubtask?.UnifiedDiff ?? "";
            CombinedWarning = null;
        }
    }

    partial void OnIsCombinedModeChanged(bool value) => ToggleCombinedCommand.Execute(null);
}

public sealed record SubtaskDiffRow(string Id, string Title, string? DiffStat, string UnifiedDiff);
