package com.prolog.eis.service.out.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.prolog.eis.dao.out.*;
import com.prolog.eis.dto.strategy.OrderDto;
import com.prolog.eis.enums.base.BaseStatusEnum;
import com.prolog.eis.enums.wms.WmsCarryTaskInCode;
import com.prolog.eis.model.out.*;
import com.prolog.eis.model.outbound.BizOutboundTask;
import com.prolog.eis.model.outbound.BizOutboundTaskDetail;
import com.prolog.eis.model.outbound.BizOutboundTaskDetailHis;
import com.prolog.eis.model.outbound.BizOutboundTaskHis;
import com.prolog.eis.service.out.*;
import com.prolog.eis.utils.MapUtils;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.core.restriction.Criteria;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zmr
 * @description: 出库任务表-服务实现类
 * @date 2023-08-30 12:24
 */
@Service
public class BizOutboundTaskServiceImpl implements BizOutboundTaskService {

    @Autowired
    private BizOutboundTaskMapper bizOutboundTaskMapper;
    @Autowired
    private BizOutboundTaskDetailMapper bizOutboundTaskDetailMapper;
    @Autowired
    private ContainerTaskMapper containerTaskMapper;
    @Autowired
    private BizOutboundTaskDismantleSupplyService outboundTaskDismantleSupplyService;
    @Autowired
    private BizOutboundTaskHisService outboundTaskHisService;
    @Autowired
    private BizOutboundTaskDetailHisMapper outboundTaskDetailHisMapper;
    @Autowired
    private BizOutboundTaskDetailDismantleService bizOutboundTaskDetailDismantleService;
    @Autowired
    private BizOutboundTaskDetailDismantleHisService outboundTaskDetailDismantleHisService;
    @Autowired
    private BizOutboundTaskDetailDismantleGridMapper outboundTaskDetailDismantleGridMapper;
    @Autowired
    private BizOutboundTaskDetailDismantleGridHisMapper outboundTaskDetailDismantleGridHisMapper;
    @Autowired
    private BizOutboundTaskDetailItemService outboundTaskDetailItemService;
    @Autowired
    private BizOutboundTaskDetailItemHisService outboundTaskDetailItemHisService;

    /**
     * 新增数据
     *
     * @param bizOutboundTask 出库任务表
     */
    @Override
    public long save(BizOutboundTask bizOutboundTask) {
        return bizOutboundTaskMapper.save(bizOutboundTask);
    }

    /**
     * 新增批量数据
     *
     * @param bizOutboundTaskList 出库任务表
     */
    @Override
    public long saveBatch(List<BizOutboundTask> bizOutboundTaskList) {
        return bizOutboundTaskMapper.saveBatch(bizOutboundTaskList);
    }

    /**
     * 查询多条数据
     *
     * @param paramMap 查询起始位置
     * @return 对象列表
     */
    @Override
    public List<BizOutboundTask> findByMap(Map<String, Object> paramMap) {
        return bizOutboundTaskMapper.findByMap(paramMap, BizOutboundTask.class);
    }

    /**
     * 查询单条数据
     *
     * @param paramMap 查询起始位置
     * @return 对象
     */
    @Override
    public BizOutboundTask findOneByMap(Map<String, Object> paramMap) {
        List<BizOutboundTask> dataList = findByMap(paramMap);
        if (CollectionUtil.isEmpty(dataList)) {
            throw new PrologException("未查询到订单");
        }
        return dataList.get(0);
    }

    /**
     * 查询多条数据
     *
     * @param criteria 查询起始位置
     * @return 对象列表
     */
    @Override
    public List<BizOutboundTask> findByCriteria(Criteria criteria) {
        return bizOutboundTaskMapper.findByCriteria(criteria);
    }

    @Override
    public long findCountByCriteria(Criteria criteria) {
        return bizOutboundTaskMapper.findCountByCriteria(criteria);
    }

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public BizOutboundTask findById(int id) {
        return bizOutboundTaskMapper.findById(id, BizOutboundTask.class);
    }

    /**
     * 修改数据
     *
     * @param bizOutboundTask 实例对象
     */
    @Override
    public long update(BizOutboundTask bizOutboundTask) {
        return bizOutboundTaskMapper.update(bizOutboundTask);
    }


