using System.Collections.ObjectModel; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using ClaudeDo.Ui.Localization; 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 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 = Loc.T("vm.planningDiff.hubError"); } else if (result.Success) { DisplayedDiff = result.UnifiedDiff ?? ""; CombinedWarning = null; } else { var files = result.ConflictedFiles?.Count ?? 0; CombinedWarning = Loc.T("vm.planningDiff.conflict", result.FirstConflictSubtaskId ?? "", 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);