using ClaudeDo.Ui.ViewModels.Modals;

namespace ClaudeDo.Ui.Tests.ViewModels;

public class WeeklyReportModalViewModelTests
{
    private sealed class Worker : StubWorkerClient
    {
        public TaskCompletionSource<string> Gate { get; } = new();
        public bool Throw { get; set; }

        public override Task<string> GenerateWeekReportAsync(DateOnly start, DateOnly end) =>
            Throw ? Task.FromException<string>(new InvalidOperationException("boom")) : Gate.Task;
    }

    private static WeeklyReportModalViewModel Build(Worker worker)
    {
        var vm = new WeeklyReportModalViewModel(worker)
        {
            StartDate = new DateTime(2026, 6, 1),
            EndDate = new DateTime(2026, 6, 3),
        };
        return vm;
    }

    [Fact]
    public async Task Generate_sets_IsRunning_while_pending_and_clears_it_after()
    {
        var worker = new Worker();
        var vm = Build(worker);

        var generate = vm.GenerateCommand.ExecuteAsync(null);

        Assert.True(vm.GenerateOperation.IsRunning);

        worker.Gate.SetResult("# report");
        await generate;

        Assert.False(vm.GenerateOperation.IsRunning);
        Assert.Equal("# report", vm.ReportMarkdown);
    }

    [Fact]
    public async Task GenerateCommand_CanExecute_is_locked_while_running()
    {
        var worker = new Worker();
        var vm = Build(worker);

        var generate = vm.GenerateCommand.ExecuteAsync(null);
        Assert.False(vm.GenerateCommand.CanExecute(null));

        worker.Gate.SetResult("# report");
        await generate;

        Assert.True(vm.GenerateCommand.CanExecute(null));
    }

    [Fact]
    public async Task Generate_ends_the_operation_when_the_worker_call_throws()
    {
        var worker = new Worker { Throw = true };
        var vm = Build(worker);

        await vm.GenerateCommand.ExecuteAsync(null);

        Assert.False(vm.GenerateOperation.IsRunning);
        Assert.True(vm.GenerateCommand.CanExecute(null));
        Assert.False(string.IsNullOrWhiteSpace(vm.StatusMessage));
    }
}
