namespace KArtSell.Integration.Tests;

using KArtSell.Modules.ModelOperations.Domain.ApprovalWorkflow;
using KArtSell.Modules.ModelOperations.Features.ApprovalWorkflow;
using Xunit;

public class ApprovalWorkflowPolicyTests
{
    [Fact]
    public void CanCreateProposal_MakerRole_ReturnsTrue()
    {
        var result = ApprovalWorkflowPolicy.CanCreateProposal("maker@test.com", "Maker");
        Assert.True(result);
    }

    [Fact]
    public void CanCreateProposal_NonMakerRole_ReturnsFalse()
    {
        var result = ApprovalWorkflowPolicy.CanCreateProposal("user@test.com", "Viewer");
        Assert.False(result);
    }

    [Fact]
    public void CanApprove_CheckerDifferentFromMaker_ReturnsTrue()
    {
        var proposal = new ApprovalProposal { CreatedBy = "maker@test.com", Justification = "test", Status = ApprovalStatus.Proposed };
        var result = ApprovalWorkflowPolicy.CanApprove(proposal, "checker@test.com", "Checker");
        Assert.True(result);
    }

    [Fact]
    public void CanApprove_SeparationOfDuties_Enforced()
    {
        var proposal = new ApprovalProposal { CreatedBy = "user@test.com", Justification = "test", Status = ApprovalStatus.Proposed };
        var result = ApprovalWorkflowPolicy.CanApprove(proposal, "user@test.com", "Checker");
        Assert.False(result);
    }

    [Fact]
    public void CanApprove_NonCheckerRole_ReturnsFalse()
    {
        var proposal = new ApprovalProposal { CreatedBy = "maker@test.com", Justification = "test", Status = ApprovalStatus.Proposed };
        var result = ApprovalWorkflowPolicy.CanApprove(proposal, "other@test.com", "Maker");
        Assert.False(result);
    }

    [Fact]
    public void CanActivate_SreRoleWithApprovedStatus_ReturnsTrue()
    {
        var proposal = new ApprovalProposal { CreatedBy = "maker@test.com", Justification = "test", Status = ApprovalStatus.Approved };
        var result = ApprovalWorkflowPolicy.CanActivate(proposal, "sre@test.com", "SRE");
        Assert.True(result);
    }

    [Fact]
    public void CanActivate_NonSreRole_ReturnsFalse()
    {
        var proposal = new ApprovalProposal { CreatedBy = "maker@test.com", Justification = "test", Status = ApprovalStatus.Approved };
        var result = ApprovalWorkflowPolicy.CanActivate(proposal, "maker@test.com", "Maker");
        Assert.False(result);
    }

    [Fact]
    public void CanActivate_ApprovedRequired_NonApprovedStatus_ReturnsFalse()
    {
        var proposal = new ApprovalProposal { CreatedBy = "maker@test.com", Justification = "test", Status = ApprovalStatus.Proposed };
        var result = ApprovalWorkflowPolicy.CanActivate(proposal, "sre@test.com", "SRE");
        Assert.False(result);
    }

    [Fact]
    public void ValidateProposalState_ValidTransition_Succeeds()
    {
        ApprovalWorkflowPolicy.ValidateProposalState(ApprovalStatus.Draft, ApprovalStatus.Proposed);
    }

    [Fact]
    public void ValidateProposalState_InvalidTransition_Throws()
    {
        Assert.Throws<InvalidOperationException>(() =>
            ApprovalWorkflowPolicy.ValidateProposalState(ApprovalStatus.Draft, ApprovalStatus.Active));
    }
}
