using DeepDrftData;
using Microsoft.AspNetCore.Mvc;

namespace DeepDrftAPI.Controllers;

[ApiController]
[Route("api/[controller]")]
public class StatsController : ControllerBase
{
    private readonly ITrackService _sqlTrackService;
    private readonly IEventService _eventService;
    private readonly ILogger<StatsController> _logger;

    public StatsController(
        ITrackService sqlTrackService, IEventService eventService, ILogger<StatsController> logger)
    {
        _sqlTrackService = sqlTrackService;
        _eventService = eventService;
        _logger = logger;
    }

    // GET api/stats/home (unauthenticated)
    // Aggregate figures behind the public home hero stat row — one read for all three cards. Same auth
    // posture as the other public browse reads (GET api/track/page). The figures span two domains:
    // the track-domain aggregation (Cuts/Mixes cards) lives in the SQL track service; the play-domain
    // figures (Phase 16 Plays card — total plays + unique listeners) live in the event service. This
    // controller is the thin composition seam that assembles both into one HomeStatsDto — neither
    // domain reaches into the other's tables. Play/listener figures are best-effort: a telemetry read
    // failure (or the not-yet-applied migration) leaves them at zero rather than failing the whole card.
    [HttpGet("home")]
    public async Task<ActionResult> GetHome(CancellationToken ct = default)
    {
        var trackResult = await _sqlTrackService.GetHomeStats(ct);
        if (!trackResult.Success || trackResult.Value is null)
        {
            var error = trackResult.Messages.FirstOrDefault()?.Message ?? "Unknown error";
            _logger.LogError("GetHome stats failed: {Error}", error);
            return StatusCode(500, "Failed to load stats");
        }

        var stats = trackResult.Value;

        var playsResult = await _eventService.GetTotalPlayCount(ct);
        if (playsResult is { Success: true })
            stats.TotalPlays = playsResult.Value;
        else
            _logger.LogWarning("GetHome total-plays read failed; Plays card falls back to 0: {Error}",
                playsResult.Messages.FirstOrDefault()?.Message);

        var listenersResult = await _eventService.GetDistinctListenerCount(ct);
        if (listenersResult is { Success: true })
            stats.UniqueListeners = listenersResult.Value;
        else
            _logger.LogWarning("GetHome unique-listeners read failed; secondary line falls back to 0: {Error}",
                listenersResult.Messages.FirstOrDefault()?.Message);

        return Ok(stats);
    }
}
