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

import com.prolog.cs.basic.warehouse.model.vo.BaseEisWarehouseLocatorVo;
import com.prolog.eis.common.util.PrologStringUtils;
import com.prolog.eis.common.util.location.LocationConstants;
import com.prolog.eis.core.dto.route.ItemContainerReqDto;
import com.prolog.eis.core.model.base.area.WhArea;
import com.prolog.eis.core.model.base.area.WhAreaDirection;
import com.prolog.eis.core.model.base.locator.WhLocator;
import com.prolog.eis.core.model.biz.carry.CarryTask;
import com.prolog.eis.core.model.biz.route.ContainerLocation;
import com.prolog.eis.dao.out.ContainerInfoDetailMapper;
import com.prolog.eis.dao.out.ContainerInfoMapper;
import com.prolog.eis.feign.PlgFeignRouteClient;
import com.prolog.eis.feign.WarehouseFeignService;
import com.prolog.eis.model.container.ContainerInfo;
import com.prolog.eis.model.container.ContainerInfoDetail;
import com.prolog.eis.router.vo.ContainerLocationVo;
import com.prolog.eis.service.route.RouteInterfaceService;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.utils.AssertUtils;
import com.prolog.framework.utils.MapUtils;
import com.prolog.framework.utils.ObjectUtils;
import com.prolog.framework.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * EIS3.0接口服务实现类
 *
 * @author zhanghan
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RouteInterfaceServiceImpl implements RouteInterfaceService {

    private final WarehouseFeignService warehouseFeignService;
    private final PlgFeignRouteClient routeFeignService;
    private final ContainerInfoMapper containerInfoMapper;
    private final ContainerInfoDetailMapper containerInfoDetailMapper;

    @Override
    public List<BaseEisWarehouseLocatorVo> findLocatorByLocationList(List<String> locationList) {
        try {
            RestMessage<List<BaseEisWarehouseLocatorVo>> restMessage = warehouseFeignService.findLocatorByLocationList(locationList);
            AssertUtils.isTrue(restMessage.isSuccess(), restMessage.getMessage());
            return Optional.ofNullable(restMessage.getData()).orElse(new ArrayList<>());
        } catch (Exception e) {
            throw new PrologException(String.format("调用warehouse服务[findLocatorByLocationList]接口异常:%s", e.getMessage()));
        }
    }

    @Override
    public void createItemContainer(String palletNo, String location, String businessProperty) {
        try {
            ItemContainerReqDto reqDto = new ItemContainerReqDto();
            reqDto.setContainerNo(palletNo);
            reqDto.setLocationNo(location);
            reqDto.setBusinessProperty(businessProperty);
            RestMessage<String> restMessage = routeFeignService.createItemContainer(reqDto);
            AssertUtils.isTrue(restMessage.isSuccess(), restMessage.getMessage());
        } catch (Exception e) {
            throw new PrologException(String.format("调用route服务[createItemContainer]接口异常:%s", e.getMessage()));
        }
    }

    @Override
    public List<WhLocator> getLocatorByLocation(List<String> locationList) {
        try {
            RestMessage<List<WhLocator>> restMessage = warehouseFeignService.getLocatorByLocation(locationList);
            AssertUtils.isTrue(restMessage.isSuccess(), restMessage.getMessage());
            return Optional.ofNullable(restMessage.getData()).orElse(new ArrayList<>());
        } catch (Exception e) {
            throw new PrologException(String.format("调用warehouse服务[getLocatorByLocation]接口异常:%s", e.getMessage()));
        }
    }

    @Override
    public List<ContainerLocationVo> findLocationByContainerList(List<String> palletNoList) {
        try {
            RestMessage<List<ContainerLocationVo>> restMessage = routeFeignService.findLocationByContainerList(palletNoList);
            AssertUtils.isTrue(restMessage.isSuccess(), restMessage.getMessage());
            return Optional.ofNullable(restMessage.getData()).orElse(new ArrayList<>());
        } catch (Exception e) {
            throw new PrologException(String.format("调用route服务[findLocationByContainerList]接口异常:%s", e.getMessage()));
        }
    }

    @Override
    public void commonContainerUpList(List<ItemContainerReqDto> commonContainerUpList) {
        try {
            RestMessage<String> restMessage = routeFeignService.commonContainerUpList(commonContainerUpList);
            AssertUtils.isTrue(restMessage.isSuccess(), restMessage.getMessage());
        } catch (Exception e) {
            throw new PrologException(String.format("调用route服务[commonContainerUpList]接口异常:%s", e.getMessage()));
        }
    }

    @Override
    public WhArea getAreaByAreaNo(String areaNo) {
        try {
            RestMessage<WhArea> restMessage = warehouseFeignService.getAreaByAreaNo(areaNo);
            AssertUtils.isTrue(restMessage.isSuccess(), restMessage.getMessage());
            return restMessage.getData();
        } catch (Exception e) {
            throw new PrologException(String.format("调用warehouse服务[getAreaByAreaNo]接口异常:%s", e.getMessage()));
        }
    }

    @Override
    public List<WhAreaDirection> findStartAreaOrEndArea(List<String> areaNoList) {
        try {
            RestMessage<List<WhAreaDirection>> restMessage = warehouseFeignService.findStartAreaOrEndArea(areaNoList);
            AssertUtils.isTrue(restMessage.isSuccess(), restMessage.getMessage());
            return Optional.ofNullable(restMessage.getData()).orElse(new ArrayList<>());
        } catch (Exception e) {
            throw new PrologException(String.format("调用warehouse服务[findStartAreaOrEndArea]接口异常:%s", e.getMessage()));
        }
    }

    @Override
    public ContainerLocation seachLocationNo(Map<String, Object> containerMap) throws Exception {
        if(containerMap == null || containerMap.size() == 0) {
            throw new Exception("根据容器编号查询点位错误，容器参数为空");
        }
        RestMessage<List<ContainerLocation>> result = routeFeignService.seachLocationNo(containerMap);
        if(!result.isSuccess()) {
            throw new Exception("根据容器编号查询点位异常");
        }
        if(ObjectUtils.isEmpty(result.getData())){
            throw new Exception("根据容器编号查询点位异常：数据未查询到");
        }
        return result.getData().get(0);
    }

    @Override
    public void createCarryTask(String containerNo, Integer taskType, String startRegion, String startLocation, String endRegion, String endLocation, String businessType, Integer height, String describe, String businessProperty) throws Exception {
        CarryTask carryTask = new CarryTask();
        carryTask.setTaskType(LocationConstants.PATH_TASK_TYPE_CARRY);
        if (Objects.nonNull(taskType)) {
            //20清点位
            carryTask.setTaskType(taskType);
        }
        carryTask.setId(PrologStringUtils.newGUID());
        carryTask.setContainerNo(containerNo);
        carryTask.setPalletNo(containerNo);
        carryTask.setStartRegion(startRegion);
        carryTask.setStartLocation(startLocation);

        if (StringUtils.isBlank(startRegion) || StringUtils.isBlank(startLocation)) {
            ContainerLocation containerLocation = seachLocationNo(MapUtils.put("containerNo", containerNo).getMap());
            carryTask.setStartRegion(containerLocation.getCurrentArea());
            carryTask.setStartLocation(containerLocation.getCurrentLocation());
        }
        carryTask.setEndRegion(endRegion);
        if (org.apache.commons.lang.StringUtils.isNotEmpty(endLocation)) {
            carryTask.setEndLocation(endLocation);
        }
        if (Objects.nonNull(height)){
            carryTask.setHeight(height);
        }

        if(StringUtils.isEmpty(businessProperty)){
            businessProperty = "EMPTY";
            ContainerInfo containerInfo = containerInfoMapper.findByMap(MapUtils.put("containerNo",containerNo).getMap(),ContainerInfo.class).stream().findFirst().orElse(null);
            if(containerInfo != null && "3".equals(containerInfo.getContainerType())){
                List<ContainerInfoDetail> containerInfoDetailDtos = containerInfoDetailMapper.findByMap(MapUtils.put("containerNo",containerInfo.getContainerNo()).getMap(),ContainerInfoDetail.class);
                if(CollectionUtils.isNotEmpty(containerInfoDetailDtos)){
                    StringBuilder businessTypeBuilder = new StringBuilder();
                    for (ContainerInfoDetail containerInfoDetailDto : containerInfoDetailDtos) {
                        //businessProperty
                        businessTypeBuilder.append(containerInfoDetailDto.getItemId() + "@@" + containerInfoDetailDto.getLotId() + "&");
                    }
                    //设置BusinessType
                    businessProperty = businessTypeBuilder.deleteCharAt(businessTypeBuilder.length() - 1).toString();
                }
            }
        }


        carryTask.setBusinessProperty(businessProperty);
        carryTask.setBusinessType(String.valueOf(businessType));
        carryTask.setBusinessDescribe(describe);
        carryTask.setPriority(99);
        routeFeignService.createCarry(carryTask);
    }
}
