// ==============================================================================
// MORPH-SPEC - Asaas Webhook Controller Template
// Controller para receber webhooks do Asaas
// ==============================================================================

using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace {{Namespace}}.Web.Controllers;

// ==============================================================================
// CONTROLLER
// ==============================================================================

[ApiController]
[Route("api/webhooks/asaas")]
public class AsaasWebhookController : ControllerBase
{
    private readonly IAsaasWebhookHandler _webhookHandler;
    private readonly ILogger<AsaasWebhookController> _logger;

    public AsaasWebhookController(
        IAsaasWebhookHandler webhookHandler,
        ILogger<AsaasWebhookController> logger)
    {
        _webhookHandler = webhookHandler;
        _logger = logger;
    }

    [HttpPost]
    public async Task<IActionResult> HandleWebhook([FromBody] AsaasWebhookPayload payload)
    {
        _logger.LogInformation("Received Asaas webhook: {Event}", payload.Event);

        try
        {
            await _webhookHandler.HandleAsync(payload);
            return Ok();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error processing Asaas webhook: {Event}", payload.Event);
            // Retorna 200 para evitar retentativas desnecessárias
            // O erro será tratado internamente
            return Ok();
        }
    }
}

// ==============================================================================
// WEBHOOK HANDLER INTERFACE
// ==============================================================================

public interface IAsaasWebhookHandler
{
    Task HandleAsync(AsaasWebhookPayload payload, CancellationToken ct = default);
}

// ==============================================================================
// WEBHOOK HANDLER IMPLEMENTATION
// ==============================================================================

public class AsaasWebhookHandler : IAsaasWebhookHandler
{
    private readonly IPaymentService _paymentService;
    private readonly ISubscriptionService _subscriptionService;
    private readonly ILogger<AsaasWebhookHandler> _logger;

    public AsaasWebhookHandler(
        IPaymentService paymentService,
        ISubscriptionService subscriptionService,
        ILogger<AsaasWebhookHandler> logger)
    {
        _paymentService = paymentService;
        _subscriptionService = subscriptionService;
        _logger = logger;
    }

    public async Task HandleAsync(AsaasWebhookPayload payload, CancellationToken ct = default)
    {
        _logger.LogInformation("Processing Asaas webhook: {Event} for {PaymentId}",
            payload.Event, payload.Payment?.Id ?? "N/A");

        switch (payload.Event)
        {
            // =========================================================
            // PAYMENT EVENTS
            // =========================================================

            case AsaasWebhookEvents.PaymentCreated:
                await HandlePaymentCreatedAsync(payload, ct);
                break;

            case AsaasWebhookEvents.PaymentAwaitingRiskAnalysis:
                await HandlePaymentAwaitingRiskAsync(payload, ct);
                break;

            case AsaasWebhookEvents.PaymentPending:
                await HandlePaymentPendingAsync(payload, ct);
                break;

            case AsaasWebhookEvents.PaymentConfirmed:
            case AsaasWebhookEvents.PaymentReceived:
                await HandlePaymentConfirmedAsync(payload, ct);
                break;

            case AsaasWebhookEvents.PaymentOverdue:
                await HandlePaymentOverdueAsync(payload, ct);
                break;

            case AsaasWebhookEvents.PaymentRefunded:
            case AsaasWebhookEvents.PaymentRefundInProgress:
                await HandlePaymentRefundedAsync(payload, ct);
                break;

            case AsaasWebhookEvents.PaymentChargebackRequested:
            case AsaasWebhookEvents.PaymentChargebackDispute:
                await HandlePaymentChargebackAsync(payload, ct);
                break;

            case AsaasWebhookEvents.PaymentDeleted:
                await HandlePaymentDeletedAsync(payload, ct);
                break;

            // =========================================================
            // SUBSCRIPTION EVENTS
            // =========================================================

            case AsaasWebhookEvents.SubscriptionCreated:
                await HandleSubscriptionCreatedAsync(payload, ct);
                break;

            case AsaasWebhookEvents.SubscriptionUpdated:
                await HandleSubscriptionUpdatedAsync(payload, ct);
                break;

            case AsaasWebhookEvents.SubscriptionDeleted:
                await HandleSubscriptionDeletedAsync(payload, ct);
                break;

            default:
                _logger.LogWarning("Unhandled Asaas webhook event: {Event}", payload.Event);
                break;
        }
    }

