using System.Text;
using JobTrackerApi.Controllers;
using JobTrackerApi.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Moq;
using Xunit;

namespace JobTrackerApi.Tests;

public sealed class BillingControllerTests
{
    [Fact]
    public async Task Webhook_rejects_an_invalid_Stripe_signature()
    {
        var configuration = new ConfigurationBuilder().AddInMemoryCollection(new Dictionary<string, string?>
        {
            ["Stripe:SecretKey"] = "sk_test_fake",
            ["Stripe:PricePremium"] = "price_fake",
            ["Stripe:WebhookSecret"] = "whsec_fake",
            ["App:PublicBaseUrl"] = "https://example.test",
        }).Build();

        var userStore = new Mock<IUserStore<ApplicationUser>>();
        var users = new Mock<UserManager<ApplicationUser>>(
            userStore.Object, Options.Create(new IdentityOptions()), new PasswordHasher<ApplicationUser>(),
            Array.Empty<IUserValidator<ApplicationUser>>(), Array.Empty<IPasswordValidator<ApplicationUser>>(),
            new UpperInvariantLookupNormalizer(), new IdentityErrorDescriber(), null!, NullLogger<UserManager<ApplicationUser>>.Instance);
        var roleStore = new Mock<IRoleStore<IdentityRole>>();
        var roles = new Mock<RoleManager<IdentityRole>>(
            roleStore.Object, Array.Empty<IRoleValidator<IdentityRole>>(), new UpperInvariantLookupNormalizer(),
            new IdentityErrorDescriber(), NullLogger<RoleManager<IdentityRole>>.Instance);

        var controller = new BillingController(configuration, users.Object, roles.Object, NullLogger<BillingController>.Instance)
        {
            ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext() },
        };
        controller.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes("{}"));
        controller.Request.Headers["Stripe-Signature"] = "invalid";

        var result = await controller.Webhook(CancellationToken.None);

        Assert.IsType<BadRequestObjectResult>(result);
    }
}
