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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSONObject;
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.service.order.mapper.OrderDetailMapper;
import com.czg.service.order.mapper.OrderInfoMapper;
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.*;

/**
 * 订单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 BigDecimal getHandoverWechatAmount(Long shopId, String loginTime, String handoverTime) {
        return orderInfoMapper.getHandoverWechatAmount(shopId, loginTime, handoverTime);
    }

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

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

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

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

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

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

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

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

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

    @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
    @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<Map<String, Object>> dataList = new ArrayList<>();
        for (OrderDetail orderDetail : detailList) {
            Map<String, Object> data = new HashMap<>(16);
            Long productId = orderDetail.getProductId();
            BigDecimal num = orderDetail.getNum();
            BigDecimal refundNum = orderDetail.getRefundNum();
            data.put("shopId", shopId);
            data.put("productId", productId);
            data.put("num", NumberUtil.sub(num, refundNum));
            dataList.add(data);
        }
        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("该订单下不存在商品");
        }
        Long shopId = orderInfo.getShopId();
        // 封装扣减库存数据
        List<Map<String, Object>> dataList = new ArrayList<>();
        for (OrderDetail orderDetail : detailList) {
            Map<String, Object> data = new HashMap<>(16);
            Long productId = orderDetail.getProductId();
            BigDecimal num = orderDetail.getNum();
            BigDecimal refundNum = orderDetail.getRefundNum();
            data.put("shopId", shopId);
            data.put("productId", productId);
            data.put("num", NumberUtil.sub(num, refundNum));
            dataList.add(data);
        }
        try {
            // 调用商品服务扣减库存
            productRpcService.orderCancelRecoverStock(shopId, orderId, dataList);
        } catch (Exception e) {
            log.error("调用商品服务恢复库存", e);
            throw e;
        }
    }

    @Override
    public void orderRefundCallback(JSONObject data) {
        log.info(">>>>>>>>>>>>>>>>>：入参：{}", data.toJSONString());
        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("该订单下不存在商品");
        }
        JSONObject obj = data.getJSONObject("returnProMap");
        Set<String> keys = obj.keySet();
        // 封装扣减库存数据
        List<Map<String, Object>> dataList = new ArrayList<>();
        for (String key : keys) {
            Long productId = Convert.toLong(key);
            BigDecimal num = obj.getBigDecimal(key);
            Map<String, Object> row = new HashMap<>(3);
            row.put("shopId", orderInfo.getShopId());
            row.put("productId", productId);
            row.put("num", num);
            dataList.add(row);
        }
        try {
            // 调用商品服务回退库存
            productRpcService.orderRefundReturnStock(orderInfo.getShopId(), orderId, dataList);
        } catch (Exception e) {
            log.error("调用商品服务回退库存", e);
            throw e;
        }
    }

    @Override
    public void sendHandoverReceiptPrintMsgToMq(Long handoverRecordId) {
        rabbitPublisher.sendHandoverPrintMsg(Convert.toStr(handoverRecordId));
    }
}
