using PowderCoating.Application.Services;
using PowderCoating.Core.Entities;

namespace PowderCoating.UnitTests;

public class InventoryDuplicateMatcherTests
{
    [Fact]
    public void Find_SkuMatch_IsRestrictedToRequestedCompany()
    {
        var otherTenantItem = Item(
            id: 1,
            companyId: 22,
            sku: "POW-001",
            manufacturer: "Prismatic Powders",
            colorName: "Illusion Malbec");

        var result = InventoryDuplicateMatcher.Find(
            new[] { otherTenantItem },
            companyId: 11,
            sku: "POW-001",
            manufacturer: null,
            manufacturerPartNumber: null,
            colorName: null,
            isCoating: false);

        Assert.Null(result);
    }

    [Fact]
    public void Find_SkuMatch_IsCaseAndWhitespaceInsensitive()
    {
        var item = Item(1, 11, "POW-001", null, null);

        var result = InventoryDuplicateMatcher.Find(
            new[] { item },
            companyId: 11,
            sku: "  pow-001 ",
            manufacturer: null,
            manufacturerPartNumber: null,
            colorName: null,
            isCoating: false);

        Assert.NotNull(result);
        Assert.Equal(InventoryDuplicateMatchType.Sku, result!.MatchType);
        Assert.Same(item, result.Item);
    }

    [Fact]
    public void Find_PowderManufacturerAndColor_NormalizesSpacingAndCase()
    {
        var item = Item(
            id: 1,
            companyId: 11,
            sku: "POW-001",
            manufacturer: "Prismatic   Powders",
            colorName: "Illusion Malbec");

        var result = InventoryDuplicateMatcher.Find(
            new[] { item },
            companyId: 11,
            sku: null,
            manufacturer: " prismatic powders ",
            manufacturerPartNumber: null,
            colorName: "illusion   malbec",
            isCoating: true);

        Assert.NotNull(result);
        Assert.Equal(InventoryDuplicateMatchType.ManufacturerColor, result!.MatchType);
    }

    [Fact]
    public void Find_SameColorFromDifferentManufacturer_IsNotDuplicate()
    {
        var item = Item(
            id: 1,
            companyId: 11,
            sku: "POW-001",
            manufacturer: "Prismatic Powders",
            colorName: "Gloss Black");

        var result = InventoryDuplicateMatcher.Find(
            new[] { item },
            companyId: 11,
            sku: null,
            manufacturer: "Columbia Coatings",
            manufacturerPartNumber: null,
            colorName: "Gloss Black",
            isCoating: true);

        Assert.Null(result);
    }

    [Fact]
    public void Find_ManufacturerPartNumber_UsesSharedPowderRule()
    {
        var item = Item(
            id: 1,
            companyId: 11,
            sku: "POW-001",
            manufacturer: "Columbia Coatings",
            colorName: "Smokey Blue",
            manufacturerPartNumber: "S5704126");

        var result = InventoryDuplicateMatcher.Find(
            new[] { item },
            companyId: 11,
            sku: null,
            manufacturer: "columbia coatings",
            manufacturerPartNumber: " s5704126 ",
            colorName: null,
            isCoating: true);

        Assert.NotNull(result);
        Assert.Equal(InventoryDuplicateMatchType.ManufacturerPartNumber, result!.MatchType);
    }

    [Fact]
    public void Find_NonCoating_DoesNotUsePowderIdentityRules()
    {
        var item = Item(
            id: 1,
            companyId: 11,
            sku: "SUP-001",
            manufacturer: "Acme",
            colorName: "Blue");

        var result = InventoryDuplicateMatcher.Find(
            new[] { item },
            companyId: 11,
            sku: null,
            manufacturer: "Acme",
            manufacturerPartNumber: null,
            colorName: "Blue",
            isCoating: false);

        Assert.Null(result);
    }

    private static InventoryItem Item(
        int id,
        int companyId,
        string sku,
        string? manufacturer,
        string? colorName,
        string? manufacturerPartNumber = null)
    {
        return new InventoryItem
        {
            Id = id,
            CompanyId = companyId,
            SKU = sku,
            Name = colorName ?? sku,
            Manufacturer = manufacturer,
            ManufacturerPartNumber = manufacturerPartNumber,
            ColorName = colorName,
            InventoryCategory = new InventoryCategoryLookup
            {
                Id = id,
                CompanyId = companyId,
                DisplayName = "Powder",
                CategoryCode = "POWDER",
                IsCoating = true
            }
        };
    }
}
