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

import cn.hutool.core.collection.CollectionUtil;
import com.prolog.eis.constants.base.OrderStatusConstants;
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.outbound.BizOutboundTask;
import com.prolog.eis.model.outbound.BizOutboundTaskDetail;
import com.prolog.eis.service.out.*;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.utils.MapUtils;
import org.apache.commons.collections.CollectionUtils;
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 BizOutboundTaskDetailHisMapper outboundTaskDetailHisMapper;
    @Autowired
    private BizOutboundTaskDetailDismantleService bizOutboundTaskDetailDismantleService;
    @Autowired
    private BizOutboundTaskDetailDismantleGridMapper outboundTaskDetailDismantleGridMapper;
    @Autowired
    private BizOutboundTaskDetailDismantleGridHisMapper outboundTaskDetailDismantleGridHisMapper;
    @Autowired
    private BizOutboundTaskDetailItemService outboundTaskDetailItemService;

    /**
     * 新增数据
     *
     * @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 List<OrderDto> getCreateOutboundTaskLSList(String billType, String warehouseArea) {
        return bizOutboundTaskMapper.getCreateOutboundTaskLSList(billType, warehouseArea);
    }

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

    @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 void batchUpdateStatus(List<Integer> ids, Integer status) {
        if(CollectionUtils.isEmpty(ids)){
            return;
        }
        Criteria criteria = Criteria.forClass(BizOutboundTask.class);
        criteria.restrictionBuilder().in(BizOutboundTaskDetail :: getId,ids.toArray()).build();
        bizOutboundTaskMapper.updateMapByCriteria(MapUtils
                .put("status", OrderStatusConstants.START_STATUS)
                .put("updateTime",LocalDateTime.now()).getMap(),criteria);
    }
}
