using Meezi.API.Models.Delivery;
using Meezi.Core.Enums;
using Meezi.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;

namespace Meezi.API.Services.Delivery;

public interface IDeliveryFinanceReportService
{
    Task<DeliveryRevenueReportDto> GetRevenueByPlatformAsync(
        string cafeId,
        DateTime utcFrom,
        DateTime utcTo,
        CancellationToken ct = default);
}

public class DeliveryFinanceReportService : IDeliveryFinanceReportService
{
    private static readonly OrderStatus[] RevenueStatuses =
    [
        OrderStatus.Confirmed,
        OrderStatus.Preparing,
        OrderStatus.Ready,
        OrderStatus.Delivered
    ];

    private readonly AppDbContext _db;

    public DeliveryFinanceReportService(AppDbContext db) => _db = db;

    public async Task<DeliveryRevenueReportDto> GetRevenueByPlatformAsync(
        string cafeId,
        DateTime utcFrom,
        DateTime utcTo,
        CancellationToken ct = default)
    {
        var orders = await _db.Orders
            .Where(o => o.CafeId == cafeId
                && o.DeliveryPlatform != null
                && o.CreatedAt >= utcFrom
                && o.CreatedAt < utcTo
                && RevenueStatuses.Contains(o.Status))
            .ToListAsync(ct);

        var platforms = Enum.GetValues<DeliveryPlatform>()
            .Where(p => p != DeliveryPlatform.Direct)
            .Select(platform =>
            {
                var subset = orders.Where(o => o.DeliveryPlatform == platform).ToList();
                var gross = subset.Sum(o => o.Total);
                var commission = subset.Sum(o => o.PlatformCommission);
                return new PlatformRevenueDto(
                    platform,
                    PlatformLabel(platform),
                    subset.Count,
                    gross,
                    commission,
                    gross - commission);
            })
            .Where(p => p.OrderCount > 0)
            .ToList();

        return new DeliveryRevenueReportDto(
            $"{utcFrom:yyyy-MM-dd} — {utcTo:yyyy-MM-dd}",
            utcFrom,
            utcTo,
            platforms,
            platforms.Sum(p => p.GrossRevenue),
            platforms.Sum(p => p.Commission),
            platforms.Sum(p => p.NetRevenue));
    }

    private static string PlatformLabel(DeliveryPlatform platform) => platform switch
    {
        DeliveryPlatform.Snappfood => "اسنپ‌فود",
        DeliveryPlatform.Tap30 => "تپسی",
        DeliveryPlatform.Digikala => "دیجی‌کالا",
        _ => platform.ToString()
    };
}
