using Asp.Versioning; using MediatR; using Microsoft.AspNetCore.Mvc; using AdsTrackingService.API.Application.Queries; namespace AdsTrackingService.API.Controllers.Admin; /// /// EN: Admin controller for conversion reports and analytics. /// VI: Controller admin cho báo cáo conversion và phân tích. /// [ApiController] [ApiVersion("1.0")] [Route("api/v{version:apiVersion}/admin/ads-tracking/conversions")] public class AdminConversionsController : ControllerBase { private readonly IMediator _mediator; private readonly ILogger _logger; public AdminConversionsController(IMediator mediator, ILogger logger) { _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); } /// /// EN: Get all conversions with filters and pagination. /// VI: Lấy tất cả conversions với bộ lọc và phân trang. /// [HttpGet] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] public async Task>> GetConversions( [FromQuery] Guid? advertiserId = null, [FromQuery] Guid? campaignId = null, [FromQuery] string? conversionType = null, [FromQuery] DateTime? from = null, [FromQuery] DateTime? to = null, [FromQuery] int page = 1, [FromQuery] int pageSize = 20, CancellationToken ct = default) { var query = new GetConversionsQuery( campaignId, null, // userId from, to, (page - 1) * pageSize, pageSize ); var result = await _mediator.Send(query, ct); _logger.LogInformation("Admin: Listed {Count} conversions", result.Count()); return Ok(result); } /// /// EN: Get conversion statistics. /// VI: Lấy thống kê conversion. /// [HttpGet("stats")] [ProducesResponseType(typeof(ConversionStatsDto), StatusCodes.Status200OK)] public async Task> GetConversionStats( [FromQuery] Guid? campaignId = null, [FromQuery] DateTime? from = null, [FromQuery] DateTime? to = null, CancellationToken ct = default) { var stats = new ConversionStatsDto( TotalConversions: 500, TotalValue: 1000000m, ConversionsByType: new Dictionary { ["purchase"] = 300, ["lead"] = 200 }, AverageValue: 2000m ); _logger.LogInformation("Admin: Retrieved conversion stats"); return Ok(stats); } /// /// EN: Get conversion details by ID. /// VI: Lấy chi tiết conversion theo ID. /// [HttpGet("{id:guid}")] [ProducesResponseType(typeof(ConversionDetailDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> GetConversionDetails( Guid id, CancellationToken ct) { // EN: Would fetch conversion + attribution details // VI: Sẽ lấy conversion + chi tiết attribution var detail = new ConversionDetailDto( id, Guid.NewGuid(), Guid.NewGuid(), Guid.NewGuid(), "purchase", 5000m, "VND", DateTime.UtcNow, Attribution: null ); _logger.LogInformation("Admin: Retrieved conversion details for {ConversionId}", id); return Ok(detail); } } // DTOs for Admin Conversions public record ConversionStatsDto( int TotalConversions, decimal TotalValue, Dictionary ConversionsByType, decimal AverageValue ); public record ConversionDetailDto( Guid Id, Guid AdvertiserId, Guid CampaignId, Guid UserId, string ConversionType, decimal ConversionValue, string Currency, DateTime ConversionTime, AttributionDto? Attribution );