using Inspectron.Epson.Templates.Configuration;

namespace Inspectron.Epson.Templates.Tests.Configuration;

public class TemplateResolverTests
{
    [Fact]
    public void Resolve_ExactMatch_ReturnsExactTemplate()
    {
        var assignments = new[]
        {
            new TemplateAssignment(1, "tm-t30iii", "kitchen-t30.template"),
            new TemplateAssignment(1, null, "kitchen-default.template")
        };
        var resolver = new TemplateResolver(assignments);

        var result = resolver.Resolve(1, "tm-t30iii");

        Assert.Equal("kitchen-t30.template", result);
    }

    [Fact]
    public void Resolve_TypeOnlyMatch_ReturnsTypeTemplate()
    {
        var assignments = new[]
        {
            new TemplateAssignment(1, null, "kitchen-default.template"),
            new TemplateAssignment(2, null, "bar-default.template")
        };
        var resolver = new TemplateResolver(assignments);

        var result = resolver.Resolve(1, "unknown-profile");

        Assert.Equal("kitchen-default.template", result);
    }

    [Fact]
    public void Resolve_NoMatch_ReturnsFallback()
    {
        var assignments = new[]
        {
            new TemplateAssignment(1, null, "kitchen-default.template")
        };
        var resolver = new TemplateResolver(assignments, "fallback.template");

        var result = resolver.Resolve(99, "unknown-profile");

        Assert.Equal("fallback.template", result);
    }

    [Fact]
    public void Resolve_PreferExactOverTypeOnly()
    {
        var assignments = new[]
        {
            new TemplateAssignment(1, null, "type-only.template"),
            new TemplateAssignment(1, "tm-t30iii", "exact.template")
        };
        var resolver = new TemplateResolver(assignments);

        var result = resolver.Resolve(1, "tm-t30iii");

        Assert.Equal("exact.template", result);
    }

    [Fact]
    public void Resolve_WithRegistry_MapsProfileCorrectly()
    {
        var registry = new PrinterProfileRegistry();
        var assignments = new[]
        {
            new TemplateAssignment(1, "tm-t30iii", "kitchen-t30.template"),
            new TemplateAssignment(1, "tm-u220ii", "kitchen-u220.template")
        };
        var resolver = new TemplateResolver(assignments);

        var result = resolver.Resolve(1, 0x01, registry);

        Assert.Equal("kitchen-t30.template", result);
    }

    [Fact]
    public void LoadConfiguration_ParsesCorrectly()
    {
        var json = """
        {
            "assignments": [
                {"receiptType": 1, "profileId": "tm-t30iii", "template": "kitchen.template"},
                {"receiptType": 2, "profileId": null, "template": "bar.template"}
            ],
            "fallbackTemplate": "default.template"
        }
        """;

        var config = TemplateConfiguration.LoadFromJson(json);

        Assert.Equal(2, config.Assignments.Count);
        Assert.Equal("default.template", config.FallbackTemplate);
    }
}
