using System.Diagnostics;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting;
using Nexus.Api.Models;
using Nexus.Api.Observability;

namespace Nexus.Api.Controllers;

[Authorize]
[ApiController]
[Route("api/v1/telemetry/browser")]
[EnableRateLimiting("agents")]
public sealed class BrowserTelemetryController : ControllerBase
{
    private static readonly HashSet<string> AllowedNames =
    [
        "CLS",
        "FCP",
        "INP",
        "LCP",
        "TTFB",
        "board_content_visible",
        "board_delta_painted",
        "mutation_confirmed",
        "agent_proposal_readback"
    ];

    private static readonly HashSet<string> AllowedRatings =
        ["good", "needs-improvement", "poor", "custom"];

    [HttpPost]
    public IResult Record([FromBody] BrowserMetricRequest request)
    {
        if (!AllowedNames.Contains(request.Name))
            return Results.ValidationProblem(new Dictionary<string, string[]>
            {
                ["name"] = ["Unsupported browser metric."]
            });

        if (!double.IsFinite(request.Value) || request.Value < 0 || request.Value > 86_400_000)
            return Results.ValidationProblem(new Dictionary<string, string[]>
            {
                ["value"] = ["Metric value must be finite and within the accepted range."]
            });

        if (!AllowedRatings.Contains(request.Rating))
            return Results.ValidationProblem(new Dictionary<string, string[]>
            {
                ["rating"] = ["Unsupported metric rating."]
            });

        var route = NormalizeBoundedDimension(request.RouteName, "unknown", 80);
        var liveMode = request.LiveMode is "live" or "polling" ? request.LiveMode : "unknown";
        var navigationType = NormalizeBoundedDimension(request.NavigationType, "unknown", 40);

        var tags = new TagList
        {
            { "metric.name", request.Name },
            { "metric.rating", request.Rating },
            { "route.name", route },
            { "nexus.live_mode", liveMode },
            { "navigation.type", navigationType }
        };

        if (request.Name == "CLS")
            NexusTelemetry.BrowserScore.Record(request.Value, tags);
        else
            NexusTelemetry.BrowserDuration.Record(request.Value, tags);

        return Results.NoContent();
    }

    private static string NormalizeBoundedDimension(string? value, string fallback, int maxLength)
    {
        if (string.IsNullOrWhiteSpace(value))
            return fallback;

        var normalized = new string(value
            .Where(character => char.IsAsciiLetterOrDigit(character) || character is ' ' or '_' or '-')
            .Take(maxLength)
            .ToArray());
        return string.IsNullOrWhiteSpace(normalized) ? fallback : normalized;
    }
}
