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 FilesSettingsTabViewModelTests
{
    public FilesSettingsTabViewModelTests()
    {
        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; } = "permission denied copying agent files";
        public override Task<SeedResultDto?> RestoreDefaultAgentsAsync() =>
            throw new Exception(ExceptionMessage);
    }

    private sealed class BlockingWorker : StubWorkerClient
    {
        public TaskCompletionSource<SeedResultDto?> Gate { get; } = new();
        public override Task<SeedResultDto?> RestoreDefaultAgentsAsync() => Gate.Task;
    }

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

        await vm.RestoreDefaultAgentsCommand.ExecuteAsync(null);

        Assert.Contains(worker.ExceptionMessage, vm.StatusMessage);
        Assert.False(vm.RestoreOp.IsRunning);
        Assert.True(vm.RestoreDefaultAgentsCommand.CanExecute(null));
    }

    [Fact]
    public async Task RestoreDefaultAgents_WhileRunning_IsRunningTrue_AndCommandLocked()
    {
        var worker = new BlockingWorker();
        var vm = new FilesSettingsTabViewModel(worker);

        var execution = vm.RestoreDefaultAgentsCommand.ExecuteAsync(null);

        Assert.True(vm.RestoreOp.IsRunning);
        Assert.False(vm.RestoreDefaultAgentsCommand.CanExecute(null));

        worker.Gate.SetResult(new SeedResultDto(1, 0));
        await execution;

        Assert.False(vm.RestoreOp.IsRunning);
        Assert.True(vm.RestoreDefaultAgentsCommand.CanExecute(null));
    }
}
