using Asp.Versioning;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using IamService.API.Application.Common;
using IamService.API.Application.Commands.Compliance;
using IamService.API.Application.Queries.Compliance;

namespace IamService.API.Controllers;

[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/compliance")]
[Authorize(AuthenticationSchemes = "Bearer")]
[Authorize(Policy = "RequireAuditor")]
[SwaggerTag("Compliance reporting - requires Auditor role")]
public class ComplianceController : ControllerBase
{
    private readonly IMediator _mediator;
    public ComplianceController(IMediator mediator) => _mediator = mediator;

    [HttpPost("reports")]
    [SwaggerOperation(Summary = "Generate compliance report", OperationId = "GenerateComplianceReport")]
    public async Task<IActionResult> Generate([FromBody] GenerateReportRequest request, CancellationToken ct = default)
    {
        try
        {
            var id = await _mediator.Send(new GenerateComplianceReportCommand(request.Name, request.ReportTypeId, request.GeneratedByUserId), ct);
            return Ok(ApiResponse<object>.Ok(new { ReportId = id, Status = "Generating" }));
        }
        catch (Exception ex) { return BadRequest(ApiResponse<object>.Fail("ERROR", ex.Message)); }
    }

    [HttpGet("reports")]
    [SwaggerOperation(Summary = "Get compliance reports", OperationId = "GetComplianceReports")]
    public async Task<IActionResult> GetReports([FromQuery] int? reportTypeId, [FromQuery] int take = 20, CancellationToken ct = default)
    {
        var reports = await _mediator.Send(new GetComplianceReportsQuery(reportTypeId, take), ct);
        return Ok(ApiResponse<IEnumerable<ComplianceReportDto>>.Ok(reports));
    }

    [HttpGet("reports/{id:guid}")]
    [SwaggerOperation(Summary = "Get compliance report by ID", OperationId = "GetComplianceReportById")]
    public async Task<IActionResult> GetById([FromRoute] Guid id, CancellationToken ct = default)
    {
        var report = await _mediator.Send(new GetComplianceReportByIdQuery(id), ct);
        if (report == null) return NotFound(ApiResponse<object>.Fail("NOT_FOUND", "Report not found"));
        return Ok(ApiResponse<ComplianceReportDetailDto>.Ok(report));
    }

    [HttpGet("violations")]
    [SwaggerOperation(Summary = "Get unresolved violations", OperationId = "GetUnresolvedViolations")]
    public async Task<IActionResult> GetViolations(CancellationToken ct = default)
    {
        var violations = await _mediator.Send(new GetUnresolvedViolationsQuery(), ct);
        return Ok(ApiResponse<IEnumerable<ViolationDto>>.Ok(violations));
    }

    [HttpPost("reports/{id:guid}/complete")]
    [SwaggerOperation(Summary = "Complete compliance report", OperationId = "CompleteComplianceReport")]
    public async Task<IActionResult> Complete([FromRoute] Guid id, [FromBody] CompleteReportRequest request, CancellationToken ct = default)
    {
        try
        {
            await _mediator.Send(new CompleteComplianceReportCommand(id, request.TotalChecks, request.PassedChecks, request.Summary), ct);
            return Ok(ApiResponse<object>.Ok(new { Message = "Report completed" }));
        }
        catch (Exception ex) { return BadRequest(ApiResponse<object>.Fail("ERROR", ex.Message)); }
    }
}

public record GenerateReportRequest(string Name, int ReportTypeId, Guid GeneratedByUserId);
public record CompleteReportRequest(int TotalChecks, int PassedChecks, string? Summary);
