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.Audit;
using IamService.API.Application.Queries.Audit;

namespace IamService.API.Controllers;

[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/audit")]
[Authorize(AuthenticationSchemes = "Bearer")]
[SwaggerTag("Audit log management - requires Auditor role")]
public class AuditController : ControllerBase
{
    private readonly IMediator _mediator;
    public AuditController(IMediator mediator) => _mediator = mediator;

    [HttpGet("logs")]
    [Authorize(Policy = "RequireAuditor")]
    [SwaggerOperation(Summary = "Get audit logs", OperationId = "GetAuditLogs")]
    public async Task<IActionResult> GetLogs(
        [FromQuery] DateTime? fromDate,
        [FromQuery] DateTime? toDate,
        [FromQuery] int? eventTypeId,
        [FromQuery] Guid? actorId,
        [FromQuery] string? resourceType,
        [FromQuery] int skip = 0,
        [FromQuery] int take = 50,
        CancellationToken ct = default)
    {
        var result = await _mediator.Send(new GetAuditLogsQuery(fromDate, toDate, eventTypeId, actorId, resourceType, skip, take), ct);
        return Ok(ApiResponse<AuditLogsResult>.Ok(result));
    }

    /// <summary>
    /// EN: Create an audit log entry (called by BFF after actions like login, merchant approve/suspend).
    /// VI: Tạo audit log entry (gọi bởi BFF sau các actions như login, duyệt/tạm ngưng merchant).
    /// </summary>
    [HttpPost("logs")]
    [Authorize(Policy = "RequireAdmin")]
    [SwaggerOperation(Summary = "Create audit log entry", OperationId = "CreateAuditLog")]
    public async Task<IActionResult> CreateLog([FromBody] CreateAuditLogRequest request, CancellationToken ct)
    {
        var id = await _mediator.Send(new CreateAuditLogCommand(
            request.EventTypeId,
            request.ResourceType,
            request.ActorId,
            request.ActorEmail,
            request.ResourceId,
            request.Action,
            request.Details,
            HttpContext.Connection.RemoteIpAddress?.ToString(),
            HttpContext.Request.Headers.UserAgent.ToString(),
            request.Success), ct);

        return Ok(ApiResponse<object>.Ok(new { id }));
    }
}

public record CreateAuditLogRequest(
    int EventTypeId,
    string ResourceType,
    Guid? ActorId = null,
    string? ActorEmail = null,
    Guid? ResourceId = null,
    string? Action = null,
    string? Details = null,
    bool Success = true);
