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

namespace ClaudeDo.Ui.ViewModels.Modals;

public sealed partial class MergeModalViewModel : ViewModelBase
{
    private readonly WorkerClient _worker;

    public string TaskId { get; set; } = "";
    public string TaskTitle { get; set; } = "";

    public ObservableCollection<string> Branches { get; } = new();

    [ObservableProperty] private string? _selectedBranch;
    [ObservableProperty] private bool _removeWorktree = true;
    [ObservableProperty] private string _commitMessage = "";

    [ObservableProperty] private bool _isBusy;
    [ObservableProperty] private string? _errorMessage;
    [ObservableProperty] private string? _warningMessage;
    [ObservableProperty] private string? _successMessage;
    [ObservableProperty] private bool _hasConflict;
    [ObservableProperty] private IReadOnlyList<string> _conflictFiles = Array.Empty<string>();

    public Action? CloseAction { get; set; }

    public MergeModalViewModel(WorkerClient worker)
    {
        _worker = worker;
    }

    public async Task InitializeAsync(string taskId, string taskTitle)
    {
        TaskId = taskId;
        TaskTitle = taskTitle;
        CommitMessage = $"Merge task: {taskTitle}";

        IsBusy = true;
        try
        {
            var targets = await _worker.GetMergeTargetsAsync(taskId);
            Branches.Clear();
            if (targets is null)
            {
                ErrorMessage = "Worker offline — cannot list branches.";
                return;
            }
            foreach (var b in targets.LocalBranches) Branches.Add(b);
            SelectedBranch = Branches.Contains(targets.DefaultBranch)
                ? targets.DefaultBranch
                : Branches.FirstOrDefault();
        }
        catch (Exception ex)
        {
            ErrorMessage = $"Failed to load branches: {ex.Message}";
        }
        finally { IsBusy = false; }
    }

    private bool CanSubmit() =>
        !IsBusy && !HasConflict && !string.IsNullOrWhiteSpace(SelectedBranch);

    [RelayCommand(CanExecute = nameof(CanSubmit))]
    private async Task SubmitAsync()
    {
        if (string.IsNullOrWhiteSpace(SelectedBranch)) return;
        IsBusy = true;
        ErrorMessage = null;
        WarningMessage = null;
        SuccessMessage = null;
        try
        {
            var result = await _worker.MergeTaskAsync(
                TaskId, SelectedBranch!, RemoveWorktree, CommitMessage);

            switch (result.Status)
            {
                case "merged":
                    SuccessMessage = result.ErrorMessage is not null
                        ? $"Merged with warning: {result.ErrorMessage}"
                        : "Merged.";
                    // Auto-close after a short delay.
                    _ = Task.Run(async () =>
                    {
                        await Task.Delay(1200);
                        Avalonia.Threading.Dispatcher.UIThread.Post(() => CloseAction?.Invoke());
                    });
                    break;
                case "conflict":
                    HasConflict = true;
                    ConflictFiles = result.ConflictFiles;
                    ErrorMessage = "Merge conflict — target branch restored. Resolve manually or via Continue, then retry.";
                    break;
                case "blocked":
                    ErrorMessage = $"Blocked: {result.ErrorMessage}";
                    break;
                default:
                    ErrorMessage = $"Unknown status: {result.Status}";
                    break;
            }
        }
        catch (Exception ex)
        {
            ErrorMessage = $"Merge failed: {ex.Message}";
        }
        finally
        {
            IsBusy = false;
        }
    }

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