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

namespace TakeoutSaaS.Application.App.Coupons;

/// <summary>
/// 优惠券模板 DTO 映射工厂。
/// </summary>
internal static class CouponTemplateDtoFactory
{
    public static CouponTemplateListItemDto ToListItemDto(
        CouponTemplate template,
        CouponStoreScopeModel storeScope,
        IReadOnlyList<string> channels,
        int redeemedQuantity,
        DateTime nowUtc)
    {
        var displayStatus = CouponTemplateMapping.ResolveDisplayStatus(template, nowUtc);
        return new CouponTemplateListItemDto
        {
            Id = template.Id,
            Name = template.Name,
            CouponType = CouponTemplateMapping.ToCouponTypeText(template.CouponType),
            Value = template.Value,
            MinimumSpend = template.MinimumSpend,
            ValidFrom = template.ValidFrom,
            ValidTo = template.ValidTo,
            RelativeValidDays = template.RelativeValidDays,
            TotalQuantity = template.TotalQuantity ?? 0,
            ClaimedQuantity = template.ClaimedQuantity,
            RedeemedQuantity = redeemedQuantity,
            PerUserLimit = template.PerUserLimit,
            DisplayStatus = displayStatus,
            IsDimmed = CouponTemplateMapping.IsDimmedDisplayStatus(displayStatus),
            StoreScopeMode = storeScope.Mode,
            StoreIds = storeScope.StoreIds,
            Channels = channels,
            UpdatedAt = template.UpdatedAt ?? template.CreatedAt
        };
    }

    public static CouponTemplateDetailDto ToDetailDto(
        CouponTemplate template,
        CouponStoreScopeModel storeScope,
        IReadOnlyList<string> channels)
    {
        return new CouponTemplateDetailDto
        {
            Id = template.Id,
            Name = template.Name,
            CouponType = CouponTemplateMapping.ToCouponTypeText(template.CouponType),
            Value = template.Value,
            MinimumSpend = template.MinimumSpend,
            TotalQuantity = template.TotalQuantity ?? 0,
            ClaimedQuantity = template.ClaimedQuantity,
            PerUserLimit = template.PerUserLimit,
            ValidityType = CouponTemplateMapping.ResolveValidityType(template),
            ValidFrom = template.ValidFrom,
            ValidTo = template.ValidTo,
            RelativeValidDays = template.RelativeValidDays,
            Channels = channels,
            StoreScopeMode = storeScope.Mode,
            StoreIds = storeScope.StoreIds,
            Status = CouponTemplateMapping.ToEditorStatus(template.Status),
            UpdatedAt = template.UpdatedAt ?? template.CreatedAt
        };
    }

    public static CouponTemplateStatsDto ToStatsDto(
        int totalCount,
        int ongoingCount,
        int claimedCount,
        int redeemedCount)
    {
        var redeemRate = claimedCount <= 0
            ? 0m
            : Math.Round((decimal)redeemedCount * 100m / claimedCount, 1, MidpointRounding.AwayFromZero);

        return new CouponTemplateStatsDto
        {
            TotalCount = totalCount,
            OngoingCount = ongoingCount,
            ClaimedCount = claimedCount,
            RedeemedCount = redeemedCount,
            RedeemRate = redeemRate
        };
    }
}
