using System.Text.Json;
using Meezi.API.Models.Snappfood;
using Meezi.API.Models.Tap30;
using Meezi.Core.Delivery;
using Meezi.Core.Enums;

namespace Meezi.API.Services.Delivery;

public interface IOrderNormalizer
{
    UnifiedDeliveryOrder? FromSnappfood(SnappfoodWebhookOrder payload);
    UnifiedDeliveryOrder? FromTap30(Tap30WebhookOrder payload);
    UnifiedDeliveryOrder? FromJson(DeliveryPlatform platform, string rawJson);
}

public class OrderNormalizer : IOrderNormalizer
{
    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNameCaseInsensitive = true
    };

    public UnifiedDeliveryOrder? FromSnappfood(SnappfoodWebhookOrder payload)
    {
        if (string.IsNullOrWhiteSpace(payload.OrderId) || string.IsNullOrWhiteSpace(payload.VendorId))
            return null;

        var items = payload.Items.Select(i => new UnifiedDeliveryItem(
            Sku: i.Name,
            Name: i.Name,
            Quantity: i.Quantity,
            UnitPrice: i.UnitPrice,
            Notes: "Snappfood")).ToList();

        if (items.Count == 0)
            return null;

        return new UnifiedDeliveryOrder(
            payload.OrderId.Trim(),
            DeliveryPlatform.Snappfood,
            payload.VendorId.Trim(),
            DateTime.UtcNow,
            new UnifiedDeliveryCustomer(
                payload.CustomerName ?? "Snappfood",
                payload.CustomerPhone ?? ""),
            items,
            new UnifiedDeliveryPayment(
                payload.Total,
                "online",
                true,
                null),
            new UnifiedDeliveryInfo("delivery"),
            UnifiedDeliveryStatus.Confirmed);
    }

    public UnifiedDeliveryOrder? FromTap30(Tap30WebhookOrder payload)
    {
        if (string.IsNullOrWhiteSpace(payload.OrderId) || string.IsNullOrWhiteSpace(payload.VendorId))
            return null;

        var items = (payload.Items ?? [])
            .Where(i => !string.IsNullOrWhiteSpace(i.Name) && i.Quantity > 0)
            .Select(i => new UnifiedDeliveryItem(
                Sku: i.Sku ?? i.Name,
                Name: i.Name,
                Quantity: i.Quantity,
                UnitPrice: i.UnitPrice,
                i.Notes))
            .ToList();

        if (items.Count == 0)
            return null;

        var customer = payload.Customer ?? new Tap30Customer(null, null, null, null, null);
        var deliveryType = string.IsNullOrWhiteSpace(payload.DeliveryType)
            ? "delivery"
            : payload.DeliveryType.Trim().ToLowerInvariant();

        return new UnifiedDeliveryOrder(
            payload.OrderId.Trim(),
            DeliveryPlatform.Tap30,
            payload.VendorId.Trim(),
            DateTime.UtcNow,
            new UnifiedDeliveryCustomer(
                customer.Name ?? "Tap30",
                customer.Phone ?? "",
                customer.Address,
                customer.Lat,
                customer.Lng),
            items,
            new UnifiedDeliveryPayment(
                payload.Total,
                payload.PaymentMethod ?? "online",
                payload.IsPaid ?? true,
                payload.Commission),
            new UnifiedDeliveryInfo(
                deliveryType,
                payload.EstimatedMinutes,
                payload.DriverName,
                payload.DriverPhone),
            MapTap30Status(payload.Status));
    }

    public UnifiedDeliveryOrder? FromJson(DeliveryPlatform platform, string rawJson)
    {
        return platform switch
        {
            DeliveryPlatform.Snappfood => FromSnappfood(
                JsonSerializer.Deserialize<SnappfoodWebhookOrder>(rawJson, JsonOptions)!),
            DeliveryPlatform.Tap30 => FromTap30(
                JsonSerializer.Deserialize<Tap30WebhookOrder>(rawJson, JsonOptions)!),
            _ => null
        };
    }

    private static UnifiedDeliveryStatus MapTap30Status(string? status) =>
        status?.Trim().ToLowerInvariant() switch
        {
            "pending" => UnifiedDeliveryStatus.Pending,
            "confirmed" => UnifiedDeliveryStatus.Confirmed,
            "preparing" or "in_progress" => UnifiedDeliveryStatus.Preparing,
            "ready" => UnifiedDeliveryStatus.Ready,
            "delivered" or "completed" => UnifiedDeliveryStatus.Delivered,
            "cancelled" or "canceled" => UnifiedDeliveryStatus.Cancelled,
            _ => UnifiedDeliveryStatus.Confirmed
        };
}
