using System.Globalization;
using ApiDenuncias.Services;
using GestionaDenuncias.Shared.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace ApiDenuncias.Controllers;

[ApiController]
[Authorize(Policy = "ConfigurationAdministrators")]
[Route("api/purge")]
public sealed class PurgeController : ControllerBase
{
    private readonly ManualPurgeService _manualPurgeService;
    private readonly ILogger<PurgeController> _logger;

    public PurgeController(
        ManualPurgeService manualPurgeService,
        ILogger<PurgeController> logger)
    {
        _manualPurgeService = manualPurgeService;
        _logger = logger;
    }

    [HttpPost("manual/current")]
    public Task<ActionResult<ManualPurgeResponse>> ExecuteCurrentManualPurge(CancellationToken cancellationToken)
        => ExecuteManualPurgeCore(DateOnly.FromDateTime(DateTime.UtcNow), cancellationToken);

    [HttpPost("manual")]
    public async Task<ActionResult<ManualPurgeResponse>> ExecuteManualPurge(
        ManualPurgeRequest request,
        CancellationToken cancellationToken)
    {
        if (string.IsNullOrWhiteSpace(request.Date) ||
            !DateOnly.TryParseExact(
                request.Date.Trim(),
                "yyyy-MM-dd",
                CultureInfo.InvariantCulture,
                DateTimeStyles.None,
                out var purgeDate))
        {
            return BadRequest(new ApiError("Debes indicar una fecha valida con formato YYYY-MM-DD."));
        }

        return await ExecuteManualPurgeCore(purgeDate, cancellationToken);
    }

    private async Task<ActionResult<ManualPurgeResponse>> ExecuteManualPurgeCore(
        DateOnly purgeDate,
        CancellationToken cancellationToken)
    {
        try
        {
            var result = await _manualPurgeService.ExecuteAsync(purgeDate, cancellationToken);
            return Ok(result);
        }
        catch (OperationCanceledException) when (!cancellationToken.IsCancellationRequested)
        {
            return StatusCode(
                StatusCodes.Status504GatewayTimeout,
                new ApiError("La Function App de purga no ha respondido dentro del tiempo configurado."));
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogError(ex, "No se ha podido ejecutar la purga manual para {Date}.", purgeDate);
            return StatusCode(
                StatusCodes.Status502BadGateway,
                new ApiError(ex.Message));
        }
    }
}
