using System.IO;
using SharepointToolbox.Core.Models;
using SharepointToolbox.Infrastructure.Persistence;

namespace SharepointToolbox.Tests.Services;

public class TemplateRepositoryTests : IDisposable
{
    private readonly string _tempDir;
    private readonly TemplateRepository _repo;

    public TemplateRepositoryTests()
    {
        _tempDir = Path.Combine(Path.GetTempPath(), $"sptoolbox_test_{Guid.NewGuid():N}");
        _repo = new TemplateRepository(_tempDir);
    }

    public void Dispose()
    {
        if (Directory.Exists(_tempDir))
            Directory.Delete(_tempDir, true);
    }

    private static SiteTemplate CreateTestTemplate(string name = "Test Template")
    {
        return new SiteTemplate
        {
            Id = Guid.NewGuid().ToString(),
            Name = name,
            SourceUrl = "https://contoso.sharepoint.com/sites/test",
            CapturedAt = DateTime.UtcNow,
            SiteType = "Team",
            Options = new SiteTemplateOptions(),
            Settings = new TemplateSettings { Title = "Test", Description = "Desc", Language = 1033 },
            Libraries = new List<TemplateLibraryInfo>
            {
                new() { Name = "Documents", BaseType = "DocumentLibrary", BaseTemplate = 101 }
            },
        };
    }

    [Fact]
    public async Task SaveAndLoad_RoundTrips_Correctly()
    {
        var template = CreateTestTemplate();
        await _repo.SaveAsync(template);

        var loaded = await _repo.GetByIdAsync(template.Id);

        Assert.NotNull(loaded);
        Assert.Equal(template.Name, loaded!.Name);
        Assert.Equal(template.SiteType, loaded.SiteType);
        Assert.Equal(template.SourceUrl, loaded.SourceUrl);
        Assert.Single(loaded.Libraries);
        Assert.Equal("Documents", loaded.Libraries[0].Name);
    }

    [Fact]
    public async Task GetAll_ReturnsAllSavedTemplates()
    {
        await _repo.SaveAsync(CreateTestTemplate("Template A"));
        await _repo.SaveAsync(CreateTestTemplate("Template B"));
        await _repo.SaveAsync(CreateTestTemplate("Template C"));

        var all = await _repo.GetAllAsync();

        Assert.Equal(3, all.Count);
    }

    [Fact]
    public async Task Delete_RemovesTemplate()
    {
        var template = CreateTestTemplate();
        await _repo.SaveAsync(template);
        Assert.NotNull(await _repo.GetByIdAsync(template.Id));

        await _repo.DeleteAsync(template.Id);

        Assert.Null(await _repo.GetByIdAsync(template.Id));
    }

    [Fact]
    public async Task Rename_UpdatesTemplateName()
    {
        var template = CreateTestTemplate("Old Name");
        await _repo.SaveAsync(template);

        await _repo.RenameAsync(template.Id, "New Name");

        var loaded = await _repo.GetByIdAsync(template.Id);
        Assert.Equal("New Name", loaded!.Name);
    }

    [Fact]
    public async Task GetAll_EmptyDirectory_ReturnsEmptyList()
    {
        var all = await _repo.GetAllAsync();
        Assert.Empty(all);
    }

    [Fact]
    public async Task GetById_NonExistent_ReturnsNull()
    {
        var result = await _repo.GetByIdAsync("nonexistent-id");
        Assert.Null(result);
    }
}
