using TakeoutSaaS.Application.App.Coupons.FullReduction.Dto;
using TakeoutSaaS.Domain.Coupons.Entities;
using TakeoutSaaS.Domain.Coupons.Enums;

namespace TakeoutSaaS.Application.App.Coupons.FullReduction;

/// <summary>
/// 满减活动 DTO 映射工厂。
/// </summary>
internal static class FullReductionDtoFactory
{
    /// <summary>
    /// 构建列表项 DTO。
    /// </summary>
    public static FullReductionListItemDto ToListItemDto(
        PromotionCampaign campaign,
        FullReductionRulesDto rules,
        DateTime nowUtc)
    {
        var displayStatus = FullReductionMapping.ResolveDisplayStatus(campaign, nowUtc);
        return new FullReductionListItemDto
        {
            Id = campaign.Id,
            Name = campaign.Name,
            StartAt = campaign.StartAt,
            EndAt = campaign.EndAt,
            DisplayStatus = displayStatus,
            IsDimmed = FullReductionMapping.IsDimmed(displayStatus),
            UpdatedAt = campaign.UpdatedAt ?? campaign.CreatedAt,
            Rules = rules
        };
    }

    /// <summary>
    /// 构建详情 DTO。
    /// </summary>
    public static FullReductionDetailDto ToDetailDto(
        PromotionCampaign campaign,
        FullReductionRulesDto rules,
        DateTime nowUtc)
    {
        return new FullReductionDetailDto
        {
            Id = campaign.Id,
            Name = campaign.Name,
            StartAt = campaign.StartAt,
            EndAt = campaign.EndAt,
            Status = FullReductionMapping.ToStatusText(campaign.Status),
            DisplayStatus = FullReductionMapping.ResolveDisplayStatus(campaign, nowUtc),
            UpdatedAt = campaign.UpdatedAt ?? campaign.CreatedAt,
            Rules = rules
        };
    }

    /// <summary>
    /// 构建统计 DTO。
    /// </summary>
    public static FullReductionStatsDto ToStatsDto(IReadOnlyCollection<FullReductionListItemDto> items)
    {
        if (items.Count == 0)
        {
            return new FullReductionStatsDto();
        }

        var monthlyDrivenSalesAmount = items.Sum(item => item.Rules.Metrics.MonthlyDrivenSalesAmount);

        var metricsForAverage = items
            .Select(item => item.Rules.Metrics.AverageTicketIncrease)
            .Where(value => value > 0)
            .ToList();

        var averageTicketIncrease = metricsForAverage.Count == 0
            ? 0m
            : decimal.Round(metricsForAverage.Average(), 2, MidpointRounding.AwayFromZero);

        return new FullReductionStatsDto
        {
            TotalCount = items.Count,
            OngoingCount = items.Count(item => string.Equals(item.DisplayStatus, "ongoing", StringComparison.Ordinal)),
            MonthlyDrivenSalesAmount = decimal.Round(monthlyDrivenSalesAmount, 2, MidpointRounding.AwayFromZero),
            AverageTicketIncrease = averageTicketIncrease
        };
    }

    /// <summary>
    /// 构建默认新增活动实体。
    /// </summary>
    public static PromotionCampaign CreateNewCampaign(
        string name,
        DateTime startAt,
        DateTime endAt,
        string rulesJson,
        string? description)
    {
        return new PromotionCampaign
        {
            Name = name,
            PromotionType = PromotionType.FullReduction,
            Status = PromotionStatus.Active,
            StartAt = startAt,
            EndAt = endAt,
            RulesJson = rulesJson,
            AudienceDescription = description,
            Budget = null,
            BannerUrl = null
        };
    }
}
