package com.qs.mp.channel.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.qs.mp.channel.domain.ChannelGoods;
import com.qs.mp.channel.domain.ChannelGoodsSettleOrder;
import com.qs.mp.channel.domain.ChannelGoodsSettleOrderItem;
import com.qs.mp.channel.domain.param.PushChannelGoodsSettleParam;
import com.qs.mp.channel.domain.vo.ChannelSettleVO;
import com.qs.mp.channel.mapper.ChannelGoodsSettleOrderMapper;
import com.qs.mp.channel.service.IChannelGoodsService;
import com.qs.mp.channel.service.IChannelGoodsSettleOrderItemService;
import com.qs.mp.channel.service.IChannelGoodsSettleOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qs.mp.common.enums.ChannelGoodsOrderSettleEnum;
import com.qs.mp.common.enums.ChannelGoodsSettleStatusTypeEnum;
import com.qs.mp.common.exception.ServiceException;
import com.qs.mp.common.utils.DateUtils;
import com.qs.mp.common.utils.LogUtil;
import com.qs.mp.pay.domain.PayOrder;
import com.qs.mp.system.service.id.BizIdGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 经销商商品结算订单 服务实现类
 * </p>
 *
 * @author quanshu
 * @since 2023-06-08
 */
@Service
public class ChannelGoodsSettleOrderServiceImpl extends ServiceImpl<ChannelGoodsSettleOrderMapper, ChannelGoodsSettleOrder> implements IChannelGoodsSettleOrderService {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName());

    @Autowired
    private IChannelGoodsService channelGoodsService;

    @Autowired
    private IChannelGoodsSettleOrderService settleOrderService;

    @Autowired
    private IChannelGoodsSettleOrderItemService settleOrderItemService;

    @Autowired
    private BizIdGenerator bizIdGenerator;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String pushSettleOrder(PushChannelGoodsSettleParam settleVO) {
        String orderId = bizIdGenerator.newId();
        List<ChannelGoods> channelGoodsList = channelGoodsService.list(new LambdaQueryWrapper<ChannelGoods>().eq(ChannelGoods::getOrderId, settleVO.getOrderId()));
        ChannelGoodsSettleOrder settleOrder = new ChannelGoodsSettleOrder();
        settleOrder.setOrderId(orderId);
        settleOrder.setSettleNum(channelGoodsList.stream().mapToInt(ChannelGoods::getSettleQty).sum());
        Integer orderAmt = 0;
        for (ChannelGoods channelGoods : channelGoodsList) {
            orderAmt += channelGoods.getPurchaseCost() * channelGoods.getRemainQty();
        }
        settleOrder.setChannelId(channelGoodsList.get(0).getChannelId());
        settleOrder.setOrderAmt(orderAmt);
        settleOrder.setSettleAmt(settleVO.getSettleAmt());
        settleOrder.setStatus(ChannelGoodsOrderSettleEnum.NOT_PAY);
        settleOrderService.save(settleOrder);

        for (ChannelGoods channelGoods : channelGoodsList) {
            ChannelGoodsSettleOrderItem settleOrderItem = new ChannelGoodsSettleOrderItem();
            settleOrderItem.setOrderId(settleOrder.getOrderId());
            settleOrderItem.setChannelId(channelGoods.getChannelId());
            settleOrderItem.setChannelGoodsId(channelGoods.getId());
            settleOrderItem.setTitle(channelGoods.getTitle());
            settleOrderItem.setPicUrl(channelGoods.getPicUrl());
            settleOrderItem.setQuantity(channelGoods.getQuantity());
            settleOrderItem.setPurchaseCost(channelGoods.getPurchaseCost());
            settleOrderItem.setVerifyQty(channelGoods.getVerifyQty());
            settleOrderItem.setRemainQty(channelGoods.getRemainQty());
            settleOrderItem.setSettleQty(channelGoods.getRemainQty());
            settleOrderItemService.save(settleOrderItem);

            boolean update = channelGoodsService.update(
                    new LambdaUpdateWrapper<ChannelGoods>()
                            .set(ChannelGoods::getStatus, ChannelGoodsSettleStatusTypeEnum.DOING)
                            .set(ChannelGoods::getSettleQty,channelGoods.getRemainQty())
                            .set(ChannelGoods::getRemainQty, 0)
                            .eq(ChannelGoods::getId, channelGoods.getId()));
            Assert.isTrue(update, "更新门店采购商品信息失败：order_id =" + settleVO.getOrderId());
        }

        return settleOrder.getOrderId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void paySuccess(PayOrder payOrder) {
        ChannelGoodsSettleOrder settleOrder = getById(payOrder.getBizId());
        if (null == settleOrder || settleOrder.getStatus() != ChannelGoodsOrderSettleEnum.NOT_PAY) {
            LogUtil.error(logger, "支付回调渠道采购商品结算订单处理，订单状态异常，不是待支付。payOrder:{0}, settleOrder:{1}",
                    JSONObject.toJSONString(payOrder), JSONObject.toJSONString(settleOrder));
            throw new ServiceException("支付回调渠道采购商品结算订单处理，订单状态异常，不是待支付。orderId:" + payOrder.getBizId());
        }
        boolean rst = update(
                new LambdaUpdateWrapper<ChannelGoodsSettleOrder>().set(ChannelGoodsSettleOrder::getStatus,
                                ChannelGoodsOrderSettleEnum.FINISHED)
                        .set(ChannelGoodsSettleOrder::getPayTime, DateUtils.parseDate(payOrder.getCompleteDate()))
                        .set(ChannelGoodsSettleOrder::getPayType,payOrder.getPayResource())
                        .eq(ChannelGoodsSettleOrder::getOrderId, settleOrder.getOrderId())
                        .eq(ChannelGoodsSettleOrder::getStatus, ChannelGoodsOrderSettleEnum.NOT_PAY));
        if (!rst) {
            LogUtil.error(logger, "渠道采购商品结算订单支付成功时，更新订单状态失败。orderId:{0}",
                    settleOrder.getOrderId());
            throw new ServiceException("渠道采购商品订单结算支付成功时，更新订单状态失败");
        }
        List<ChannelGoodsSettleOrderItem> items = settleOrderItemService.list(new LambdaQueryWrapper<ChannelGoodsSettleOrderItem>().eq(ChannelGoodsSettleOrderItem::getOrderId, settleOrder.getOrderId()));
        List<Long> channelGoodsIdList = items.stream().map(ChannelGoodsSettleOrderItem::getChannelGoodsId).collect(Collectors.toList());
        boolean updateRst = channelGoodsService.update(new LambdaUpdateWrapper<ChannelGoods>()
                .set(ChannelGoods::getStatus, ChannelGoodsSettleStatusTypeEnum.FINISHED)
                .set(ChannelGoods::getSettleTime, DateUtils.parseDate(payOrder.getCompleteDate()))
                .in(ChannelGoods::getId, channelGoodsIdList));

        if (!updateRst) {
            LogUtil.error(logger, "更新门店采购商品信息失败。orderId:{0}",
                    settleOrder.getOrderId());
            throw new ServiceException("更新门店采购商品信息失败");
        }
    }

    @Override
    public List<ChannelSettleVO> listGoodsSettleOrder(QueryWrapper<ChannelGoodsSettleOrder> channelGoodsSettleOrderQueryWrapper) {
        return getBaseMapper().listGoodsSettleOrder(channelGoodsSettleOrderQueryWrapper);
    }
}