    /**
     * 修改数据
     *
     */
    @Override
    public long updateMapByCriteria(Map<String,Object> params,Criteria criteria) {
        return bizOutboundTaskMapper.updateMapByCriteria(params,criteria);
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     */
    @Override
    public long deleteById(int id) {
        return bizOutboundTaskMapper.deleteById(id, BizOutboundTask.class);
    }

    /**
     * 通过参数删除数据
     *
     * @param paramMap 参数
     */
    @Override
    public long deleteByMap(Map<String, Object> paramMap) {
        return bizOutboundTaskMapper.deleteByMap(paramMap, BizOutboundTask.class);
    }

    /**
     * 通过参数查询总条数
     *
     * @param paramMap 参数
     */
    @Override
    public long findCountByMap(Map<String, Object> paramMap) {
        return bizOutboundTaskMapper.findCountByMap(paramMap, BizOutboundTask.class);
    }

    @Override
    public List<OrderDto> getOutboundTaskByBillType(String billType, String warehouseArea, String assemblyOrderSwitch,int checkStore,int isBindGrid) {
        return bizOutboundTaskMapper.getOutboundTaskByBillType(billType, warehouseArea, assemblyOrderSwitch,checkStore,isBindGrid);
    }

    @Override
    public List<OrderDto> getOutboundTaskList(String billType, String warehouseArea) {
        return bizOutboundTaskMapper.getOutboundTaskList(billType, warehouseArea);
    }

    @Override
    public List<OrderDto> getCreateOutboundTaskList(String billType, String warehouseArea) {
        return bizOutboundTaskMapper.getCreateOutboundTaskList(billType, warehouseArea);
    }

    @Override
    public void updateById(Integer orderId, Map<String, Object> params) {
        bizOutboundTaskMapper.updateMapById(orderId, params, BizOutboundTask.class);
    }

    @Override
    public List<OrderDto> getOutboundTaskByArea(String agvl) {
        return bizOutboundTaskMapper.getOutboundTaskByArea(agvl);
    }

    @Override
    public List<BizOutboundTask> findOutTaskList(String warehouseArea, String billType) {
        return bizOutboundTaskMapper.findOutTaskList(warehouseArea,billType);
    }

    @Override
    public void batchUpdate(List<BizOutboundTask> updateBizOutboundTaskList) {
        for (BizOutboundTask bizOutboundTask : updateBizOutboundTaskList) {
            update(bizOutboundTask);
        }
    }

    /**
     * 获取拆零区新建状态的盘点/养护订单
     */
    @Override
    public List<BizOutboundTask> getAGVLPdYhOrder() {
        Criteria criteria = new Criteria(BizOutboundTask.class);
        criteria.restrictionBuilder().eq(BizOutboundTask::getStatus, BaseStatusEnum.STATUS_INIT.getCode())
                .eq(BizOutboundTask::getWmsLocationCode, WmsCarryTaskInCode.AGVL.getCode())
                .in(BizOutboundTask::getWorkType, Arrays.asList(40, 50)).build();
        List<BizOutboundTask> bizOutboundTaskList = bizOutboundTaskMapper.findByCriteria(criteria);
        if (CollectionUtil.isEmpty(bizOutboundTaskList)) {
            return bizOutboundTaskList;
        }
        List<Integer> orderIds = bizOutboundTaskList.stream().map(BizOutboundTask::getId).collect(Collectors.toList());
        Criteria detailCriteria = new Criteria(BizOutboundTaskDetail.class);
        detailCriteria.restrictionBuilder().in(BizOutboundTaskDetail::getOutboundId, orderIds).build();
        List<BizOutboundTaskDetail> bizOutboundTaskDetailList = bizOutboundTaskDetailMapper.findByCriteria(detailCriteria);
        bizOutboundTaskList.forEach(item->{
            List<BizOutboundTaskDetail> list = bizOutboundTaskDetailList.stream().filter(inner -> Objects.equals(item.getId(), inner.getOutboundId())).collect(Collectors.toList());
            item.setSubList(list);
        });
        return bizOutboundTaskList;
    }

    @Override
    public boolean outboundToHis(BizOutboundTask outboundTask) {
        //查询是否有补货任务还没有下发
        final List<BizOutboundTaskDismantleSupply> supplyList = outboundTaskDismantleSupplyService.findByMap(MapUtils.put(BizOutboundTaskDismantleSupply::getOutboundId, outboundTask.getId()).getMap());
        if (CollectionUtils.isEmpty(supplyList)) {
            BizOutboundTaskHis outboundTaskHis = new BizOutboundTaskHis();
            BeanUtils.copyProperties(outboundTask,outboundTaskHis);
            outboundTaskHis.setStatus(BaseStatusEnum.STATUS_FINISH.getCode());
            outboundTaskHis.setUpdateTime(LocalDateTime.now());
            outboundTaskHisService.save(outboundTaskHis);
            this.deleteById(outboundTask.getId());
            //全零发整订单 物料转历史
            if (StrUtil.isNotBlank(outboundTask.getExtend2()) && StrUtil.equals(outboundTask.getExtend2(), "1")) {
                List<BizOutboundTaskDetailItem> outboundTaskDetailItems = outboundTaskDetailItemService.findByMap(MapUtils.put(BizOutboundTaskDetailItem::getExtend1, outboundTask.getBillNo()).getMap());
                if (CollectionUtils.isNotEmpty(outboundTaskDetailItems)) {
//                    BizOutboundTaskDetailItem bizOutboundTaskDetailItem = outboundTaskDetailItems.get(0);
//                    outboundTask = bizOutboundTaskMapper.findById(bizOutboundTaskDetailItem.getOutboundId(), BizOutboundTask.class);
//                    if (Objects.nonNull(outboundTask)) {
//                        outboundTaskHis = new BizOutboundTaskHis();
//                        BeanUtils.copyProperties(outboundTask,outboundTaskHis);
//                        outboundTaskHis.setStatus(BaseStatusEnum.STATUS_FINISH.getCode());
//                        outboundTaskHis.setUpdateTime(LocalDateTime.now());
//                        outboundTaskHisService.save(outboundTaskHis);
//                        this.deleteById(outboundTask.getId());
//                    }
                    for (BizOutboundTaskDetailItem outboundTaskDetailItem : outboundTaskDetailItems) {
                        BizOutboundTaskDetailItemHis outboundTaskDetailItemHis = new BizOutboundTaskDetailItemHis();
                        org.springframework.beans.BeanUtils.copyProperties(outboundTaskDetailItem, outboundTaskDetailItemHis);
                        outboundTaskDetailItemHisService.save(outboundTaskDetailItemHis);
                        outboundTaskDetailItemService.deleteById(outboundTaskDetailItem.getId());
                    }
                }
            }

            List<BizOutboundTaskDetail> bizOutboundTaskDetailList = bizOutboundTaskDetailMapper.findByMap(MapUtils.put(BizOutboundTaskDetail::getOutboundId, outboundTask.getId()).getMap(), BizOutboundTaskDetail.class);
            for (BizOutboundTaskDetail bizOutboundTaskDetail : bizOutboundTaskDetailList) {
                BizOutboundTaskDetailHis outboundTaskDetailHis = new BizOutboundTaskDetailHis();
                BeanUtils.copyProperties(bizOutboundTaskDetail, outboundTaskDetailHis);
                outboundTaskDetailHis.setStatus(BaseStatusEnum.STATUS_FINISH.getCode());
                outboundTaskDetailHis.setUpdateTime(LocalDateTime.now());
                outboundTaskDetailHisMapper.save(outboundTaskDetailHis);
                bizOutboundTaskDetailMapper.deleteById(bizOutboundTaskDetail.getId(), BizOutboundTaskDetail.class);
            }
            List<BizOutboundTaskDetailDismantle> outboundTaskDetailDismantleList = bizOutboundTaskDetailDismantleService.findByMap(MapUtils.put(BizOutboundTaskDetailDismantle::getOutboundId, outboundTask.getId()).getMap());
            for (BizOutboundTaskDetailDismantle bizOutboundTaskDetailDismantle : outboundTaskDetailDismantleList) {
                BizOutboundTaskDetailDismantleHis outboundTaskDetailDismantleHis = new BizOutboundTaskDetailDismantleHis();
                BeanUtils.copyProperties(bizOutboundTaskDetailDismantle, outboundTaskDetailDismantleHis);
                outboundTaskDetailDismantleHisService.save(outboundTaskDetailDismantleHis);
                bizOutboundTaskDetailDismantleService.deleteById(bizOutboundTaskDetailDismantle.getId());
            }
            List<BizOutboundTaskDetailDismantleGridHis> hisList = new ArrayList<>();
            List<BizOutboundTaskDetailDismantleGrid> outboundTaskDetailDismantleGrids = outboundTaskDetailDismantleGridMapper.findByMap(MapUtils.put(BizOutboundTaskDetailDismantleGrid::getOutboundId, outboundTask.getId()).getMap(), BizOutboundTaskDetailDismantleGrid.class);
            for (BizOutboundTaskDetailDismantleGrid outboundTaskDetailDismantleGrid : outboundTaskDetailDismantleGrids) {
                BizOutboundTaskDetailDismantleGridHis his = new BizOutboundTaskDetailDismantleGridHis();
                BeanUtils.copyProperties(outboundTaskDetailDismantleGrid, his);
                hisList.add(his);
                outboundTaskDetailDismantleGridMapper.deleteById(outboundTaskDetailDismantleGrid.getId(), BizOutboundTaskDetailDismantleGrid.class);
            }
            if (CollectionUtils.isNotEmpty(hisList)) {
                outboundTaskDetailDismantleGridHisMapper.saveBatch(hisList);
            }
            return true;
        }
        return false;
    }
}