    // =========================================================================
    // PAYMENT HANDLERS
    // =========================================================================

    private async Task HandlePaymentCreatedAsync(AsaasWebhookPayload payload, CancellationToken ct)
    {
        if (payload.Payment is null) return;

        _logger.LogInformation("Payment created: {PaymentId}", payload.Payment.Id);
        await _paymentService.SyncPaymentAsync(payload.Payment.Id, ct);
    }

    private async Task HandlePaymentAwaitingRiskAsync(AsaasWebhookPayload payload, CancellationToken ct)
    {
        if (payload.Payment is null) return;

        _logger.LogInformation("Payment awaiting risk analysis: {PaymentId}", payload.Payment.Id);
        await _paymentService.UpdateStatusAsync(payload.Payment.Id, PaymentStatus.AwaitingRisk, ct);
    }

    private async Task HandlePaymentPendingAsync(AsaasWebhookPayload payload, CancellationToken ct)
    {
        if (payload.Payment is null) return;

        _logger.LogInformation("Payment pending: {PaymentId}", payload.Payment.Id);
        await _paymentService.UpdateStatusAsync(payload.Payment.Id, PaymentStatus.Pending, ct);
    }

    private async Task HandlePaymentConfirmedAsync(AsaasWebhookPayload payload, CancellationToken ct)
    {
        if (payload.Payment is null) return;

        _logger.LogInformation("Payment confirmed: {PaymentId}, Value: {Value}",
            payload.Payment.Id, payload.Payment.Value);

        await _paymentService.ConfirmPaymentAsync(payload.Payment.Id, ct);
    }

    private async Task HandlePaymentOverdueAsync(AsaasWebhookPayload payload, CancellationToken ct)
    {
        if (payload.Payment is null) return;

        _logger.LogWarning("Payment overdue: {PaymentId}", payload.Payment.Id);
        await _paymentService.MarkOverdueAsync(payload.Payment.Id, ct);
    }

    private async Task HandlePaymentRefundedAsync(AsaasWebhookPayload payload, CancellationToken ct)
    {
        if (payload.Payment is null) return;

        _logger.LogInformation("Payment refunded: {PaymentId}", payload.Payment.Id);
        await _paymentService.RefundPaymentAsync(payload.Payment.Id, ct);
    }

    private async Task HandlePaymentChargebackAsync(AsaasWebhookPayload payload, CancellationToken ct)
    {
        if (payload.Payment is null) return;

        _logger.LogWarning("Payment chargeback: {PaymentId}", payload.Payment.Id);
        await _paymentService.HandleChargebackAsync(payload.Payment.Id, ct);
    }

    private async Task HandlePaymentDeletedAsync(AsaasWebhookPayload payload, CancellationToken ct)
    {
        if (payload.Payment is null) return;

        _logger.LogInformation("Payment deleted: {PaymentId}", payload.Payment.Id);
        await _paymentService.DeletePaymentAsync(payload.Payment.Id, ct);
    }

    // =========================================================================
    // SUBSCRIPTION HANDLERS
    // =========================================================================

    private async Task HandleSubscriptionCreatedAsync(AsaasWebhookPayload payload, CancellationToken ct)
    {
        // Subscription events may not have payment data
        _logger.LogInformation("Subscription created via webhook");
        // Implement as needed
    }

    private async Task HandleSubscriptionUpdatedAsync(AsaasWebhookPayload payload, CancellationToken ct)
    {
        _logger.LogInformation("Subscription updated via webhook");
        // Implement as needed
    }

