using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;


/// <summary>
/// Batch verification and rejection endpoints.
/// Enforces separation of duties: the user who entered the data cannot verify
/// or reject the same batch. All transitions write DigitizationEvents.
/// </summary>
[ApiController]
[Route("api/v1/digitization-batches")]
[Produces("application/json")]
[Authorize]
public class VerificationController : ControllerBase
{
    private readonly IVerificationService _verification;

    public VerificationController(IVerificationService verification)
    {
        _verification = verification;
    }

    /// <summary>
    /// Verifies a batch that is in PendingVerification status.
    /// Requires field-level checks. If passed is true, transitions to Verified
    /// or AwaitingClinicalApproval based on site configuration for the batch type.
    /// If passed is false, transitions to Rejected with field check errors as the reason.
    /// Returns 409 SEPARATION_OF_DUTIES_VIOLATION if the verifier is the same user
    /// who entered the data.
    /// </summary>
    /// <param name="id">The batch ID to verify.</param>
    /// <param name="request">Verification request with field checks and pass/fail.</param>
    [HttpPost("{id:guid}/verify")]
    [Authorize(Roles = "VERIFIER,CLINICAL_APPROVER,ADMINISTRATOR")]
    [ProducesResponseType(typeof(ApiResponse<BatchDetailResponse>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status409Conflict)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status422UnprocessableEntity)]
    public async Task<IActionResult> Verify(Guid id, [FromBody] VerifyBatchRequest request)
    {
        var verifierUserId = Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
        var batch = await _verification.VerifyAsync(id, request, verifierUserId);

        return Ok(ApiResponse<BatchDetailResponse>.Ok(BatchDetailResponse.FromEntity(batch)));
    }

    /// <summary>
    /// Rejects a batch that is in PendingVerification or AwaitingClinicalApproval status.
    /// Requires a rejection reason (minimum 10 characters). The batch returns to the
    /// entry work queue for re-entry by a data entry clerk.
    /// Returns 409 SEPARATION_OF_DUTIES_VIOLATION if the rejector is the same user
    /// who entered the data (for PendingVerification status only).
    /// </summary>
    /// <param name="id">The batch ID to reject.</param>
    /// <param name="request">Rejection request with required reason.</param>
    [HttpPost("{id:guid}/reject")]
    [Authorize(Roles = "VERIFIER,CLINICAL_APPROVER,ADMINISTRATOR")]
    [ProducesResponseType(typeof(ApiResponse<BatchDetailResponse>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status409Conflict)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status422UnprocessableEntity)]
    public async Task<IActionResult> Reject(Guid id, [FromBody] RejectBatchRequest request)
    {
        var actorUserId = Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!);
        var batch = await _verification.RejectAsync(id, request, actorUserId);

        return Ok(ApiResponse<BatchDetailResponse>.Ok(BatchDetailResponse.FromEntity(batch)));
    }
}