using System.Text;
using System.Text.Json;

namespace DoliMiddlewareApi.Services.Notifications;

/// <summary>
/// Envía notificaciones a un webhook de Teams o Slack cuando cambia el estado de una factura.
/// Compatible con Teams (Adaptive Cards) y Slack (Block Kit).
/// Configurar la URL en appsettings: Notifications:WebhookUrl
/// </summary>
public class WebhookNotificationService(
    IHttpClientFactory httpClientFactory,
    WebhookSettings webhookSettings,
    ILogger<WebhookNotificationService> logger) : INotificationService
{
    private static readonly Dictionary<string, (string label, string color)> StatusMeta = new()
    {
        ["draft"]  = ("Borrador",  "#8a7dff"),
        ["unpaid"] = ("Pendiente de pago", "#ffb454"),
        ["paid"]   = ("Pagada ✓",  "#5dd39e"),
    };

    public async Task NotifyInvoiceStatusChangedAsync(int invoiceId, string invoiceRef, string newStatus)
    {
        var webhookUrl = webhookSettings.WebhookUrl;
        if (string.IsNullOrWhiteSpace(webhookUrl))
            return; // Notificaciones desactivadas — no hay webhook configurado

        var (label, color) = StatusMeta.GetValueOrDefault(newStatus, (newStatus, "#888"));

        var payload = BuildPayload(invoiceId, invoiceRef, label, color);

        _ = SendAsync(webhookUrl, payload, invoiceId);
    }

    private async Task SendAsync(string url, object payload, int invoiceId)
    {
        try
        {
            var client = httpClientFactory.CreateClient("Webhook");
            var content = new StringContent(
                JsonSerializer.Serialize(payload), Encoding.UTF8, "application/json");
            var response = await client.PostAsync(url, content);
            if (!response.IsSuccessStatusCode)
                logger.LogWarning("Webhook respondió {Status} para factura {Id}",
                    response.StatusCode, invoiceId);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "Error enviando notificación para factura {Id}", invoiceId);
        }
    }

    /// <summary>
    /// Construye un payload compatible con Teams (Adaptive Card via Incoming Webhook)
    /// y con Slack (message payload básico con attachments).
    /// Teams espera { "type": "message", "attachments": [...] } con Adaptive Card.
    /// Slack espera { "text": "...", "attachments": [...] }.
    /// Detectamos por URL cuál usar.
    /// </summary>
    private object BuildPayload(int invoiceId, string invoiceRef, string label, string color)
    {
        var webhookUrl = webhookSettings.WebhookUrl ?? "";

        if (webhookUrl.Contains("slack.com"))
        {
            return new
            {
                text = $"🧾 Factura *{invoiceRef}* ha cambiado de estado",
                attachments = new[]
                {
                    new
                    {
                        color,
                        fields = new[]
                        {
                            new { title = "Factura", value = invoiceRef, @short = true },
                            new { title = "Estado",  value = label,      @short = true },
                        }
                    }
                }
            };
        }

        // Teams — Adaptive Card
        return new
        {
            type = "message",
            attachments = new[]
            {
                new
                {
                    contentType = "application/vnd.microsoft.card.adaptive",
                    content = new
                    {
                        type    = "AdaptiveCard",
                        version = "1.2",
                        body = new object[]
                        {
                            new
                            {
                                type   = "TextBlock",
                                text   = "🧾 Estado de factura actualizado",
                                weight = "Bolder",
                                size   = "Medium"
                            },
                            new
                            {
                                type  = "FactSet",
                                facts = new[]
                                {
                                    new { title = "Factura", value = invoiceRef },
                                    new { title = "ID",      value = invoiceId.ToString() },
                                    new { title = "Estado",  value = label },
                                }
                            }
                        },
                        msteams = new { width = "Full" }
                    }
                }
            }
        };
    }
}
