using ClaudeDo.Ui.Services;
using ClaudeDo.Ui.ViewModels.Modals.Settings;

namespace ClaudeDo.Ui.Tests.ViewModels;

public class PrimeClaudeTabViewModelTests
{
    private sealed class FakeApi : IPrimeScheduleApi
    {
        public List<PrimeScheduleDto> Stored { get; } = new();
        public List<PrimeScheduleDto> Upserts { get; } = new();
        public List<Guid> Deletes { get; } = new();
        public Task<List<PrimeScheduleDto>> ListAsync() => Task.FromResult(Stored.ToList());
        public Task<PrimeScheduleDto?> UpsertAsync(PrimeScheduleDto dto)
        {
            Upserts.Add(dto);
            return Task.FromResult<PrimeScheduleDto?>(dto);
        }
        public Task DeleteAsync(Guid id) { Deletes.Add(id); return Task.CompletedTask; }
    }

    [Fact]
    public async Task Load_Populates_Rows()
    {
        var api = new FakeApi();
        api.Stored.Add(new PrimeScheduleDto(
            Guid.NewGuid(), new DateOnly(2026,5,1), new DateOnly(2026,5,31),
            new TimeSpan(7,0,0), true, true, null, null));
        var vm = new PrimeClaudeTabViewModel(api);
        await vm.LoadAsync();
        Assert.Single(vm.Rows);
    }

    [Fact]
    public void AddSchedule_Appends_Row_With_Defaults()
    {
        var vm = new PrimeClaudeTabViewModel(new FakeApi());
        vm.AddScheduleCommand.Execute(null);
        Assert.Single(vm.Rows);
        Assert.True(vm.Rows[0].Enabled);
        Assert.True(vm.Rows[0].WorkdaysOnly);
        Assert.Equal(new TimeSpan(7,0,0), vm.Rows[0].TimeOfDay);
    }

    [Fact]
    public async Task Save_Diffs_New_And_Removed_Rows()
    {
        var api = new FakeApi();
        var keptId = Guid.NewGuid();
        var deletedId = Guid.NewGuid();
        api.Stored.Add(new PrimeScheduleDto(keptId, new(2026,5,1), new(2026,5,31), new(7,0,0), true, true, null, null));
        api.Stored.Add(new PrimeScheduleDto(deletedId, new(2026,5,1), new(2026,5,31), new(8,0,0), true, true, null, null));

        var vm = new PrimeClaudeTabViewModel(api);
        await vm.LoadAsync();
        vm.RemoveScheduleCommand.Execute(vm.Rows.Single(r => r.Id == deletedId));
        vm.AddScheduleCommand.Execute(null);

        await vm.SaveAsync();

        Assert.Contains(deletedId, api.Deletes);
        Assert.Equal(2, api.Upserts.Count);
    }

    [Fact]
    public void Validate_Reports_StartAfterEnd()
    {
        var vm = new PrimeClaudeTabViewModel(new FakeApi());
        vm.AddScheduleCommand.Execute(null);
        vm.Rows[0].StartDate = new DateOnly(2026, 6, 1);
        vm.Rows[0].EndDate = new DateOnly(2026, 5, 1);
        Assert.NotNull(vm.Validate());
    }
}
