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.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.qs.mp.admin.domain.Goods;
import com.qs.mp.admin.domain.GoodsSku;
import com.qs.mp.admin.service.IGoodsService;
import com.qs.mp.admin.service.IGoodsSkuService;
import com.qs.mp.channel.domain.ChannelGoods;
import com.qs.mp.channel.domain.ChannelGoodsOrder;
import com.qs.mp.channel.domain.ChannelGoodsOrderItem;
import com.qs.mp.channel.domain.vo.ChannelGoodsOrderSettleVO;
import com.qs.mp.channel.domain.vo.ChannelGoodsOrderVO;
import com.qs.mp.channel.domain.vo.ChannelGoodsSettleVO;
import com.qs.mp.channel.mapper.ChannelGoodsOrderMapper;
import com.qs.mp.channel.service.IChannelGoodsOrderItemService;
import com.qs.mp.channel.service.IChannelGoodsOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qs.mp.channel.service.IChannelGoodsService;
import com.qs.mp.common.enums.*;
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 com.qs.mp.user.domain.UserAddr;
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.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @auther quanshu
 * @create 2023-06-05 11:13:54
 * @describe 经销商商品采购订单服务实现类
 */
@Service
public class ChannelGoodsOrderServiceImpl extends ServiceImpl<ChannelGoodsOrderMapper, ChannelGoodsOrder> implements IChannelGoodsOrderService {

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

    @Autowired
    private IChannelGoodsOrderService channelGoodsOrderService;

    @Autowired
    private IChannelGoodsOrderItemService channelGoodsOrderItemService;

    @Autowired
    private IGoodsService goodsService;

    @Autowired
    private IChannelGoodsService channelGoodsService;

    @Autowired
    private IGoodsSkuService goodsSkuService;

