package cn.iocoder.yudao.module.order.service.order.impl;

import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.apollo.core.event.BoxCheckOrderSchedulingEvent;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.order.convert.order.OrderConvert;
import cn.iocoder.yudao.module.order.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.order.service.order.OrderBusinessService;
import cn.iocoder.yudao.module.order.service.order.OrderMutualService;
import cn.iocoder.yudao.module.order.service.order.OrderQueryService;
import cn.iocoder.yudao.module.order.service.order.OrderService;
import cn.iocoder.yudao.module.order.vo.order.OrderBackVO;
import cn.iocoder.yudao.module.order.vo.order.OrderQueryVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService;
import cn.iocoder.yudao.module.order.vo.orderMutual.*;
import cn.iocoder.yudao.module.order.dal.dataobject.orderMutual.OrderMutualDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.order.convert.orderMutual.OrderMutualConvert;
import cn.iocoder.yudao.module.order.dal.mysql.orderMutual.OrderMutualMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.order.enums.ErrorCodeConstants.*;

/**
 * 订单互斥 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class OrderMutualServiceImpl extends AbstractService<OrderMutualMapper,
        OrderMutualDO> implements OrderMutualService {


    @Resource
    private OrderMutualMapper mutualMapper;

    @Resource
    @Lazy
    private OrderService orderService;

    @Resource
    @Lazy
    private OrderBusinessService orderBusinessService;

    @Resource
    private OrderQueryService orderQueryService;

    @Resource
    private ApplicationEventPublisher applicationContext;

    @Override
    public Long createMutual(OrderMutualCreateReqVO createReqVO) {
        OrderMutualDO orderMutualDO = mutualMapper.selectOne(OrderMutualDO::getOrderId, createReqVO.getOrderId(), OrderMutualDO::getMutualOrderId, createReqVO.getMutualOrderId());
        OrderMutualDO orderMutualDO1 = mutualMapper.selectOne(OrderMutualDO::getOrderId, createReqVO.getMutualOrderId(), OrderMutualDO::getMutualOrderId, createReqVO.getOrderId());
        if (orderMutualDO != null || orderMutualDO1 != null) {
            throw exception(ORDER_MUTUAL_IS_EXISTS);
        }

        applicationContext.publishEvent(new BoxCheckOrderSchedulingEvent(createReqVO.getOrderId()));
        applicationContext.publishEvent(new BoxCheckOrderSchedulingEvent(createReqVO.getMutualOrderId()));
        // 插入
        OrderMutualDO mutual = OrderMutualConvert.INSTANCE.convert(createReqVO);
        mutualMapper.insert(mutual);
        orderBusinessService.addOrderOperateLog(createReqVO.getOrderId(),"","新增互斥订单","");
//        orderBusinessService.addOrderOperateLog(createReqVO.getMutualOrderId(),"","新增互斥订单","");
        // 返回
        return mutual.getId();
    }

    @Override
    public void updateMutual(OrderMutualUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateMutualExists(updateReqVO.getId());
        // 更新
        OrderMutualDO updateObj = OrderMutualConvert.INSTANCE.convert(updateReqVO);
        mutualMapper.updateById(updateObj);
    }

    @Override
    public void deleteMutual(Long id) {
        // 校验存在
        this.validateMutualExists(id);
        // 删除
        mutualMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dealMutualByOrderId(Long orderId,
                                    List<Long> splitOrderIds,int type) {
        if (type == 1) {
            List<OrderMutualDO> orderMutualDOS =
                    mutualMapper.selectList(new LambdaQueryWrapperX<OrderMutualDO>()
                    .and(i -> i.eq(OrderMutualDO::getMutualOrderId, orderId)
                            .or()
                            .eq(OrderMutualDO::getOrderId, orderId)
                    )
            );
            if (CollectionUtil.isNotEmpty(orderMutualDOS)) {
                //继承关联关系
                orderMutualDOS.stream().forEach(item -> {
                    splitOrderIds.stream().forEach(id ->{
                        OrderMutualDO orderGuanlianDO = new OrderMutualDO();
                        BeanUtils.copyProperties(item,orderGuanlianDO);
                        if (item.getOrderId().longValue() == orderId.longValue()) {
                            orderGuanlianDO.setOrderId(id);
                        } else {
                            orderGuanlianDO.setMutualOrderId(id);
                        }
                        orderGuanlianDO.setId(null);
                        mutualMapper.insert(orderGuanlianDO);
                    });
                    mutualMapper.deleteById(item);
                });
            }
        } else if (type == 2) {
            if (CollectionUtil.isNotEmpty(splitOrderIds)) {
                //删除拆单后的关联订单，不管后面有没有新增关联，都删除才对
                List<OrderMutualDO> orderGuanlianDOS =
                        mutualMapper.selectList(
                                new LambdaQueryWrapperX<OrderMutualDO>().
                                        and(i -> i.in(OrderMutualDO::getOrderId,
                                                splitOrderIds).or().
                                                in(OrderMutualDO::getMutualOrderId,
                                                        splitOrderIds)));
                orderGuanlianDOS.stream().forEach(item -> {

                    if (splitOrderIds.contains(item.getOrderId())) {
                        mutualMapper.updateMutualBackByRelatId(item);
                    } else if (splitOrderIds.contains(item.getMutualOrderId())) {
                        mutualMapper.updateMutualBackByOrderId(item);
                    }
                });
                if (CollectionUtil.isNotEmpty(orderGuanlianDOS)) {
                    mutualMapper.deleteBatchIds(orderGuanlianDOS.stream().map(OrderMutualDO::getId).collect(Collectors.toList()));
                }
            }
        }
    }

    private void validateMutualExists(Long id) {
        if (mutualMapper.selectById(id) == null) {
            throw exception(MUTUAL_NOT_EXISTS);
        }
    }

    @Override
    public OrderMutualDO getMutual(Long id) {
        return mutualMapper.selectById(id);
    }

    @Override
    public List<OrderMutualDO> getMutualList(Collection<Long> ids) {
        return mutualMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<OrderMutualDO> getMutualPage(OrderMutualQueryVO query, PageVO page) {
        return mutualMapper.selectPage(page, query);
    }

    @Override
    public List<OrderMutualDO> getMutualList(OrderMutualQueryVO query) {
        return mutualMapper.selectList(query);
    }

    @Override
    public void batchCreateMutual(List<OrderMutualCreateReqVO> createReqVOList) {
        if (createReqVOList != null && createReqVOList.size() > 0) {
            Date date = new Date();
            for (OrderMutualCreateReqVO orderMutualCreateReqVO : createReqVOList) {
                applicationContext.publishEvent(new BoxCheckOrderSchedulingEvent(orderMutualCreateReqVO.getMutualOrderId()));
                // 插入
                orderMutualCreateReqVO.setAddTime(date);
                OrderMutualDO mutual = OrderMutualConvert.INSTANCE.convert(orderMutualCreateReqVO);
                mutualMapper.insert(mutual);
//                orderBusinessService.addOrderOperateLog(orderMutualCreateReqVO.getMutualOrderId(),"","新增互斥订单","");
                // 返回
            }
            applicationContext.publishEvent(new BoxCheckOrderSchedulingEvent(createReqVOList.get(0).getOrderId()));
            orderBusinessService.addOrderOperateLog(createReqVOList.get(0).getOrderId(),"","新增互斥订单","");
        }
    }

    @Override
    public PageResult<OrderMutualBackVO> getMutualOrderByOrderId(OrderMutualQueryVO orderMutualQueryVO, PageVO pageVO) {
        List<OrderMutualBackVO> list = new ArrayList<>();
        PageResult<OrderMutualBackVO> pageResult = new PageResult<>();
        if (StringUtils.isBlank(orderMutualQueryVO.getMutualOrderNo())) {
            PageResult<OrderMutualDO> orderMutualDOPageResult = mutualMapper.selectPage(pageVO, orderMutualQueryVO);
            List<OrderMutualDO> orderMutualDOS = orderMutualDOPageResult.getList();
            if (orderMutualDOS != null && orderMutualDOS.size() > 0) {
                for (OrderMutualDO orderMutualDO : orderMutualDOS) {
                    OrderBackVO order = orderQueryService.getOrder(orderMutualDO.getMutualOrderId());
                    OrderMutualBackVO convert = OrderMutualConvert.INSTANCE.convert(orderMutualDO);
                    convert.setOrderBackVO(order);
                    list.add(convert);
                }
                pageResult.setList(list);
                pageResult.setPage(orderMutualDOPageResult.getPage());
                pageResult.setPages(orderMutualDOPageResult.getPages());
                pageResult.setRows(orderMutualDOPageResult.getRows());
                pageResult.setTotal(orderMutualDOPageResult.getTotal());
            }
        } else {
            OrderDO orderDO = orderService.selectOne(OrderDO::getOrderNo, orderMutualQueryVO.getMutualOrderNo());
            if (orderDO == null) {
                throw exception(ORDER_NOT_EXISTS);
            }
            OrderMutualDO orderMutualDO = mutualMapper.selectOne(OrderMutualDO::getOrderId, orderMutualQueryVO.getOrderId(), OrderMutualDO::getMutualOrderId, orderDO.getOrderId());
            if (orderMutualDO != null) {
                OrderBackVO order = orderQueryService.getOrder(orderMutualDO.getMutualOrderId());
                OrderMutualBackVO convert = OrderMutualConvert.INSTANCE.convert(orderMutualDO);
                convert.setOrderBackVO(order);
                list.add(convert);
            }
            pageResult.setList(list);
            pageResult.setPage(1L);
            pageResult.setPages(1L);
            pageResult.setRows(10L);
            pageResult.setTotal(1L);
        }
        return pageResult;
    }

    @Override
    public PageResult<OrderBackVO> getUnMutualOrderByOrderId(OrderMutualQueryVO orderMutualQueryVO, PageVO pageVO) {
        PageResult<OrderBackVO> pageResult = new PageResult<>();
        List<OrderBackVO> orderList = new ArrayList<>();
        OrderBackVO order = orderQueryService.getOrder(orderMutualQueryVO.getOrderId());
        OrderQueryVO orderQueryVo = new OrderQueryVO();
        orderQueryVo.setParentOrderId(orderMutualQueryVO.getOrderId());
        orderQueryVo.setTransportId(order.getTransportId());
        orderQueryVo.setDepartureId(order.getDepartureId());
        orderQueryVo.setObjectiveId(order.getObjectiveId());
        if (StringUtils.isNotBlank(orderMutualQueryVO.getMutualOrderNo())) {
            orderQueryVo.setOrderNo(orderMutualQueryVO.getMutualOrderNo());
        }
        PageResult<OrderDO> unMutualOrderPage = orderQueryService.getUnMutualOrderPage(orderQueryVo, pageVO);
        orderList.addAll(OrderConvert.INSTANCE.convertList(unMutualOrderPage.getList()));
        pageResult.setList(orderList);
        pageResult.setTotal(unMutualOrderPage.getTotal());
        pageResult.setRows(unMutualOrderPage.getTotal());
        pageResult.setPages(unMutualOrderPage.getPages());
        pageResult.setPage(unMutualOrderPage.getPage());
//        if(orderList!=null&&orderList.size()>0){
//            List<OrderMutualDO> orderMutualDOS = mutualMapper.selectList(OrderMutualDO::getOrderId, orderMutualQueryVO.getOrderId());
//            if(orderMutualDOS!=null){
//                for (OrderBackVO orderBackVO : orderList) {
//                    boolean flag = true;
//                    for (OrderMutualDO orderMutualDO : orderMutualDOS){
//                        if(orderBackVO.getOrderId().equals(orderMutualDO.getMutualOrderId())){
//                            flag = false;
//                        }
//                    }
//                    if(flag){
//                        list.add(orderBackVO);
//                    }
//                }
//            } else {
//                list.addAll(orderList);
//            }
//        }
        return pageResult;
    }

    @Override
    public void deleteMutualOrderByOrderId(OrderMutualQueryVO orderMutualQueryVO) {
        mutualMapper.delete(new LambdaQueryWrapperX<OrderMutualDO>()
                .eqIfPresent(OrderMutualDO::getOrderId, orderMutualQueryVO.getOrderId())
                .eqIfPresent(OrderMutualDO::getMutualOrderId, orderMutualQueryVO.getMutualOrderId()));
        mutualMapper.delete(new LambdaQueryWrapperX<OrderMutualDO>()
                .eqIfPresent(OrderMutualDO::getOrderId, orderMutualQueryVO.getMutualOrderId())
                .eqIfPresent(OrderMutualDO::getMutualOrderId, orderMutualQueryVO.getOrderId()));
    }

    @Override
    public void deleteBatchMutualOrderByOrderId(List<OrderMutualQueryVO> orderMutualQueryVOList) {
        if (orderMutualQueryVOList != null && orderMutualQueryVOList.size() > 0) {
            for (OrderMutualQueryVO orderMutualQueryVO : orderMutualQueryVOList) {
                mutualMapper.delete(new LambdaQueryWrapperX<OrderMutualDO>()
                        .eqIfPresent(OrderMutualDO::getOrderId, orderMutualQueryVO.getOrderId())
                        .eqIfPresent(OrderMutualDO::getMutualOrderId, orderMutualQueryVO.getMutualOrderId()));
                mutualMapper.delete(new LambdaQueryWrapperX<OrderMutualDO>()
                        .eqIfPresent(OrderMutualDO::getOrderId, orderMutualQueryVO.getMutualOrderId())
                        .eqIfPresent(OrderMutualDO::getMutualOrderId, orderMutualQueryVO.getOrderId()));
            }
        }
    }


    @Override
    public List<OrderMutualDO> getMutualList(Set<Long> orderIdSet) {
        return mutualMapper.selectList(new LambdaQueryWrapperX<OrderMutualDO>()
                .in(OrderMutualDO::getOrderId, orderIdSet)
        );
    }

    @Override
    public List<OrderDO> searchMutualOrderList(Long orderId, Set<Long> orderIdSet) {
        List<OrderMutualDO> orderMutualList = getMutualList(orderIdSet);

        List<OrderDO> orderList = null;
        if (CollectionUtil.isNotEmpty(orderMutualList)) {
            //有互斥订单
            List<Long> mutualOrderIdList = new ArrayList<>();
            for (OrderMutualDO orderMutualDO : orderMutualList) {
                Long oId = orderMutualDO.getOrderId();
                Long mutualOrderId = orderMutualDO.getMutualOrderId();
                if (oId.equals(orderId)) {
                    mutualOrderIdList.add(mutualOrderId);
                } else if (mutualOrderId.equals(orderId)) {
                    mutualOrderIdList.add(oId);
                }
            }
            if(CollectionUtil.isNotEmpty(mutualOrderIdList)) {
                orderList = orderQueryService.getOrderList(mutualOrderIdList);
            }
        }
        return orderList;
    }
}