    private async Task HandleSubscriptionDeletedAsync(AsaasWebhookPayload payload, CancellationToken ct)
    {
        _logger.LogInformation("Subscription deleted via webhook");
        // Implement as needed
    }
}

// ==============================================================================
// WEBHOOK EVENTS
// ==============================================================================

public static class AsaasWebhookEvents
{
    // Payment events
    public const string PaymentCreated = "PAYMENT_CREATED";
    public const string PaymentAwaitingRiskAnalysis = "PAYMENT_AWAITING_RISK_ANALYSIS";
    public const string PaymentPending = "PAYMENT_PENDING";
    public const string PaymentConfirmed = "PAYMENT_CONFIRMED";
    public const string PaymentReceived = "PAYMENT_RECEIVED";
    public const string PaymentOverdue = "PAYMENT_OVERDUE";
    public const string PaymentRefunded = "PAYMENT_REFUNDED";
    public const string PaymentRefundInProgress = "PAYMENT_REFUND_IN_PROGRESS";
    public const string PaymentChargebackRequested = "PAYMENT_CHARGEBACK_REQUESTED";
    public const string PaymentChargebackDispute = "PAYMENT_CHARGEBACK_DISPUTE";
    public const string PaymentDeleted = "PAYMENT_DELETED";

    // Subscription events
    public const string SubscriptionCreated = "SUBSCRIPTION_CREATED";
    public const string SubscriptionUpdated = "SUBSCRIPTION_UPDATED";
    public const string SubscriptionDeleted = "SUBSCRIPTION_DELETED";
}

// ==============================================================================
// WEBHOOK PAYLOAD
// ==============================================================================

public record AsaasWebhookPayload
{
    [JsonPropertyName("event")]
    public string Event { get; init; } = string.Empty;

    [JsonPropertyName("payment")]
    public AsaasWebhookPayment? Payment { get; init; }
}

public record AsaasWebhookPayment
{
    [JsonPropertyName("id")]
    public string Id { get; init; } = string.Empty;

    [JsonPropertyName("customer")]
    public string Customer { get; init; } = string.Empty;

    [JsonPropertyName("value")]
    public decimal Value { get; init; }

    [JsonPropertyName("status")]
    public string Status { get; init; } = string.Empty;

    [JsonPropertyName("billingType")]
    public string BillingType { get; init; } = string.Empty;

    [JsonPropertyName("externalReference")]
    public string? ExternalReference { get; init; }

    [JsonPropertyName("subscription")]
    public string? Subscription { get; init; }
}

// ==============================================================================
// PAYMENT STATUS ENUM
// ==============================================================================

public enum PaymentStatus
{
    Pending,
    AwaitingRisk,
    Confirmed,
    Received,
    Overdue,
    Refunded,
    Chargeback,
    Deleted
}

// ==============================================================================
// SERVICE INTERFACES (to be implemented)
// ==============================================================================

public interface IPaymentService
{
    Task SyncPaymentAsync(string asaasPaymentId, CancellationToken ct = default);
    Task UpdateStatusAsync(string asaasPaymentId, PaymentStatus status, CancellationToken ct = default);
    Task ConfirmPaymentAsync(string asaasPaymentId, CancellationToken ct = default);
    Task MarkOverdueAsync(string asaasPaymentId, CancellationToken ct = default);
    Task RefundPaymentAsync(string asaasPaymentId, CancellationToken ct = default);
    Task HandleChargebackAsync(string asaasPaymentId, CancellationToken ct = default);
    Task DeletePaymentAsync(string asaasPaymentId, CancellationToken ct = default);
}

public interface ISubscriptionService
{
    // Implement as needed
}

// ==============================================================================
// DEPENDENCY INJECTION
// ==============================================================================

public static class AsaasWebhookServiceExtensions
{
    public static IServiceCollection AddAsaasWebhook(this IServiceCollection services)
    {
        services.AddScoped<IAsaasWebhookHandler, AsaasWebhookHandler>();
        return services;
    }
}
