namespace TaxBaik.Application.Tests;

using TaxBaik.Application.Services;
using TaxBaik.Domain.Entities;
using TaxBaik.Domain.Interfaces;
using Xunit;

public class CommonCodeServiceTests
{
    [Fact]
    public async Task UpsertAsync_TrimsAndRejectsWhitespaceInCodeValue()
    {
        var repository = new FakeCommonCodeRepository();
        var service = new CommonCodeService(repository);

        await Assert.ThrowsAsync<ValidationException>(() => service.UpsertAsync(new CommonCode
        {
            CodeGroup = " CLIENT_STATUS ",
            CodeValue = "active code",
            CodeName = " 활성 "
        }));
    }

    [Fact]
    public async Task UpsertAsync_TrimsAndPersistsNormalizedValues()
    {
        var repository = new FakeCommonCodeRepository();
        var service = new CommonCodeService(repository);

        await service.UpsertAsync(new CommonCode
        {
            CodeGroup = " CLIENT_STATUS ",
            CodeValue = "active",
            CodeName = " 활성 ",
            SortOrder = 10
        });

        var saved = Assert.Single(repository.SavedCodes);
        Assert.Equal("CLIENT_STATUS", saved.CodeGroup);
        Assert.Equal("active", saved.CodeValue);
        Assert.Equal("활성", saved.CodeName);
    }

    private sealed class FakeCommonCodeRepository : ICommonCodeRepository
    {
        public List<CommonCode> SavedCodes { get; } = [];

        public Task<IEnumerable<string>> GetAllGroupsAsync(CancellationToken ct = default) =>
            Task.FromResult<IEnumerable<string>>([]);

        public Task<IEnumerable<CommonCode>> GetByGroupAsync(string codeGroup, CancellationToken ct = default) =>
            Task.FromResult<IEnumerable<CommonCode>>([]);

        public Task<IEnumerable<CommonCode>> GetAllActiveAsync(CancellationToken ct = default) =>
            Task.FromResult<IEnumerable<CommonCode>>([]);

        public Task<CommonCode?> GetAsync(string codeGroup, string codeValue, CancellationToken ct = default) =>
            Task.FromResult<CommonCode?>(null);

        public Task UpsertAsync(CommonCode code, CancellationToken ct = default)
        {
            SavedCodes.Add(new CommonCode
            {
                CodeGroup = code.CodeGroup,
                CodeValue = code.CodeValue,
                CodeName = code.CodeName,
                SortOrder = code.SortOrder,
                IsActive = code.IsActive
            });
            return Task.CompletedTask;
        }

        public Task DeleteAsync(string codeGroup, string codeValue, CancellationToken ct = default) =>
            Task.CompletedTask;
    }
}
