package com.czg.service.order.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSONObject;
import com.czg.account.entity.HandoverRecord;
import com.czg.account.vo.HandoverCategoryListVo;
import com.czg.account.vo.HandoverProductListVo;
import com.czg.config.RabbitPublisher;
import com.czg.exception.CzgException;
import com.czg.order.entity.OrderDetail;
import com.czg.order.entity.OrderInfo;
import com.czg.order.service.OrderInfoRpcService;
import com.czg.product.service.ProductRpcService;
import com.czg.product.vo.ProductStockVO;
import com.czg.service.market.mapper.OrderInfoMapper;
import com.czg.service.order.mapper.OrderDetailMapper;
import com.mybatisflex.core.query.QueryWrapper;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 订单Rpc ServiceImpl
 *
 * @author tankaikai
 * @since 2025-02-28 11:29
 */
@DubboService
@Slf4j
public class OrderInfoRpcServiceImpl implements OrderInfoRpcService {

    @Resource
    private OrderInfoMapper orderInfoMapper;

    @Resource
    private OrderDetailMapper orderDetailMapper;

    @DubboReference
    private ProductRpcService productRpcService;

    @Resource
    private RabbitPublisher rabbitPublisher;


    @Override
    public List<HandoverProductListVo> getHandoverDetailList(Long shopId, String loginTime, String handoverTime) {
        return orderInfoMapper.getHandoverDetailList(shopId, loginTime, handoverTime);
    }

    @Override
    public List<HandoverCategoryListVo> getHandoverCategoryList(Long shopId, String loginTime, String handoverTime) {
        return orderInfoMapper.getHandoverCategoryList(shopId, loginTime, handoverTime);
    }

    @Override
    public HandoverRecord getOnlinePayTypeDate(Long shopId, String loginTime, String handoverTime) {
        return orderInfoMapper.getOnlinePayTypeDate(shopId, loginTime, handoverTime);
    }

    @Override
    public BigDecimal countReturnDish(Long shopId, String loginTime, String handoverTime) {
        return orderInfoMapper.countReturnDish(shopId, loginTime, handoverTime);
    }

    @Override
    public HandoverRecord countShopUserFlow(Long shopId, String loginTime, String handoverTime) {
        return orderInfoMapper.countShopUserFlow(shopId, loginTime, handoverTime);
    }


    @Override
    @GlobalTransactional
    public void paySuccessCallback(Long orderId) {
        // 下单后商品库存扣减，耗材扣减，流水记录
        OrderInfo orderInfo = orderInfoMapper.selectOneById(orderId);
        if (orderInfo == null) {
            throw new CzgException("订单不存在");
        }
        Integer placeNum = orderInfo.getPlaceNum();
        // 查询订单下商品
        List<OrderDetail> detailList = orderDetailMapper.selectListByQuery(
                QueryWrapper.create()
                        .eq(OrderDetail::getOrderId, orderId)
                        .eq(OrderDetail::getPlaceNum, placeNum)
        );
        if (CollUtil.isEmpty(detailList)) {
            throw new CzgException("该订单下不存在商品");
        }
        Long shopId = orderInfo.getShopId();
        // 封装扣减库存数据
        List<ProductStockVO> dataList = new ArrayList<>();
        for (OrderDetail orderDetail : detailList) {
            Long productId = orderDetail.getProductId();
            BigDecimal num = orderDetail.getNum();
            BigDecimal refundNum = orderDetail.getRefundNum();
            dataList.add(new ProductStockVO(productId, NumberUtil.sub(num, refundNum)));
        }
        try {
            // 调用商品服务扣减库存
            productRpcService.paySuccessSubtractStock(shopId, orderId, dataList);
        } catch (Exception e) {
            log.error("调用商品服务扣减库存失败", e);
            throw e;
        }
        log.info("OrderService.--------------------------------------------库存更新成功");
    }

    @Override
    @GlobalTransactional
    @Transactional(rollbackFor = Exception.class)
    public void orderCancelCallback(Long orderId) {
        // 订单取消后商品库存恢复，耗材恢复，流水记录
        OrderInfo orderInfo = orderInfoMapper.selectOneById(orderId);
        if (orderInfo == null) {
            throw new CzgException("订单不存在");
        }
        // 查询订单下商品
        List<OrderDetail> detailList = orderDetailMapper.selectListByQuery(QueryWrapper.create().eq(OrderDetail::getOrderId, orderId));
        if (CollUtil.isEmpty(detailList)) {
            throw new CzgException("该订单下不存在商品");
        }
        // 封装扣减库存数据
        List<ProductStockVO> dataList = new ArrayList<>();
        for (OrderDetail orderDetail : detailList) {
            Long productId = orderDetail.getProductId();
            BigDecimal num = orderDetail.getNum();
            BigDecimal refundNum = orderDetail.getRefundNum();
            BigDecimal returnNum = orderDetail.getReturnNum();
            dataList.add(new ProductStockVO(productId, NumberUtil.sub(num, refundNum, returnNum)));
        }
        try {
            // 调用商品服务扣减库存
            productRpcService.orderCancelRecoverStock(orderInfo.getShopId(), orderId, dataList);
        } catch (Exception e) {
            log.error("调用商品服务恢复库存", e);
            throw e;
        }
    }

    @Override
    public void orderRefundCallback(JSONObject data) {
        Long orderId = data.getLong("orderId");
        // 订单取消后商品库存恢复，耗材恢复，流水记录
        OrderInfo orderInfo = orderInfoMapper.selectOneById(orderId);
        if (orderInfo == null) {
            throw new CzgException("订单不存在");
        }
        // 查询订单下商品
        List<OrderDetail> detailList = orderDetailMapper.selectListByQuery(QueryWrapper.create().eq(OrderDetail::getOrderId, orderId));
        if (CollUtil.isEmpty(detailList)) {
            throw new CzgException("该订单下不存在商品");
        }
        List<ProductStockVO> dataList = data.getList("returnProList", ProductStockVO.class);
        try {
            // 调用商品服务回退库存
            productRpcService.orderRefundReturnStock(orderInfo.getShopId(), orderId, dataList);
        } catch (Exception e) {
            log.error("调用商品服务回退库存", e);
            throw e;
        }
    }

    @Override
    public void sendHandoverReceiptPrintMsgToMq(Long shopId, HandoverRecord record) {
        rabbitPublisher.sendOtherPrintMsg(shopId, record, "HANDOVER");

    }
}
