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

namespace TakeoutSaaS.Application.App.Coupons.Seckill;

/// <summary>
/// 秒杀 DTO 映射工厂。
/// </summary>
internal static class SeckillDtoFactory
{
    /// <summary>
    /// 构建列表项 DTO。
    /// </summary>
    public static SeckillListItemDto ToListItemDto(
        PromotionCampaign campaign,
        SeckillRulesDto rules,
        DateTime nowUtc)
    {
        var displayStatus = SeckillMapping.ResolveDisplayStatus(campaign, rules, nowUtc);
        return new SeckillListItemDto
        {
            Id = campaign.Id,
            Name = campaign.Name,
            Status = SeckillMapping.ToStatusText(campaign.Status),
            DisplayStatus = displayStatus,
            IsDimmed = SeckillMapping.IsDimmed(displayStatus),
            UpdatedAt = campaign.UpdatedAt ?? campaign.CreatedAt,
            Rules = rules
        };
    }

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

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

        var totalParticipantCount = items.Sum(item => item.Rules.Metrics.ParticipantCount);
        var totalDealCount = items.Sum(item => item.Rules.Metrics.DealCount);

        decimal conversionRate = 0m;
        if (totalParticipantCount > 0)
        {
            conversionRate = decimal.Round(
                totalDealCount * 100m / totalParticipantCount,
                2,
                MidpointRounding.AwayFromZero);
        }

        return new SeckillStatsDto
        {
            TotalCount = items.Count,
            OngoingCount = items.Count(item => string.Equals(item.DisplayStatus, "ongoing", StringComparison.Ordinal)),
            MonthlySeckillSalesCount = items.Sum(item => item.Rules.Metrics.MonthlySeckillSalesCount),
            ConversionRate = conversionRate
        };
    }

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