    @Autowired
    private BizIdGenerator bizIdGenerator;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String submitOrder(Long channelId, String memo, ChannelGoodsOrderSettleVO orderSettleVO) {

        UserAddr addr = orderSettleVO.getAddr();
        String orderId = bizIdGenerator.newId();
        Goods goods = goodsService.getById(orderSettleVO.getGoodsId());

//        if (goods.getQuantity() < orderSettleVO.getOrderNum()) {
//            throw new ServiceException(goods.getTitle() + "库存不足,请重新下单");
//        }
//        // 更新库存
//        boolean updateGoods = goodsService.update(new LambdaUpdateWrapper<Goods>()
//                .set(goods.getQuantity() - orderSettleVO.getOrderNum() == 0, Goods::getStatus,
//                        GoodsStatusEnum.PUT_OFF)
//                .set(Goods::getQuantity, goods.getQuantity() - orderSettleVO.getOrderNum())
//                .eq(Goods::getGoodsId, goods.getGoodsId()).eq(Goods::getQuantity, goods.getQuantity()));
//        Assert.isTrue(updateGoods, "门店购买采购商品更新GOODS库存失败。goodsId:" + goods.getGoodsId());

        // 创建订单
        ChannelGoodsOrder channelGoodsOrder = new ChannelGoodsOrder();
        channelGoodsOrder.setOrderId(orderId);
        channelGoodsOrder.setChannelId(channelId);
        channelGoodsOrder.setTitle(goods.getTitle());
        if (orderSettleVO.getOrderNum() < 0) {
            throw new ServiceException("订单商品数量不能小于0");
        }
        channelGoodsOrder.setOrderNum(orderSettleVO.getOrderNum());
        channelGoodsOrder.setOrderAmt(orderSettleVO.getOrderAmt());
        channelGoodsOrder.setFreightAmt(orderSettleVO.getFreightAmt());
        channelGoodsOrder.setPayAmt(orderSettleVO.getPayAmt());
        channelGoodsOrder.setStatus(ChannelGoodsOrderStatusEnum.NOT_PAY);
        channelGoodsOrder.setMemo(memo);
        channelGoodsOrder.setReceiver(addr.getReceiver());
        channelGoodsOrder.setTel(addr.getMobile());
        channelGoodsOrder.setProvince(addr.getProvince());
        channelGoodsOrder.setCity(addr.getCity());
        channelGoodsOrder.setArea(addr.getArea());
        channelGoodsOrder.setAddress(addr.getAddr());
        channelGoodsOrderService.save(channelGoodsOrder);

        // 创建订单明细
        for (ChannelGoods channelGoods : orderSettleVO.getItems()) {
            ChannelGoodsOrderItem item = new ChannelGoodsOrderItem();
            item.setChannelId(channelId);
            item.setOrderId(orderId);
            item.setGoodsId(goods.getGoodsId());
            item.setSkuId(channelGoods.getSkuId());
            item.setProperties(channelGoods.getProperties());
            item.setTitle(goods.getTitle());
            item.setGoodsNum(channelGoods.getQuantity());
            item.setPicUrl(goods.getPicUrl());
            item.setSupplierId(goods.getSupplierId());
            item.setPurchasePrice(channelGoods.getPurchasePrice());
            item.setPurchaseCost(channelGoods.getPurchaseCost());
            channelGoodsOrderItemService.save(item);

            if (Objects.nonNull(channelGoods.getSkuId()) && channelGoods.getSkuId() != 0) {
                GoodsSku goodsSku = goodsSkuService.getById(channelGoods.getSkuId());
                if (goodsSku.getQuantity() < channelGoods.getQuantity()) {
                    throw new ServiceException(channelGoods.getTitle() + "库存不足,请重新下单");
                }

                // 更新sku库存
                boolean updateSku = goodsSkuService.update(new LambdaUpdateWrapper<GoodsSku>()
                        .set(GoodsSku::getQuantity, goodsSku.getQuantity() - channelGoods.getQuantity())
                        .set(GoodsSku::getSoldQty, goodsSku.getSoldQty() + channelGoods.getQuantity())
                        .eq(GoodsSku::getSkuId, goodsSku.getSkuId())
                        .eq(GoodsSku::getQuantity, goodsSku.getQuantity())
                        .eq(GoodsSku::getSoldQty, goodsSku.getSoldQty()));
                Assert.isTrue(updateSku,
                        "门店购买采购商品更新SKU库存失败。goodsId:" + goodsSku.getGoodsId() + ",skuId:" + goodsSku.getSkuId());

                // 更新goods库存
                boolean updateGoods = goodsService.update(new LambdaUpdateWrapper<Goods>()
                        .set(goods.getQuantity() - channelGoods.getQuantity() == 0, Goods::getStatus,
                                GoodsStatusEnum.PUT_OFF)
                        .set(Goods::getQuantity, goods.getQuantity() - channelGoods.getQuantity())
                        .eq(Goods::getGoodsId, goods.getGoodsId()));
                Assert.isTrue(updateGoods, "门店购买采购商品更新GOODS库存失败。goodsId:" + goods.getGoodsId());

            } else {
                if (goods.getQuantity() < channelGoods.getQuantity()) {
                    throw new ServiceException(channelGoods.getTitle() + "库存不足,请重新下单");
                }
                // 更新库存
                boolean updateGoods = goodsService.update(new LambdaUpdateWrapper<Goods>()
                        .set(goods.getQuantity() - channelGoods.getQuantity() == 0, Goods::getStatus,
                                GoodsStatusEnum.PUT_OFF)
                        .set(Goods::getQuantity, goods.getQuantity() - channelGoods.getQuantity())
                        .eq(Goods::getGoodsId, goods.getGoodsId())
                        .eq(Goods::getQuantity, goods.getQuantity()));
                Assert.isTrue(updateGoods, "门店购买采购商品更新GOODS库存失败。goodsId:" + goods.getGoodsId());
            }
        }


        return channelGoodsOrder.getOrderId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelOrder(Long channelId, String orderId) {
        ChannelGoodsOrder channelGoodsOrder = channelGoodsOrderService.getOne(new LambdaQueryWrapper<ChannelGoodsOrder>()
                .eq(ChannelGoodsOrder::getChannelId, channelId)
                .eq(ChannelGoodsOrder::getOrderId, orderId));

        if (ChannelGoodsOrderStatusEnum.NOT_PAY != channelGoodsOrder.getStatus()) {
            throw new ServiceException("订单状态异常，不能取消订单");
        }

        ChannelGoodsOrderItem goodsOrderItem = channelGoodsOrderItemService.getOne(new LambdaQueryWrapper<ChannelGoodsOrderItem>().eq(ChannelGoodsOrderItem::getChannelId, channelId)
                .eq(ChannelGoodsOrderItem::getOrderId, orderId));
        // 恢复采购商品库存
        Goods goods = goodsService.getById(goodsOrderItem.getGoodsId());
        boolean rst = goodsService.update(new LambdaUpdateWrapper<Goods>()
                .set(Goods::getStatus, GoodsStatusEnum.PUT_ON)
                .set(Goods::getQuantity, goods.getQuantity() + goodsOrderItem.getGoodsNum())
                .eq(Goods::getGoodsId, goods.getGoodsId())
                .eq(Goods::getQuantity, goods.getQuantity())

        );
        Assert.isTrue(rst,"门店采购商品订单取消恢复采购商品库存失败，goodsId：" + goods.getGoodsId());

        channelGoodsOrder.setStatus(ChannelGoodsOrderStatusEnum.CANCELED);
        boolean updateRst = channelGoodsOrderService.updateById(channelGoodsOrder);
        Assert.isTrue(updateRst,"门店采购商品订单取消失败，orderId：" + orderId);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void paySuccess(PayOrder payOrder) {
        ChannelGoodsOrder channelGoodsOrder = getById(payOrder.getBizId());
        if (null == channelGoodsOrder || channelGoodsOrder.getStatus() != ChannelGoodsOrderStatusEnum.NOT_PAY) {
            LogUtil.error(logger, "支付回调渠道采购商品订单处理，订单状态异常，不是待支付。payOrder:{0}, channelGoodsOrder:{1}",
                    JSONObject.toJSONString(payOrder), JSONObject.toJSONString(channelGoodsOrder));
            throw new ServiceException("支付回调渠道采购商品订单处理，订单状态异常，不是待支付。orderId:" + payOrder.getBizId());
        }
        boolean rst = update(
                new LambdaUpdateWrapper<ChannelGoodsOrder>().set(ChannelGoodsOrder::getStatus,
                                ChannelGoodsOrderStatusEnum.NOT_DELIVER)
                        .set(ChannelGoodsOrder::getPayTime, DateUtils.parseDate(payOrder.getCompleteDate()))
                        .set(ChannelGoodsOrder::getPayType,payOrder.getPayResource())
                        .eq(ChannelGoodsOrder::getOrderId, channelGoodsOrder.getOrderId())
                        .eq(ChannelGoodsOrder::getStatus, ChannelGoodsOrderStatusEnum.NOT_PAY));
        if (!rst) {
            LogUtil.error(logger, "渠道采购商品订单支付成功时，更新订单状态失败。orderId:{0}",
                    channelGoodsOrder.getOrderId());
            throw new ServiceException("渠道采购商品订单支付成功时，更新订单状态失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmOrder(ChannelGoodsOrder channelGoodsOrder) {
        ChannelGoodsOrder param = new ChannelGoodsOrder();
        param.setOrderId(channelGoodsOrder.getOrderId());
        param.setStatus(ChannelGoodsOrderStatusEnum.FINISHED);
        param.setConfirmTime(new Date());
        boolean rst = channelGoodsOrderService.updateById(param);
        Assert.isTrue(rst,"门店采购商品订单确认失败，orderId：" + channelGoodsOrder.getOrderId());

        List<ChannelGoodsOrderItem> items = channelGoodsOrderItemService.list(new QueryWrapper<ChannelGoodsOrderItem>().eq("order_id", channelGoodsOrder.getOrderId()));
        List<ChannelGoods> goodsList = new ArrayList<>();
        for (ChannelGoodsOrderItem item : items) {
            Goods goods = goodsService.getById(item.getGoodsId());
            ChannelGoods channelGoods = new ChannelGoods();
            channelGoods.setChannelId(item.getChannelId());
            channelGoods.setGoodsId(item.getGoodsId());
            channelGoods.setOrderId(item.getOrderId());
            channelGoods.setSkuId(item.getSkuId());
            channelGoods.setProperties(item.getProperties());
            channelGoods.setTitle(item.getTitle());
            channelGoods.setPicUrl(item.getPicUrl());
            channelGoods.setStatus(ChannelGoodsSettleStatusTypeEnum.NO);
            channelGoods.setRefId(goods.getRefId());
            channelGoods.setSupplierId(item.getSupplierId());
            channelGoods.setQuantity(item.getGoodsNum());
            channelGoods.setRemainQty(item.getGoodsNum());
            channelGoods.setPurchasePrice(item.getPurchasePrice());
            channelGoods.setPurchaseCost(item.getPurchaseCost());
            goodsList.add(channelGoods);
        }
        channelGoodsService.saveBatch(goodsList);
    }

    @Override
    public List<ChannelGoodsOrderVO> selectChannelGoodsOrderVOList(QueryWrapper<ChannelGoodsOrder> queryWrapper) {
        return getBaseMapper().selectChannelGoodsOrderVOList(queryWrapper);
    }

    @Override
    public boolean ship(ChannelGoodsOrder goodsOrder) {
        if(null == goodsOrder || StringUtils.isBlank(goodsOrder.getOrderId())) {
            throw new ServiceException("发货订单异常，发货失败");
        }

        String deliveryFlowId = goodsOrder.getDeliveryFlowId();
        // 物流单号为空则表示无需物流发货
        if (StringUtils.isBlank(deliveryFlowId)) {
            goodsOrder.setStatus(ChannelGoodsOrderStatusEnum.FINISHED);
            List<ChannelGoodsOrderItem> items = channelGoodsOrderItemService.list(new QueryWrapper<ChannelGoodsOrderItem>().eq("order_id", goodsOrder.getOrderId()));
            List<ChannelGoods> goodsList = new ArrayList<>();
            for (ChannelGoodsOrderItem item : items) {
                Goods goods = goodsService.getById(item.getGoodsId());
                ChannelGoods channelGoods = new ChannelGoods();
                channelGoods.setChannelId(item.getChannelId());
                channelGoods.setGoodsId(item.getGoodsId());
                channelGoods.setOrderId(item.getOrderId());
                channelGoods.setSkuId(item.getSkuId());
                channelGoods.setProperties(item.getProperties());
                channelGoods.setTitle(item.getTitle());
                channelGoods.setPicUrl(item.getPicUrl());
                channelGoods.setStatus(ChannelGoodsSettleStatusTypeEnum.NO);
                channelGoods.setRefId(goods.getRefId());
                channelGoods.setSupplierId(item.getSupplierId());
                channelGoods.setQuantity(item.getGoodsNum());
                channelGoods.setRemainQty(item.getGoodsNum());
                channelGoods.setPurchasePrice(item.getPurchasePrice());
                channelGoods.setPurchaseCost(item.getPurchaseCost());
                goodsList.add(channelGoods);
            }
            channelGoodsService.saveBatch(goodsList);
        } else {
            goodsOrder.setStatus(ChannelGoodsOrderStatusEnum.NOT_CONFIRM);
        }
        boolean updateOrderRtn = updateById(goodsOrder);
        Assert.isTrue(updateOrderRtn, "更新采购商品订单失败,orderId:" + goodsOrder.getOrderId());
        return true;
    }

    @Override
    public int selectChannelGoodsOrderCount(QueryWrapper<ChannelGoodsOrder> queryWrapper) {
        return getBaseMapper().selectChannelGoodsOrderCount(queryWrapper);
    }

    @Override
    public List<ChannelGoodsSettleVO> selectChannelGoodsSettleList(QueryWrapper<ChannelGoodsOrder> queryWrapper) {
        return getBaseMapper().selectChannelGoodsSettleList(queryWrapper);
    }

    @Override
    public ChannelGoodsOrderVO listChannelGoodsOrder(QueryWrapper<ChannelGoodsOrder> queryWrapper) {
        return getBaseMapper().listChannelGoodsOrder(queryWrapper);
    }

}
