using Asp.Versioning;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using AdsTrackingService.API.Application.Commands;
using AdsTrackingService.API.Application.Queries;

namespace AdsTrackingService.API.Controllers;

/// <summary>
/// EN: Controller for conversion tracking and attribution.
/// VI: Controller theo dõi conversion và attribution.
/// </summary>
[ApiController]
[Authorize]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/ads-tracking/conversions")]
public class ConversionsController : ControllerBase
{
    private readonly IMediator _mediator;
    private readonly ILogger<ConversionsController> _logger;

    public ConversionsController(IMediator mediator, ILogger<ConversionsController> logger)
    {
        _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    /// <summary>
    /// EN: Record a new conversion event.
    /// VI: Ghi nhận sự kiện conversion mới.
    /// </summary>
    [HttpPost]
    [ProducesResponseType(typeof(ConversionResult), StatusCodes.Status201Created)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> RecordConversion(
        [FromBody] RecordConversionRequest request,
        CancellationToken ct)
    {
        var command = new RecordConversionCommand(
            request.AdvertiserId,
            request.CampaignId,
            request.UserId,
            request.ConversionType,
            request.ConversionValue,
            request.Currency ?? "VND"
        );

        var result = await _mediator.Send(command, ct);

        _logger.LogInformation(
            "Recorded conversion: Id={ConversionId}, Campaign={CampaignId}, Type={ConversionType}",
            result.ConversionId, request.CampaignId, request.ConversionType);

        return CreatedAtAction(null, new { success = true, data = result });
    }

    /// <summary>
    /// EN: Get conversions with optional filtering.
    /// VI: Lấy danh sách conversions với bộ lọc tùy chọn.
    /// </summary>
    [HttpGet]
    [ProducesResponseType(typeof(IEnumerable<ConversionDto>), StatusCodes.Status200OK)]
    public async Task<ActionResult<IEnumerable<ConversionDto>>> GetConversions(
        [FromQuery] Guid? campaignId = null,
        [FromQuery] Guid? userId = null,
        [FromQuery] DateTime? from = null,
        [FromQuery] DateTime? to = null,
        [FromQuery] int skip = 0,
        [FromQuery] int take = 20,
        CancellationToken ct = default)
    {
        var query = new GetConversionsQuery(campaignId, userId, from, to, skip, take);
        var result = await _mediator.Send(query, ct);

        return Ok(new { success = true, data = result });
    }

    /// <summary>
    /// EN: Get attribution details for a specific conversion.
    /// VI: Lấy chi tiết attribution cho conversion cụ thể.
    /// </summary>
    [HttpGet("{id:guid}/attribution")]
    [ProducesResponseType(typeof(AttributionDto), StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public async Task<ActionResult<AttributionDto>> GetAttributionDetails(
        Guid id,
        CancellationToken ct)
    {
        var query = new GetAttributionDetailsQuery(id);
        var result = await _mediator.Send(query, ct);

        if (result == null)
        {
            return NotFound(new { success = false, error = new { code = "NOT_FOUND", message = "Attribution not found for this conversion" } });
        }

        return Ok(new { success = true, data = result });
    }
}

/// <summary>
/// EN: Request to record a conversion event.
/// VI: Request ghi nhận sự kiện conversion.
/// </summary>
public record RecordConversionRequest(
    Guid AdvertiserId,
    Guid CampaignId,
    Guid UserId,
    string ConversionType,
    decimal ConversionValue,
    string? Currency
);
