using TakeoutSaaS.Application.App.Members.StoredCard.Commands;
using TakeoutSaaS.Application.App.Members.StoredCard.Dto;
using TakeoutSaaS.Domain.Membership.Entities;
using TakeoutSaaS.Domain.Membership.Enums;
using TakeoutSaaS.Domain.Membership.Repositories;

namespace TakeoutSaaS.Application.App.Members.StoredCard;

/// <summary>
/// 储值卡 DTO 构造器。
/// </summary>
internal static class MemberStoredCardDtoFactory
{
    public static MemberStoredCardPlanAggregateSnapshot EmptyAggregate(long planId)
    {
        return new MemberStoredCardPlanAggregateSnapshot
        {
            PlanId = planId,
            RechargeCount = 0,
            TotalRechargeAmount = 0m
        };
    }

    public static MemberStoredCardPlanDto ToPlanDto(
        MemberStoredCardPlan source,
        MemberStoredCardPlanAggregateSnapshot aggregate)
    {
        return new MemberStoredCardPlanDto
        {
            PlanId = source.Id,
            RechargeAmount = decimal.Round(source.RechargeAmount, 2, MidpointRounding.AwayFromZero),
            GiftAmount = decimal.Round(source.GiftAmount, 2, MidpointRounding.AwayFromZero),
            ArrivedAmount = decimal.Round(source.RechargeAmount + source.GiftAmount, 2, MidpointRounding.AwayFromZero),
            SortOrder = source.SortOrder,
            Status = MemberStoredCardMapping.ToPlanStatusText(source.Status),
            RechargeCount = aggregate.RechargeCount,
            TotalRechargeAmount = decimal.Round(aggregate.TotalRechargeAmount, 2, MidpointRounding.AwayFromZero)
        };
    }

    public static MemberStoredCardPlanStatsDto ToPlanStatsDto(MemberStoredCardPlanStatsSnapshot source)
    {
        return new MemberStoredCardPlanStatsDto
        {
            TotalRechargeAmount = decimal.Round(source.TotalRechargeAmount, 2, MidpointRounding.AwayFromZero),
            TotalGiftAmount = decimal.Round(source.TotalGiftAmount, 2, MidpointRounding.AwayFromZero),
            CurrentMonthRechargeAmount = decimal.Round(source.CurrentMonthRechargeAmount, 2, MidpointRounding.AwayFromZero),
            RechargeMemberCount = source.RechargeMemberCount
        };
    }

    public static MemberStoredCardRechargeRecordDto ToRechargeRecordDto(MemberStoredCardRechargeRecord source)
    {
        return new MemberStoredCardRechargeRecordDto
        {
            RecordId = source.Id,
            RecordNo = source.RecordNo,
            MemberId = source.MemberId,
            MemberName = source.MemberName,
            MemberMobileMasked = source.MemberMobileMasked,
            RechargeAmount = decimal.Round(source.RechargeAmount, 2, MidpointRounding.AwayFromZero),
            GiftAmount = decimal.Round(source.GiftAmount, 2, MidpointRounding.AwayFromZero),
            ArrivedAmount = decimal.Round(source.ArrivedAmount, 2, MidpointRounding.AwayFromZero),
            PaymentMethod = MemberStoredCardMapping.ToPaymentMethodText(source.PaymentMethod),
            RechargedAt = source.RechargedAt,
            PlanId = source.PlanId,
            Remark = source.Remark
        };
    }

    public static MemberStoredCardPlan CreatePlanEntity(
        SaveStoredCardPlanCommand request,
        decimal normalizedRechargeAmount,
        decimal normalizedGiftAmount,
        int normalizedSortOrder,
        MemberStoredCardPlanStatus status)
    {
        return new MemberStoredCardPlan
        {
            StoreId = request.StoreId,
            RechargeAmount = normalizedRechargeAmount,
            GiftAmount = normalizedGiftAmount,
            SortOrder = normalizedSortOrder,
            Status = status
        };
    }
}
