package edu.whut.domain.order.service;

import com.alipay.api.AlipayApiException;
import edu.whut.domain.order.adapter.port.IProductPort;
import edu.whut.domain.order.adapter.repository.IOrderRepository;
import edu.whut.domain.order.model.aggregate.CreateOrderAggregate;
import edu.whut.domain.order.model.entity.*;
import edu.whut.domain.order.model.valobj.MarketTypeVO;
import edu.whut.domain.order.model.valobj.OrderStatusVO;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.util.List;

@Slf4j
public abstract class AbstractOrderService implements IOrderService {

    protected final IOrderRepository repository;
    protected final IProductPort port;

    public AbstractOrderService(IOrderRepository repository, IProductPort port) {
        this.repository = repository;
        this.port = port;
    }

    /**
     * 创建订单
     */
    @Override
    public PayOrderEntity createOrder(ShopCartEntity shopCartEntity) throws Exception {
        // 1. 查询当前用户是否存在掉单或未支付订单
        OrderEntity unpaidOrderEntity = repository.queryUnPayOrder(shopCartEntity);

        // 如果已有未支付订单且状态为“等待支付”，直接复用该订单
        if (unpaidOrderEntity != null
                && OrderStatusVO.PAY_WAIT.equals(unpaidOrderEntity.getOrderStatusVO())) {
            log.info("创建订单-存在，已存在未支付订单。userId:{} productId:{} orderId:{}",
                    shopCartEntity.getUserId(), shopCartEntity.getProductId(), unpaidOrderEntity.getOrderId());
            return PayOrderEntity.builder()
                    .orderId(unpaidOrderEntity.getOrderId())
                    .payUrl(unpaidOrderEntity.getPayUrl())
                    .build();

            // 如果已有订单仅创建了记录但未生成支付单，则进入支付单生成流程
        } else if (unpaidOrderEntity != null
                && OrderStatusVO.CREATE.equals(unpaidOrderEntity.getOrderStatusVO())) {
            log.info("创建订单-存在，存在未创建支付单订单，创建支付单开始 userId:{} productId:{} orderId:{}",
                    shopCartEntity.getUserId(), shopCartEntity.getProductId(), unpaidOrderEntity.getOrderId());

            Integer marketType = unpaidOrderEntity.getMarketType();
            BigDecimal marketDeductionAmount = unpaidOrderEntity.getMarketDeductionAmount();
            PayOrderEntity payOrderEntity;

            // === marketType 分支处理 ===
            if (MarketTypeVO.GROUP_BUY_MARKET.getCode().equals(marketType)
                    && marketDeductionAmount == null) {
                // 1) 是拼团类型，且还未计算优惠（deductionAmount == null）时
                //    先锁定优惠（如拼团满减），获取 discount 对象
                MarketPayDiscountEntity discount = lockMarketPayOrder(
                        shopCartEntity.getUserId(),
                        shopCartEntity.getTeamId(),
                        shopCartEntity.getActivityId(),
                        shopCartEntity.getProductId(),
                        unpaidOrderEntity.getOrderId());
                // 2) 再发起预支付，传入优惠后金额
                payOrderEntity = doPrepayOrder(
                        shopCartEntity.getUserId(),
                        shopCartEntity.getProductId(),
                        unpaidOrderEntity.getProductName(),
                        unpaidOrderEntity.getOrderId(),
                        unpaidOrderEntity.getTotalAmount(),
                        discount);

            } else if (MarketTypeVO.GROUP_BUY_MARKET.getCode().equals(marketType)) {
                // 是拼团类型，但已经计算过优惠，直接使用 payAmount（已扣优惠）
                payOrderEntity = doPrepayOrder(
                        shopCartEntity.getUserId(),
                        shopCartEntity.getProductId(),
                        unpaidOrderEntity.getProductName(),
                        unpaidOrderEntity.getOrderId(),
                        unpaidOrderEntity.getPayAmount());

            } else {
                // 其他类型（如单独购买或普通下单），按总价全额下单
                payOrderEntity = doPrepayOrder(
                        shopCartEntity.getUserId(),
                        shopCartEntity.getProductId(),
                        unpaidOrderEntity.getProductName(),
                        unpaidOrderEntity.getOrderId(),
                        unpaidOrderEntity.getTotalAmount());
            }

            // 返回已生成支付单的订单信息
            return PayOrderEntity.builder()
                    .orderId(payOrderEntity.getOrderId())
                    .payUrl(payOrderEntity.getPayUrl())
                    .build();
        }

        // ———— 以下为“全新下单”流程 ————

        // 2. 查询商品信息
        ProductEntity productEntity = port.queryProductByProductId(shopCartEntity.getProductId());

        // 3. 构建新的订单实体，并保存
        OrderEntity orderEntity = CreateOrderAggregate.buildOrderEntity(
                productEntity.getProductId(),
                productEntity.getProductName(),
                shopCartEntity.getMarketTypeVO().getCode());
        CreateOrderAggregate orderAggregate = CreateOrderAggregate.builder()
                .userId(shopCartEntity.getUserId())
                .productEntity(productEntity)
                .orderEntity(orderEntity)
                .build();
        this.doSaveOrder(orderAggregate);

        // 4. 如果是拼团（marketType == GROUP_BUY_MARKET），先锁定营销优惠
        MarketPayDiscountEntity marketPayDiscountEntity = null;
        if (MarketTypeVO.GROUP_BUY_MARKET.equals(shopCartEntity.getMarketTypeVO())) {
            marketPayDiscountEntity = this.lockMarketPayOrder(                 //调用拼团交易系统的锁单逻辑
                    shopCartEntity.getUserId(),
                    shopCartEntity.getTeamId(),
                    shopCartEntity.getActivityId(),
                    shopCartEntity.getProductId(),
                    orderEntity.getOrderId());
        }

        // 5. 创建支付订单（预支付），如果有拼团优惠则传入 discount，否则按原价下单
        PayOrderEntity payOrderEntity = doPrepayOrder(
                shopCartEntity.getUserId(),
                productEntity.getProductId(),
                productEntity.getProductName(),
                orderEntity.getOrderId(),
                productEntity.getPrice(),
                marketPayDiscountEntity);

        log.info("创建订单-完成，生成支付单。userId: {} orderId: {} payUrl: {}",
                shopCartEntity.getUserId(), orderEntity.getOrderId(), payOrderEntity.getPayUrl());

        // 返回新订单的支付链接
        return PayOrderEntity.builder()
                .orderId(orderEntity.getOrderId())
                .payUrl(payOrderEntity.getPayUrl())
                .build();
    }


    /**
     * 保存订单
     */
    protected abstract void doSaveOrder(CreateOrderAggregate orderAggregate);

    protected abstract MarketPayDiscountEntity lockMarketPayOrder(String userId, String teamId, Long activityId, String productId, String orderId);

    protected abstract PayOrderEntity doPrepayOrder(String userId, String productId, String productName, String orderId, BigDecimal totalAmount) throws AlipayApiException;

    protected abstract PayOrderEntity doPrepayOrder(String userId, String productId, String productName, String orderId, BigDecimal totalAmount, MarketPayDiscountEntity marketPayDiscountEntity) throws AlipayApiException;

    @Override
    public List<OrderEntity> queryUserOrderList(String userId, Long lastId, Integer pageSize) {
        return repository.queryUserOrderList(userId, lastId, pageSize);
    }
}
