using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;

[ApiController]
[Produces("application/json")]
[Authorize]
public class AlertQualityMetricsController : ControllerBase
{
    private readonly IAlertQualityMetricsService _metrics;
    private readonly SimulationOptions _simulation;

    public AlertQualityMetricsController(
        IAlertQualityMetricsService metrics,
        IOptions<SimulationOptions> simulation)
    {
        _metrics = metrics;
        _simulation = simulation.Value;
    }

    /// <summary>
    /// Returns alert quality metric snapshots for a time range, optionally filtered by alert type.
    /// </summary>
    [HttpGet("api/v1/alerts/quality-metrics")]
    [AuthorizePermission(ClinicalPermissions.AnalyticsRead)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> List(
        [FromQuery] string? alertType,
        [FromQuery] DateTimeOffset? from,
        [FromQuery] DateTimeOffset? to)
    {
        AlertType? parsedType = null;
        if (!string.IsNullOrEmpty(alertType))
        {
            try
            {
                parsedType = AlertTypeExtensions.FromDbString(alertType);
            }
            catch (ArgumentOutOfRangeException)
            {
                return BadRequest(ApiResponse<object>.Fail(
                    400, "Invalid alert type filter.", "INVALID_ALERT_TYPE"));
            }
        }

        var periodEnd = to ?? DateTimeOffset.UtcNow;
        var periodStart = from ?? periodEnd.AddDays(-7);
        if (periodStart >= periodEnd)
        {
            return BadRequest(ApiResponse<object>.Fail(
                400, "'from' must be before 'to'.", "INVALID_DATE_RANGE"));
        }

        var items = await _metrics.ListAsync(parsedType, periodStart, periodEnd);
        return Ok(ApiResponse<object>.Ok(new
        {
            periodStart,
            periodEnd,
            items
        }));
    }

    /// <summary>
    /// Returns aggregate alert quality rates across all alert types for a time range.
    /// </summary>
    [HttpGet("api/v1/alerts/quality-metrics/summary")]
    [AuthorizePermission(ClinicalPermissions.AnalyticsRead)]
    [ProducesResponseType(typeof(ApiResponse<AlertQualitySummaryResponse>), StatusCodes.Status200OK)]
    public async Task<IActionResult> Summary(
        [FromQuery] DateTimeOffset? from,
        [FromQuery] DateTimeOffset? to)
    {
        var periodEnd = to ?? DateTimeOffset.UtcNow;
        var periodStart = from ?? periodEnd.AddDays(-7);

        var summary = await _metrics.GetSummaryAsync(periodStart, periodEnd);
        return Ok(ApiResponse<AlertQualitySummaryResponse>.Ok(summary));
    }

    /// <summary>
    /// Per-alert feedback rows with optional scenario attribution (when simulation is enabled).
    /// Filter with <c>?scenarioId=</c> to limit to one simulated scenario.
    /// </summary>
    [HttpGet("api/v1/alerts/quality-metrics/feedback")]
    [AuthorizePermission(ClinicalPermissions.AnalyticsRead)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> ListFeedback(
        [FromQuery] string? scenarioId,
        [FromQuery] DateTimeOffset? from,
        [FromQuery] DateTimeOffset? to)
    {
        var periodEnd = to ?? DateTimeOffset.UtcNow;
        var periodStart = from ?? periodEnd.AddDays(-7);
        if (periodStart >= periodEnd)
        {
            return BadRequest(ApiResponse<object>.Fail(
                400, "'from' must be before 'to'.", "INVALID_DATE_RANGE"));
        }

        // Scenario filter only applies when simulation attribution is available.
        var filterScenario = _simulation.Enabled ? scenarioId : null;
        var rows = await _metrics.ListFeedbackAsync(periodStart, periodEnd, filterScenario);

        if (_simulation.Enabled)
        {
            var withAttribution = rows.Select(r => new
            {
                id = r.Id,
                alertId = r.AlertId,
                alertType = r.AlertType,
                feedbackType = r.FeedbackType,
                comment = r.Comment,
                createdAt = r.CreatedAt,
                scenarioId = r.ScenarioId,
                sessionId = r.SessionId,
            });
            return Ok(ApiResponse<object>.Ok(new
            {
                periodStart,
                periodEnd,
                items = withAttribution,
            }));
        }

        var withoutAttribution = rows.Select(r => new
        {
            id = r.Id,
            alertId = r.AlertId,
            alertType = r.AlertType,
            feedbackType = r.FeedbackType,
            comment = r.Comment,
            createdAt = r.CreatedAt,
        });
        return Ok(ApiResponse<object>.Ok(new
        {
            periodStart,
            periodEnd,
            items = withoutAttribution,
        }));
    }
}
