using System.IO;
using ClaudeDo.Localization;
using ClaudeDo.Ui.Localization;
using ClaudeDo.Ui.Services;
using ClaudeDo.Ui.ViewModels.Modals.Settings;

namespace ClaudeDo.Ui.Tests.ViewModels;

public class WorktreesSettingsTabViewModelTests
{
    public WorktreesSettingsTabViewModelTests()
    {
        var dir = AppContext.BaseDirectory;
        while (dir is not null && !Directory.Exists(Path.Combine(dir, "src", "ClaudeDo.Localization", "locales")))
            dir = Path.GetDirectoryName(dir);
        Loc.Current = new Localizer(
            LocaleStore.Load(Path.Combine(dir!, "src", "ClaudeDo.Localization", "locales")), "en");
    }

    private sealed class ThrowingWorker : StubWorkerClient
    {
        public string ExceptionMessage { get; init; } = "disk full";
        public override Task<WorktreeCleanupDto?> CleanupFinishedWorktreesAsync(string? listId = null) =>
            throw new Exception(ExceptionMessage);
        public override Task<WorktreeResetDto?> ResetAllWorktreesAsync() =>
            throw new Exception(ExceptionMessage);
    }

    private sealed class CountingWorker : StubWorkerClient
    {
        public int ResetCallCount;
        public override Task<WorktreeResetDto?> ResetAllWorktreesAsync()
        {
            ResetCallCount++;
            return Task.FromResult<WorktreeResetDto?>(new WorktreeResetDto(0, 0, false, 0));
        }
    }

    [Fact]
    public async Task CleanupWorktrees_WhenWorkerThrows_ShowsExceptionMessage()
    {
        var worker = new ThrowingWorker();
        var vm = new WorktreesSettingsTabViewModel(worker);

        await vm.CleanupWorktreesCommand.ExecuteAsync(null);

        Assert.Contains(worker.ExceptionMessage, vm.StatusMessage);
        Assert.False(vm.IsBusy);
    }

    [Fact]
    public async Task ConfirmResetAll_WhenWorkerThrows_ShowsExceptionMessage()
    {
        var worker = new ThrowingWorker();
        var vm = new WorktreesSettingsTabViewModel(worker) { ConfirmAsync = _ => Task.FromResult(true) };

        await vm.ConfirmResetAllCommand.ExecuteAsync(null);

        Assert.Contains(worker.ExceptionMessage, vm.StatusMessage);
        Assert.False(vm.ResetStatus.IsRunning);
    }

    [Fact]
    public async Task ConfirmResetAll_WhenConfirmDeclined_DoesNotCallWorker()
    {
        var worker = new CountingWorker();
        var vm = new WorktreesSettingsTabViewModel(worker) { ConfirmAsync = _ => Task.FromResult(false) };

        await vm.ConfirmResetAllCommand.ExecuteAsync(null);

        Assert.Equal(0, worker.ResetCallCount);
    }

    [Fact]
    public async Task ConfirmResetAll_WhenConfirmHookMissing_DoesNotCallWorker()
    {
        var worker = new CountingWorker();
        var vm = new WorktreesSettingsTabViewModel(worker);

        await vm.ConfirmResetAllCommand.ExecuteAsync(null);

        Assert.Equal(0, worker.ResetCallCount);
    }
}
