package com.starry.admin.modules.blindbox.service;

import com.starry.admin.common.exception.CustomException;
import com.starry.admin.modules.blindbox.module.entity.BlindBoxRewardEntity;
import com.starry.admin.modules.order.module.constant.OrderConstant;
import com.starry.admin.modules.order.module.dto.CommodityInfo;
import com.starry.admin.modules.order.module.dto.OrderCreationContext;
import com.starry.admin.modules.order.module.dto.OrderPlacementCommand;
import com.starry.admin.modules.order.module.dto.OrderPlacementResult;
import com.starry.admin.modules.order.module.dto.PaymentInfo;
import com.starry.admin.modules.order.service.IOrderLifecycleService;
import com.starry.admin.modules.order.service.IPlayOrderInfoService;
import com.starry.admin.modules.shop.module.entity.PlayGiftInfoEntity;
import com.starry.admin.modules.shop.service.IPlayClerkGiftInfoService;
import com.starry.admin.modules.shop.service.IPlayGiftInfoService;
import com.starry.common.utils.IdUtils;
import java.math.BigDecimal;
import java.util.Collections;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class BlindBoxDispatchService {

    private final IOrderLifecycleService orderLifecycleService;
    private final IPlayOrderInfoService orderInfoService;
    private final IPlayGiftInfoService giftInfoService;
    private final IPlayClerkGiftInfoService clerkGiftInfoService;

    @Transactional(rollbackFor = Exception.class)
    public OrderPlacementResult dispatchRewardOrder(BlindBoxRewardEntity reward, String clerkId) {
        PlayGiftInfoEntity giftInfo = giftInfoService.selectPlayGiftInfoById(reward.getRewardGiftId());
        if (giftInfo == null) {
            throw new CustomException("奖励礼物不存在或已下架");
        }

        BigDecimal rewardPrice = reward.getRewardPrice();
        PaymentInfo paymentInfo = PaymentInfo.builder()
                .orderMoney(rewardPrice)
                .finalAmount(rewardPrice)
                .discountAmount(BigDecimal.ZERO)
                .couponIds(Collections.emptyList())
                .payMethod(OrderConstant.PayMethod.BALANCE.getCode())
                .paymentSource(OrderConstant.PaymentSource.BLIND_BOX)
                .build();

        CommodityInfo commodityInfo = CommodityInfo.builder()
                .commodityId(giftInfo.getId())
                .commodityType(OrderConstant.CommodityType.GIFT)
                .commodityPrice(giftInfo.getPrice())
                .commodityName(giftInfo.getName())
                .commodityNumber("1")
                .serviceDuration("")
                .build();

        OrderCreationContext context = OrderCreationContext.builder()
                .orderId(IdUtils.getUuid())
                .orderNo(orderInfoService.getOrderNo())
                .orderStatus(OrderConstant.OrderStatus.COMPLETED)
                .orderType(OrderConstant.OrderType.GIFT)
                .placeType(OrderConstant.PlaceType.REWARD)
                .rewardType(OrderConstant.RewardType.GIFT)
                .paymentSource(OrderConstant.PaymentSource.BLIND_BOX)
                .sourceRewardId(reward.getId())
                .paymentInfo(paymentInfo)
                .commodityInfo(commodityInfo)
                .purchaserBy(reward.getCustomerId())
                .acceptBy(clerkId)
                .creatorActor(OrderConstant.OrderActor.CUSTOMER)
                .creatorId(reward.getCustomerId())
                .remark("盲盒奖励兑现")
                .build();

        OrderPlacementResult result = orderLifecycleService.placeOrder(OrderPlacementCommand.builder()
                .orderContext(context)
                .balanceOperationAction("盲盒奖励兑现")
                .build());
        if (clerkId != null) {
            clerkGiftInfoService.incrementGiftCount(clerkId, giftInfo.getId(), reward.getTenantId(), 1);
        }
        return result;
    }
}
