using Meezi.API.Configuration;
using Meezi.API.Models.Snappfood;
using Meezi.API.Models.Tap30;
using Meezi.API.Services.Delivery;
using Meezi.Core.Delivery;
using Meezi.Core.Enums;
using Meezi.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Xunit;

namespace Meezi.API.Tests;

public class DeliveryIntegrationTests
{
    private static DeliveryPlatformsOptions TestOptions() => new()
    {
        DefaultSnappfoodCommissionPercent = 18,
        DefaultTap30CommissionPercent = 15
    };

    [Fact]
    public void OrderNormalizer_Snappfood_MapsToUnifiedOrder()
    {
        var normalizer = new OrderNormalizer();
        var unified = normalizer.FromSnappfood(new SnappfoodWebhookOrder(
            "sf-100",
            "vendor-1",
            "Ali",
            "09121234567",
            250_000m,
            [new SnappfoodWebhookItem("Espresso", 2, 100_000m)]));

        Assert.NotNull(unified);
        Assert.Equal("sf-100", unified!.ExternalId);
        Assert.Equal(DeliveryPlatform.Snappfood, unified.Platform);
        Assert.Equal(2, unified.Items[0].Quantity);
        Assert.Equal(UnifiedDeliveryStatus.Confirmed, unified.Status);
    }

    [Fact]
    public void OrderNormalizer_Tap30_MapsToUnifiedOrder()
    {
        var normalizer = new OrderNormalizer();
        var unified = normalizer.FromTap30(new Tap30WebhookOrder(
            "t30-55",
            "tap-vendor",
            new Tap30Customer("Sara", "09129876543", "Tehran", null, null),
            180_000m,
            "online",
            true,
            null,
            "delivery",
            35,
            null,
            null,
            "confirmed",
            [new Tap30WebhookItem("latte-1", "Latte", 1, 180_000m, null)]));

        Assert.NotNull(unified);
        Assert.Equal(DeliveryPlatform.Tap30, unified!.Platform);
        Assert.Equal("Sara", unified.Customer.Name);
        Assert.Equal(35, unified.Delivery.EstimatedMinutes);
    }

    [Fact]
    public async Task CommissionCalculator_SnappfoodDefault_Is18Percent()
    {
        var options = new DbContextOptionsBuilder<AppDbContext>()
            .UseInMemoryDatabase(Guid.NewGuid().ToString())
            .Options;
        await using var db = new AppDbContext(options);
        var calc = new CommissionCalculator(db, Options.Create(TestOptions()));

        var commission = await calc.CalculateForOrderAsync(
            "cafe-1",
            new UnifiedDeliveryOrder(
                "x1",
                DeliveryPlatform.Snappfood,
                "v1",
                DateTime.UtcNow,
                new UnifiedDeliveryCustomer("A", "09"),
                [new UnifiedDeliveryItem("1", "Coffee", 1, 100_000m)],
                new UnifiedDeliveryPayment(100_000m, "online", true),
                new UnifiedDeliveryInfo("delivery"),
                UnifiedDeliveryStatus.Confirmed));

        Assert.Equal(18_000m, commission);
    }

    [Fact]
    public async Task CommissionCalculator_Tap30Default_Is15Percent()
    {
        var options = new DbContextOptionsBuilder<AppDbContext>()
            .UseInMemoryDatabase(Guid.NewGuid().ToString())
            .Options;
        await using var db = new AppDbContext(options);
        var calc = new CommissionCalculator(db, Options.Create(TestOptions()));

        var rate = await calc.ResolveRatePercentAsync("cafe-1", DeliveryPlatform.Tap30);
        Assert.Equal(15m, rate);
        Assert.Equal(15_000m, calc.CalculateCommission(100_000m, rate));
    }

    [Fact]
    public void WebhookSignature_ValidHmac_Accepts()
    {
        const string secret = "test-secret";
        const string body = """{"orderId":"1"}""";
        var expected = WebhookSignatureService.ComputeHmacSha256Hex(body, secret);

        var svc = new WebhookSignatureService(Options.Create(new DeliveryPlatformsOptions
        {
            Snappfood = new SnappfoodPlatformOptions { WebhookSecret = secret }
        }));

        Assert.True(svc.Verify(DeliveryPlatform.Snappfood, body, expected));
        Assert.True(svc.Verify(DeliveryPlatform.Snappfood, body, $"sha256={expected}"));
    }
}
