using FastEndpoints;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Npgsql;

namespace KArtSell.Modules.ModelOperations.Compliance;

/// <summary>
/// Query audit events with filters (compliance officer access).
/// GET /audit/events?entityId=uuid&eventType=MODEL_ACTIVATED&dateFrom=2026-01-01&dateTo=2026-12-31&actorEmail=user@company.com
/// </summary>
public class QueryAuditEventsRequest
{
    public Guid? EntityId { get; set; }
    public string? EventType { get; set; }
    public DateTime? DateFrom { get; set; }
    public DateTime? DateTo { get; set; }
    public string? ActorEmail { get; set; }
    public int Skip { get; set; }
    public int Take { get; set; } = 50;
}

public class AuditEventDto
{
    public Guid Id { get; set; }
    public string EventType { get; set; } = string.Empty;
    public string EntityType { get; set; } = string.Empty;
    public Guid EntityId { get; set; }
    public string ActorEmail { get; set; } = string.Empty;
    public string? ActorRole { get; set; }
    public DateTime EventAt { get; set; }
    public string Result { get; set; } = string.Empty;
    public Dictionary<string, object>? Details { get; set; }
    public string[]? EvidenceLinks { get; set; }
    public DateTime PublishedAt { get; set; }
    public Guid CorrelationId { get; set; }
}

public class QueryAuditEventsResponse
{
    public List<AuditEventDto> Items { get; set; } = new();
    public int Total { get; set; }
    public int Skip { get; set; }
    public int Take { get; set; }
    public int Pages => (Total + Take - 1) / Take;
}

public class QueryAuditEventsEndpoint : Endpoint<QueryAuditEventsRequest, QueryAuditEventsResponse>
{
    private readonly AuditSql _sql;
    private readonly ILogger<QueryAuditEventsEndpoint> _logger;

    public QueryAuditEventsEndpoint(AuditSql sql, ILogger<QueryAuditEventsEndpoint> logger)
    {
        _sql = sql;
        _logger = logger;
    }

    public override void Configure()
    {
        Get("/audit/events");
        Roles("Compliance");
        Summary(x =>
        {
            x.Summary = "Query Audit Events";
            x.Description = "Query immutable audit trail with optional filters";
        });
    }

    public override async Task HandleAsync(QueryAuditEventsRequest req, CancellationToken ct)
    {
        try
        {
            using var db = new NpgsqlConnection(Environment.GetEnvironmentVariable("KARTSELL_POSTGRES"));
            db.Open();

            var (events, total) = await _sql.QueryAuditEventsAsync(
                db,
                req.EntityId,
                req.EventType,
                req.DateFrom,
                req.DateTo,
                req.ActorEmail,
                req.Skip,
                req.Take,
                ct);

            var response = new QueryAuditEventsResponse
            {
                Items = events.Select(e => new AuditEventDto
                {
                    Id = e.Id,
                    EventType = e.EventType,
                    EntityType = e.EntityType,
                    EntityId = e.EntityId,
                    ActorEmail = e.ActorEmail,
                    ActorRole = e.ActorRole,
                    EventAt = e.EventAt,
                    Result = e.Result,
                    Details = e.Details,
                    EvidenceLinks = e.EvidenceLinks,
                    PublishedAt = e.PublishedAt,
                    CorrelationId = e.CorrelationId
                }).ToList(),
                Total = total,
                Skip = req.Skip,
                Take = req.Take
            };

            await Send.OkAsync(response, ct);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to query audit events");
            await SendInternalErrorResponse(ct);
        }
    }

    private async Task SendInternalErrorResponse(CancellationToken ct)
    {
        await Send.ResponseAsync(
            new QueryAuditEventsResponse(),
            StatusCodes.Status500InternalServerError,
            ct);
    }
}
