using System;
using Autofac;
using FitConnect.Encryption;
using FitConnect.Models;
using FitConnect.Models.v1.Api;
using FitConnect.Services.Models.v1.Submission;
using FluentAssertions;
using MockContainer;
using NUnit.Framework;
using SecurityEventToken = FitConnect.Models.SecurityEventToken;

namespace FluentApiTest;

[TestFixture]
public class SecurityEventTokenTests {
    [SetUp]
    public void Setup() {
        var container = Container.Create();
        _encryption = new FitEncryption(container.Resolve<KeySet>(), null);
    }

    private FitEncryption _encryption = null!;

    [Test]
    public void CreateJwt_AcceptSubmission() {
        var token = _encryption.CreateAcceptSecurityEventToken(new SubmissionForPickupDto {
            SubmissionId = Guid.NewGuid().ToString(), CaseId = Guid.NewGuid().ToString(),
            DestinationId = Guid.NewGuid().ToString()
        });
        Console.WriteLine(token);
        var decoded = new SecurityEventToken(token);
        decoded.Event?.Type.Should()
            .Be("https://schema.fitko.de/fit-connect/events/accept-submission");
        decoded.EventType.Should().Be(EventType.Accept);
    }

    [Test]
    public void CreateJwt_Reject_WithEncryptionIssue() {
        var token = _encryption.CreateRejectSecurityEventToken(Guid.NewGuid().ToString(),
            Guid.NewGuid().ToString(),
            Guid.NewGuid().ToString(),
            new[] { Problems.EncryptionIssue }
        );
        Console.WriteLine(token);
        var decoded = new SecurityEventToken(token);
        decoded.Event?.Type.Should()
            .Be("https://schema.fitko.de/fit-connect/events/reject-submission");
        decoded.EventType.Should().Be(EventType.Reject);
    }

    [Test]
    public void CreateJwt_Reject_WithMissingSchema() {
        var token = _encryption.CreateRejectSecurityEventToken(Guid.NewGuid().ToString(),
            Guid.NewGuid().ToString(),
            Guid.NewGuid().ToString(),
            new[] { Problems.MissingSchema }
        );
        Console.WriteLine(token);
        var decoded = new SecurityEventToken(token);
        decoded.Event?.Type.Should()
            .Be("https://schema.fitko.de/fit-connect/events/reject-submission");

        decoded.EventType.Should().Be(EventType.Reject);
    }

    [Test]
    public void CreateJwt_Reject_WithSchemaViolation() {
        var token = _encryption.CreateRejectSecurityEventToken(Guid.NewGuid().ToString(),
            Guid.NewGuid().ToString(),
            Guid.NewGuid().ToString(),
            new[] { Problems.SchemaViolation }
        );
        Console.WriteLine(token);
        var decoded = new SecurityEventToken(token);
        decoded.Event?.Type.Should()
            .Be("https://schema.fitko.de/fit-connect/events/reject-submission");
        decoded.EventType.Should().Be(EventType.Reject);
    }

    [Test]
    public void CreateJwt_Reject_WithSyntaxViolation() {
        var token = _encryption.CreateRejectSecurityEventToken(Guid.NewGuid().ToString(),
            Guid.NewGuid().ToString(),
            Guid.NewGuid().ToString(),
            new[] { Problems.SyntaxViolation }
        );
        Console.WriteLine(token);

        var decoded = new SecurityEventToken(token);
        decoded.Event?.Type.Should()
            .Be("https://schema.fitko.de/fit-connect/events/reject-submission");
        decoded.EventType.Should().Be(EventType.Reject);
    }

    [Test]
    public void CreateJwt_Reject_WithUnsupportedSchema() {
        var token = _encryption.CreateRejectSecurityEventToken(Guid.NewGuid().ToString(),
            Guid.NewGuid().ToString(),
            Guid.NewGuid().ToString(),
            new[] { Problems.UnsupportedSchema }
        );
        Console.WriteLine(token);
        var decoded = new SecurityEventToken(token);
        decoded.Event?.Type.Should()
            .Be("https://schema.fitko.de/fit-connect/events/reject-submission");
        decoded.EventType.Should().Be(EventType.Reject);
    }

    [Test]
    public void CreateJwt_Reject_WithIncorrectAuthenticationTag() {
        var token = _encryption.CreateRejectSecurityEventToken(Guid.NewGuid().ToString(),
            Guid.NewGuid().ToString(),
            Guid.NewGuid().ToString(),
            new[] { Problems.IncorrectAuthenticationTag }
        );
        Console.WriteLine(token);
        var decoded = new SecurityEventToken(token);
        decoded.Event?.Type.Should()
            .Be("https://schema.fitko.de/fit-connect/events/reject-submission");
        decoded.EventType.Should().Be(EventType.Reject);
    }

    // [Test]
    // public void CreateJwt_Reject_WithCustomProblem() {
    //     var token = _encryption.CreateSecurityEventToken(Guid.NewGuid().ToString(),
    //         Guid.NewGuid().ToString(),
    //         Guid.NewGuid().ToString(),
    //         "https://schema.fitko.de/fit-connect/events/reject-submission",
    //         new[] { new Problems { Description = "A real big issue" } }
    //     );
    //     Console.WriteLine(token);
    //     var decoded = new SecurityEventToken(token);
    //     decoded.Event?.Type.Should()
    //         .Be("https://schema.fitko.de/fit-connect/events/reject-submission");
    //     decoded.EventType.Should().Be(EventType.Reject);
    // }
}