using BigRegister.Domain.Authorization;
using Xunit;

namespace BigRegister.Tests;

/// <summary>
/// Unit tests for the single authorization helper (PRD-0002 phase P1) that both
/// computes the brief screen's decision flags and gates the mutation endpoints.
/// </summary>
public class AuthzTests
{
  private static readonly Principal Drafter = new(PrincipalRole.Drafter);
  private static readonly Principal Approver = new(PrincipalRole.Approver);
  private const string DrafterId = "demo-drafter";

  [Fact]
  public void Drafter_may_not_approve_or_reject_even_when_submitted()
  {
    Assert.False(Authz.CanActOn(BriefAction.Approve, Drafter, DrafterId));
    Assert.False(Authz.CanActOn(BriefAction.Reject, Drafter, DrafterId));
  }

  [Fact]
  public void Approver_may_approve_and_reject_a_different_drafters_letter()
  {
    Assert.True(Authz.CanActOn(BriefAction.Approve, Approver, DrafterId));
    Assert.True(Authz.CanActOn(BriefAction.Reject, Approver, DrafterId));
  }

  [Fact]
  public void Send_is_not_role_gated()
  {
    Assert.True(Authz.CanActOn(BriefAction.Send, Drafter, DrafterId));
    Assert.True(Authz.CanActOn(BriefAction.Send, Approver, DrafterId));
  }

  [Theory]
  [InlineData("draft")]
  [InlineData("rejected")]
  public void Decisions_CanEdit_true_for_drafter_in_editable_statuses(string status)
  {
    Assert.True(Authz.Decisions(Drafter, status, DrafterId).CanEdit);
    Assert.False(Authz.Decisions(Approver, status, DrafterId).CanEdit);
  }

  [Fact]
  public void Decisions_CanApprove_requires_submitted_status_and_approver_role()
  {
    Assert.True(Authz.Decisions(Approver, "submitted", DrafterId).CanApprove);
    Assert.False(Authz.Decisions(Approver, "draft", DrafterId).CanApprove);
    Assert.False(Authz.Decisions(Drafter, "submitted", DrafterId).CanApprove);
  }

  [Fact]
  public void Decisions_CanSend_requires_approved_status_only()
  {
    Assert.True(Authz.Decisions(Drafter, "approved", DrafterId).CanSend);
    Assert.True(Authz.Decisions(Approver, "approved", DrafterId).CanSend);
    Assert.False(Authz.Decisions(Approver, "submitted", DrafterId).CanSend);
  }

  [Fact]
  public void RoleCapabilities_are_empty_for_drafter_and_the_three_brief_capabilities_for_approver()
  {
    Assert.Empty(Authz.RoleCapabilities(Drafter));
    Assert.Equal(new[] { "brief:approve", "brief:reject", "brief:send" }, Authz.RoleCapabilities(Approver));
  }
}
