package com.cf.imes.module.executor.service.order;

import co.elastic.clients.elasticsearch.core.BulkResponse;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.es.core.service.ESDocumentService;
import com.cf.imes.module.executor.dal.dataobject.goods.GoodsDO;
import com.cf.imes.module.executor.dal.dataobject.order.OrderDO;
import com.cf.imes.module.executor.dal.dataobject.orderBody.OrderBodyDO;
import com.cf.imes.module.executor.dal.dataobject.orderGroup.OrderGroupDO;
import com.cf.imes.module.executor.dal.dataobject.orderItem.OrderItemDO;
import com.cf.imes.module.executor.dal.dataobject.orderModuleExtra.OrderModuleExtraDO;
import com.cf.imes.module.executor.dal.dataobject.orderParts.OrderPartsDO;
import com.cf.imes.module.executor.dal.dataobject.ordermodel.OrderModelDO;
import com.cf.imes.module.executor.dal.dataobject.plate.PlateDO;
import com.cf.imes.module.executor.dal.dataobject.plate.PlateGoodDO;
import com.cf.imes.module.executor.dal.dataobject.rawgoods.RawGoodsDO;
import com.cf.imes.module.executor.dal.mysql.goods.GoodsMapper;
import com.cf.imes.module.executor.dal.mysql.order.OrderMapper;
import com.cf.imes.module.executor.dal.mysql.orderBody.OrderBodyMapper;
import com.cf.imes.module.executor.dal.mysql.orderGroup.OrderGroupMapper;
import com.cf.imes.module.executor.dal.mysql.orderItem.OrderItemMapper;
import com.cf.imes.module.executor.dal.mysql.orderModuleExtra.OrderModuleExtraMapper;
import com.cf.imes.module.executor.dal.mysql.orderParts.OrderPartsMapper;
import com.cf.imes.module.executor.dal.mysql.plate.PlateGoodMapper;
import com.cf.imes.module.executor.dal.mysql.plate.PlateMapper;
import com.cf.imes.module.executor.dal.mysql.rawgoods.RawGoodsMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @author Beal
 * 生产单入库处理器
 */
@Slf4j
@Component
public class OrderInputProcessor {

    @Resource
    private IdentifierGenerator identifierGenerator;
    /*private IdentifierGenerator identifierGenerator = new SnowFlakeGenerator(0, 0);*/

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private RawGoodsMapper rawGoodsMapper;

    @Resource
    private OrderBodyMapper orderBodyMapper;

    @Resource
    private OrderGroupMapper orderGroupMapper;

    @Resource
    private OrderPartsMapper orderPartsMapper;

    @Resource
    private PlateMapper plateMapper;

    @Resource
    private OrderItemMapper orderItemMapper;

    @Resource
    private GoodsMapper goodsMapper;

    @Resource
    private PlateGoodMapper plateGoodMapper;

    @Resource
    private OrderModuleExtraMapper orderModuleExtraMapper;

    @Resource
    private ESDocumentService esDocumentService;

    public static final String ORDER_PLATE_MODEL = "imes_order_plate_model";

    /**
     * 批量保存生产单小板五金数据
     *
     * @param rawGoodsDOS
     * @param orderBodyDOS
     * @param orderGroupDOS
     * @param orderPartsDOS
     * @param plateDOS
     * @param orderModuleExtraDOS
     * @param itemDOS
     */
    @Transactional(rollbackFor = Exception.class)
    public Long batchInsert(Collection<RawGoodsDO> rawGoodsDOS, Collection<OrderBodyDO> orderBodyDOS,
                            Collection<OrderGroupDO> orderGroupDOS, Collection<OrderPartsDO> orderPartsDOS,
                            Collection<PlateDO> plateDOS, Collection<OrderModuleExtraDO> orderModuleExtraDOS,
                            Collection<OrderItemDO> itemDOS, OrderDO orderDO,
                            Collection<GoodsDO> goodsDOS, Collection<PlateGoodDO> plateGoodDOS) {
        if (orderDO != null)
            orderMapper.insert(orderDO);

        if (rawGoodsDOS != null)
            for (int i = 0; i < rawGoodsDOS.size(); i += 1000) {
                rawGoodsMapper.insertBatch(rawGoodsDOS.stream().skip(i).limit(1000).collect(Collectors.toList()));
            }
        if (orderBodyDOS != null)
            for (int i = 0; i < orderBodyDOS.size(); i += 1000) {
                orderBodyMapper.insertBatch(orderBodyDOS.stream().skip(i).limit(1000).collect(Collectors.toList()));
            }
        if (orderGroupDOS != null)
            for (int i = 0; i < orderGroupDOS.size(); i += 1000) {
                orderGroupMapper.insertBatch(orderGroupDOS.stream().skip(i).limit(1000).collect(Collectors.toList()));
            }
        if (orderPartsDOS != null)
            for (int i = 0; i < orderPartsDOS.size(); i += 1000) {
                orderPartsMapper.insertBatch(orderPartsDOS.stream().skip(i).limit(1000).collect(Collectors.toList()));
            }
        if (plateDOS != null)
            for (int i = 0; i < plateDOS.size(); i += 1000) {
                plateMapper.insertBatch(plateDOS.stream().skip(i).limit(1000).collect(Collectors.toList()));
            }
        if (orderModuleExtraDOS != null) {
            for (int i = 0; i < orderModuleExtraDOS.size(); i += 1000) {
                orderModuleExtraMapper.insertBatch(orderModuleExtraDOS.stream().skip(i).limit(1000).collect(Collectors.toList()));
            }
        }
        if (itemDOS != null) {
            for (int i = 0; i < itemDOS.size(); i += 1000) {
                orderItemMapper.insertBatch(itemDOS.stream().skip(i).limit(1000).collect(Collectors.toList()));
            }
        }
        if (goodsDOS != null) {
            for (int i = 0; i < itemDOS.size(); i += 1000) {
                goodsMapper.insertBatch(goodsDOS.stream().skip(i).limit(1000).collect(Collectors.toList()));
            }
        }
        if (plateGoodDOS != null) {
            for (int i = 0; i < itemDOS.size(); i += 1000) {
                plateGoodMapper.insertBatch(plateGoodDOS.stream().skip(i).limit(1000).collect(Collectors.toList()));
            }
        }
        //rawGoodsMapper.insertBatch(rawGoodsDOS);
        //orderBodyMapper.insertBatch(orderBodyDOS);
        //orderGroupMapper.insertBatch(orderGroupDOS);
        //orderPartsMapper.insertBatch(orderPartsDOS);
        //plateMapper.insertBatch(plateDOS);
        //orderModuleExtraMapper.insertBatch(orderModuleExtraDOS);
        //orderItemMapper.insertBatch(itemDOS);
        return orderDO.getId();
    }

    /**
     * 保存生产单造型数据
     *
     * @param orderModelDOs
     */
    public void batchSaveModel(List<OrderModelDO> orderModelDOs) {
        try {
            BulkResponse bulkResponse = esDocumentService.bulkCreate(ORDER_PLATE_MODEL, orderModelDOs);
            boolean errors = bulkResponse.errors();
            if (errors) {
                log.error(bulkResponse.items().toString());
                throw new ServiceException(500, "未知异常");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            throw new RuntimeException(e);
        }

    }
}
