using AVSCartonShipmentVerifier.DTOs; using AVSCartonShipmentVerifier.Services; using Microsoft.AspNetCore.Mvc; namespace AVSCartonShipmentVerifier.Controllers; [Route("api/verification")] public sealed class VerificationController( IShipmentVerificationService shipmentVerificationService, IScanHistoryStore scanHistoryStore, ILogger logger) : Controller { private readonly IShipmentVerificationService _shipmentVerificationService = shipmentVerificationService; private readonly IScanHistoryStore _scanHistoryStore = scanHistoryStore; private readonly ILogger _logger = logger; [HttpPost("scan")] [ValidateAntiForgeryToken] public async Task Scan([FromBody] QrScanRequestDto request, CancellationToken cancellationToken) { if (request is null) { return BadRequest(new { message = "Request payload is required." }); } try { var verificationResult = await _shipmentVerificationService.VerifyQrAsync( request.QrValue, request.EntryMethod ?? "Scanner", cancellationToken); return Ok(new { result = verificationResult, recentSuccessfulScans = await _scanHistoryStore.GetLastFiveSuccessfulScansAsync(cancellationToken), recentRejectedScans = await _scanHistoryStore.GetLastFiveRejectedScansAsync(cancellationToken) }); } catch (OperationCanceledException) { return StatusCode(StatusCodes.Status499ClientClosedRequest); } catch (Exception exception) { _logger.LogError(exception, "Unexpected error while verifying QR scan."); return StatusCode(StatusCodes.Status500InternalServerError, new { message = "An unexpected error occurred during verification." }); } } /// /// Returns all successful or all rejected scan records from SQLite (not limited to five). /// [HttpGet("history")] public async Task GetFullHistory([FromQuery] string category = "successful", CancellationToken cancellationToken = default) { var normalized = category.Trim().ToLowerInvariant(); try { if (normalized == "successful") { var records = await _scanHistoryStore.GetAllSuccessfulScansAsync(cancellationToken); return Ok(new { category = "successful", records }); } if (normalized == "rejected") { var records = await _scanHistoryStore.GetAllRejectedScansAsync(cancellationToken); return Ok(new { category = "rejected", records }); } return BadRequest(new { message = "Invalid category. Use 'successful' or 'rejected'." }); } catch (Exception exception) { _logger.LogError(exception, "Unexpected error while loading scan history."); return StatusCode(StatusCodes.Status500InternalServerError, new { message = "Unable to load scan history." }); } } }