using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using AdsAnalyticsService.API.Application.DTOs;
using AdsAnalyticsService.Infrastructure;

namespace AdsAnalyticsService.API.Controllers.Admin;

/// <summary>
/// EN: Admin API Controller for platform-wide metrics.
/// VI: Admin API Controller cho metrics toàn nền tảng.
/// </summary>
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/admin/ads-analytics/metrics")]
[Produces("application/json")]
public class AdminMetricsController : ControllerBase
{
    private readonly AdsAnalyticsServiceContext _context;
    private readonly ILogger<AdminMetricsController> _logger;

    public AdminMetricsController(
        AdsAnalyticsServiceContext context,
        ILogger<AdminMetricsController> logger)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    /// <summary>
    /// EN: Get platform-wide metrics overview.
    /// VI: Lấy tổng quan metrics toàn nền tảng.
    /// </summary>
    [HttpGet("overview")]
    [ProducesResponseType(typeof(PlatformMetricsDto), StatusCodes.Status200OK)]
    public async Task<ActionResult<PlatformMetricsDto>> GetOverview(
        [FromQuery] DateTime? startDate = null,
        [FromQuery] DateTime? endDate = null)
    {
        var start = startDate ?? DateTime.UtcNow.AddDays(-30).Date;
        var end = endDate ?? DateTime.UtcNow.Date;

        // EN: Aggregate all metrics
        // VI: Tổng hợp tất cả metrics
        var metrics = await _context.CampaignMetrics
            .Where(m => m.Date >= start && m.Date <= end)
            .ToListAsync();

        var totalImpressions = metrics.Sum(m => m.Impressions);
        var totalClicks = metrics.Sum(m => m.Clicks);
        var totalSpend = metrics.Sum(m => m.Spend);
        var totalRevenue = metrics.Sum(m => m.Revenue);

        // EN: Count active campaigns (with impressions in period)
        // VI: Đếm campaigns đang hoạt động
        var activeCampaigns = metrics.Select(m => m.CampaignId).Distinct().Count();

        // EN: Mock active advertisers (would come from campaigns table in full implementation)
        // VI: Mock active advertisers
        var activeAdvertisers = (activeCampaigns > 0) ? (activeCampaigns / 3) + 1 : 0;

        var avgCTR = totalImpressions > 0 ? (decimal)totalClicks / totalImpressions * 100 : 0;
        var avgROAS = totalSpend > 0 ? totalRevenue / totalSpend : 0;

        var overview = new PlatformMetricsDto(
            totalImpressions,
            totalClicks,
            totalSpend,
            totalRevenue,
            activeCampaigns,
            activeAdvertisers,
            avgCTR,
            avgROAS);

        _logger.LogInformation("Generated platform overview for period {Start} to {End}", start, end);

        return Ok(overview);
    }

    /// <summary>
    /// EN: Get top performing campaigns.
    /// VI: Lấy campaigns hiệu suất cao nhất.
    /// </summary>
    [HttpGet("top-campaigns")]
    [ProducesResponseType(typeof(List<TopCampaignDto>), StatusCodes.Status200OK)]
    public async Task<ActionResult<List<TopCampaignDto>>> GetTopCampaigns(
        [FromQuery] string metric = "spend",
        [FromQuery] int limit = 10)
    {
        var validMetrics = new[] { "spend", "impressions", "clicks", "revenue", "roas" };
        if (!validMetrics.Contains(metric.ToLower()))
            return BadRequest(new { message = $"Invalid metric. Valid options: {string.Join(", ", validMetrics)}" });

        // EN: Get metrics from last 30 days
        // VI: Lấy metrics 30 ngày gần nhất
        var campaigns = await _context.CampaignMetrics
            .Where(m => m.Date >= DateTime.UtcNow.AddDays(-30).Date)
            .GroupBy(m => m.CampaignId)
            .Select(g => new
            {
                CampaignId = g.Key,
                TotalImpressions = g.Sum(m => m.Impressions),
                TotalClicks = g.Sum(m => m.Clicks),
                TotalSpend = g.Sum(m => m.Spend),
                TotalRevenue = g.Sum(m => m.Revenue)
            })
            .ToListAsync();

        var topCampaigns = metric.ToLower() switch
        {
            "spend" => campaigns.OrderByDescending(c => c.TotalSpend).Take(limit)
                .Select(c => new TopCampaignDto(c.CampaignId, $"Campaign {c.CampaignId.ToString()[..8]}", 
c.TotalSpend, "Spend")).ToList(),
            "impressions" => campaigns.OrderByDescending(c => c.TotalImpressions).Take(limit)
                .Select(c => new TopCampaignDto(c.CampaignId, $"Campaign {c.CampaignId.ToString()[..8]}", 
                    c.TotalImpressions, "Impressions")).ToList(),
            "clicks" => campaigns.OrderByDescending(c => c.TotalClicks).Take(limit)
                .Select(c => new TopCampaignDto(c.CampaignId, $"Campaign {c.CampaignId.ToString()[..8]}", 
c.TotalClicks, "Clicks")).ToList(),
            "revenue" => campaigns.OrderByDescending(c => c.TotalRevenue).Take(limit)
                .Select(c => new TopCampaignDto(c.CampaignId, $"Campaign {c.CampaignId.ToString()[..8]}", 
                    c.TotalRevenue, "Revenue")).ToList(),
            "roas" => campaigns.Where(c => c.TotalSpend > 0)
                .OrderByDescending(c => c.TotalRevenue / c.TotalSpend).Take(limit)
                .Select(c => new TopCampaignDto(c.CampaignId, $"Campaign {c.CampaignId.ToString()[..8]}", 
                    c.TotalRevenue / c.TotalSpend, "ROAS")).ToList(),
            _ => new List<TopCampaignDto>()
        };

        _logger.LogInformation("Generated top {Limit} campaigns by {Metric}", limit, metric);

        return Ok(topCampaigns);
    }

    /// <summary>
    /// EN: Detect anomalies (placeholder).
    /// VI: Phát hiện bất thường (placeholder).
    /// </summary>
    [HttpGet("anomalies")]
    [ProducesResponseType(StatusCodes.Status501NotImplemented)]
    public IActionResult GetAnomalies()
    {
        _logger.LogWarning("GetAnomalies not yet implemented");
        return StatusCode(StatusCodes.Status501NotImplemented,
            new { message = "Anomaly detection will be implemented in future version with ML models" });
    }
}
