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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.prolog.eis.dto.item.ItemSyncVO;
import com.prolog.eis.constants.base.ContainerTaskStatusConstants;
import com.prolog.eis.dao.container.ContainerTaskHisMapper;
import com.prolog.eis.dao.container.ContainerTaskMapper;
import com.prolog.eis.dto.page.PickingConfirmReqDto;
import com.prolog.eis.dto.page.PickingDetailDto;
import com.prolog.eis.dto.page.PickingListDto;
import com.prolog.eis.dto.pms.PmsRobotTaskFinishReq;
import com.prolog.eis.dto.strategy.ContainerTaskDto;
import com.prolog.eis.model.container.ContainerTask;
import com.prolog.eis.model.container.ContainerTaskHis;
import com.prolog.eis.service.container.ContainerTaskService;
import com.prolog.eis.service.feign.FeignGoodsService;
import com.prolog.eis.service.outbound.BizOutboundTaskService;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.utils.AssertUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class ContainerTaskServiceImpl implements ContainerTaskService {

    private final ContainerTaskMapper containerTaskMapper;
    private final ContainerTaskHisMapper containerTaskHisMapper;
    private final BizOutboundTaskService bizOutboundTaskService;
    private final FeignGoodsService feignGoodsService;

    @Override
    public void batchSave(List<ContainerTask> containerTaskList) {
        containerTaskMapper.saveBatch(containerTaskList);
    }

    @Override
    public List<ContainerTask> findAll() {
        return containerTaskMapper.findByMap(null, ContainerTask.class);
    }

    @Override
    public List<ContainerTask> findByCriteria(Criteria criteria) {
        List<ContainerTask> containerTaskList = containerTaskMapper.findByCriteria(criteria);
        return containerTaskList;
    }

    @Override
    public Long findCountByCriteria(Criteria criteria) {
        return containerTaskMapper.findCountByCriteria(criteria);
    }

    @Override
    public void updateStatusBatch(List<ContainerTask> containerTaskList, int taskStatus) {
        containerTaskMapper.updateStatusBatch(containerTaskList, taskStatus);
    }

    @Override
    public void toHistory(List<ContainerTask> containerTaskList) {
        List<ContainerTaskHis> hisList = new ArrayList<>();
        for (ContainerTask containerTask : containerTaskList) {
            ContainerTaskHis containerTaskHis = new ContainerTaskHis();
            BeanUtil.copyProperties(containerTask, containerTaskHis);
            containerTaskHis.setStatus(ContainerTaskStatusConstants.FINISH_STATUS);
            hisList.add(containerTaskHis);
        }
        containerTaskMapper.deleteByIds(containerTaskList.stream().map(ContainerTask::getId).toArray(), ContainerTask.class);
        containerTaskHisMapper.saveBatch(hisList);
    }

    @Override
    public void createContainerTaskBatch(List<ContainerTaskDto> containerTaskDtoList) throws Exception {
        if (CollectionUtils.isEmpty(containerTaskDtoList)){
            throw new Exception("容器任务集合为空");
        }
        List<ContainerTask> containerTaskList = new ArrayList<>();
        for (ContainerTaskDto containerTaskDto : containerTaskDtoList) {
            //检验托盘是否已在运行中（同类型同波次同产成品才可保存）
            ContainerTask containerTask = new ContainerTask();
            containerTask.setContainerNo(containerTaskDto.getContainerNo());
            containerTask.setContainerSubNo(containerTaskDto.getContainerSubNo());
            containerTask.setContainerType(containerTaskDto.getContainerType());
            containerTask.setOutboundId(containerTaskDto.getOrderId());
            containerTask.setWaveNo(containerTaskDto.getWaveNo());
            containerTask.setCompanyId(containerTaskDto.getCompanyId());
            containerTask.setOutboundDetailId(containerTaskDto.getOrderDetailId());
            containerTask.setItemId(containerTaskDto.getItemId());
            containerTask.setLotId(containerTaskDto.getLotId());
            containerTask.setOwnerId(containerTaskDto.getOwnerId());
            containerTask.setPackId(containerTaskDto.getPackId());
            containerTask.setPickOrderId(containerTaskDto.getPickOrderId());
            containerTask.setTaskType(containerTaskDto.getTaskType());
            containerTask.setWarehouseArea(containerTaskDto.getWmsLocationCode());
            containerTask.setWmsLocationCode(containerTaskDto.getWmsLocationCode());
            containerTask.setStatus(0);
            containerTask.setQty(containerTaskDto.getBindingNum());
            containerTask.setCreateTime(LocalDateTime.now());
            containerTask.setPriorty(containerTaskDto.getPriority());
            containerTask.setShelvesState(0);
            containerTaskList.add(containerTask);
        }
        containerTaskMapper.saveBatch(containerTaskList);
    }

    @Override
    public List<PickingListDto> pickingList(String containerNo) throws Exception {
        List<PickingListDto> pickingListDtos = containerTaskMapper.pickingList(containerNo);
        List<String> itemIds = pickingListDtos.stream().map(PickingListDto::getItemId).collect(Collectors.toList());
        final List<ItemSyncVO> itemSyncVOS = feignGoodsService.queryItemMst(itemIds);
        for (PickingListDto pickingListDto : pickingListDtos) {
            ItemSyncVO itemInfo = itemSyncVOS.stream().filter(item -> StrUtil.equals(item.getItemId(), pickingListDto.getItemId())).findFirst().orElseThrow(() -> new PrologException("未查询到商品信息"));
            pickingListDto.setItemCode(itemInfo.getItemCode());
            pickingListDto.setItemName(itemInfo.getItemName());
        }
        return pickingListDtos;
    }

    @Override
    public List<PickingDetailDto> pickingDetail(Integer id) throws Exception {
         List<PickingDetailDto> pickingDetailDtos = containerTaskMapper.pickingDetail(id);
         List<String> itemIds = pickingDetailDtos.stream().map(PickingDetailDto::getItemId).collect(Collectors.toList());
        final List<ItemSyncVO> itemSyncVOS = feignGoodsService.queryItemMst(itemIds);
        for (PickingDetailDto pickingDetailDto : pickingDetailDtos) {
            ItemSyncVO itemInfo = itemSyncVOS.stream().filter(item -> StrUtil.equals(item.getItemId(), pickingDetailDto.getItemId())).findFirst().orElseThrow(() -> new PrologException("未查询到商品信息"));
            pickingDetailDto.setItemName(itemInfo.getItemName());
            pickingDetailDto.setCapacity(itemInfo.getSpecification());
        }
         return pickingDetailDtos;
    }

    @Override
    public void pickingConfirm(PickingConfirmReqDto req) throws Exception{
        ContainerTask containerTask = containerTaskMapper.findById(req.getId(), ContainerTask.class);
        AssertUtils.isNotTrue(containerTask.getQty().compareTo(req.getPickQty()) < 0, "拣选数量不能大于任务数量");

        PmsRobotTaskFinishReq pmsRobotTaskFinishReq = new PmsRobotTaskFinishReq();
        pmsRobotTaskFinishReq.setContainerNo(containerTask.getContainerNo());
        pmsRobotTaskFinishReq.setQty(req.getPickQty());
        bizOutboundTaskService.outboundConfirm(Arrays.asList(containerTask),pmsRobotTaskFinishReq);
    }

    @Override
    public void updateMapById(Integer id, Map<String, Object> params) {
        containerTaskMapper.updateMapById(id,params,ContainerTask.class);
    }
}

