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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Maps;
import com.prolog.eis.api.StrategyApi;
import com.prolog.eis.bcr_handle.BcrHandleStrategy;
import com.prolog.eis.common.util.JsonHelper;
import com.prolog.eis.common.util.PrologHttpUtils;
import com.prolog.eis.component.core.dto.mcs.McsCarryRequestDto;
import com.prolog.eis.core.dto.route.ContainerLocationDto;
import com.prolog.eis.dto.wcs.*;
import com.prolog.eis.feign.McsInterfaceFeignClient;
import com.prolog.eis.inter.dto.mcs.ZxMcsExitRequestDto;
import com.prolog.eis.inter.dto.mcs.ZxMcsExitResponseDto;
import com.prolog.eis.model.container.LocationCfg;
import com.prolog.eis.router.vo.ContainerLocationVo;
import com.prolog.eis.service.carry.StackerService;
import com.prolog.eis.service.config.BcrConfigService;
import com.prolog.eis.service.container.LocationCfgService;
import com.prolog.eis.service.feign.RouteFeignService;
import com.prolog.eis.service.led.LedService;
import com.prolog.eis.service.wcs.WcsService;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.utils.MapUtils;
import com.prolog.framework.utils.StringUtils;
import com.prolog.fx.inf.core.InterfaceType;
import com.prolog.fx.inf.core.annotation.InterfaceMethod;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;

@Slf4j
@Service
@RequiredArgsConstructor
public class WcsServiceImpl implements WcsService {

    @Autowired
    private Map<String, BcrHandleStrategy> map;
    private final StackerService stackerService;
    private final BcrConfigService bcrConfigService;
    private final McsInterfaceFeignClient mcsInterfaceFeignClient;
    private final RestTemplate newRestTemplate;
    private final LocationCfgService locationCfgService;
    private final RouteFeignService routeFeignService;
    private final LedService ledService;
    @Value("${mcs.get-exit-status}")
    private String url;

    @Override
    public List<McsResponseDto> mcsRequest(CarryListDto carryListDto) {
        List<McsResponseDto> mcsResponseDtoList = new ArrayList<>();
        List<BcrConfigDto> bcrConfigDtoList = bcrConfigService.findAllConfig();
        for (BcrRequestDto bcrRequestDto : carryListDto.getCarryList()) {
            McsResponseDto mcsResponseDto = new McsResponseDto();
            mcsResponseDto.setTaskId(bcrRequestDto.getTaskId());
            try {
                String s = StrategyApi.doBcrAsyncHandle(map, bcrRequestDto, bcrConfigDtoList);
                if (!StringUtils.isBlank(s)) {
                    ledService.sendInboundErrMsg(bcrRequestDto.getSource(), bcrRequestDto.getStockId(), s);
                    traySendBack(bcrRequestDto, s);
                    mcsResponseDto.setErrorMsg(s);
                    mcsResponseDtoList.add(mcsResponseDto);
                } else {
                    ledService.sendInboundSuccessMsg(bcrRequestDto.getSource(), bcrRequestDto.getStockId());
                }
            } catch (Exception e) {
                //后退
                log.error("MCS异步请求{}异常：" + e.getMessage(), e);
                ledService.sendInboundErrMsg(bcrRequestDto.getSource(), bcrRequestDto.getStockId(), e.getMessage());
                traySendBack(bcrRequestDto, e.getMessage());
                mcsResponseDto.setTaskId(bcrRequestDto.getTaskId());
                mcsResponseDto.setErrorMsg(e.getMessage() == null ? "系统异常" : e.getMessage());
                mcsResponseDtoList.add(mcsResponseDto);
            }
        }
        return mcsResponseDtoList;
    }

    @Override
    @InterfaceMethod(key = "发送回退任务", name = "EIS->MCS发送回退任务", type = InterfaceType.Send)
    public void traySendBack(BcrRequestDto bcrRequestDto, String message) {
        try {
            ContainerLocationDto locationInfo = routeFeignService.findContainerInfoByLocationNotCheck(MapUtils.put("locationNo", bcrRequestDto.getSource()).getMap());
            if (Objects.nonNull(locationInfo) && StrUtil.isNotBlank(locationInfo.getContainerNo())) {
                routeFeignService.containerOffShelf(locationInfo.getContainerNo());
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        McsCarryRequestDto mcsSendTaskDto = new McsCarryRequestDto();
        mcsSendTaskDto.setTaskId(UUID.randomUUID().toString());
        mcsSendTaskDto.setType(99);
        mcsSendTaskDto.setPalletNo(bcrRequestDto.getStockId());
        mcsSendTaskDto.setSourceLocation(bcrRequestDto.getSource());
        mcsSendTaskDto.setTargetLocation("-1");
        mcsSendTaskDto.setPriority(1);
        mcsSendTaskDto.setWeight(bcrRequestDto.getWeight());
        mcsSendTaskDto.setStatus(0);
        mcsSendTaskDto.setEquipmentFirm("MCS");
        try {
            mcsInterfaceFeignClient.sendCarryTaskAsync(mcsSendTaskDto);
        } catch (Exception e) {
            log.error("容器跑【{}】回退任务发送失败" + e.getMessage(), bcrRequestDto.getStockId(), e);
        }
        log.warn("入库点位【{}】容器【{}】回退原因" + message, bcrRequestDto.getSource(), bcrRequestDto.getStockId());
    }


    @Override
    public List<ZxMcsExitResponseDto> getExitStatus(List<ZxMcsExitRequestDto> list) throws Exception {
        Map<String, Object> map = Maps.newHashMap();
        map.put("carryList", list);
        String data = JsonHelper.toJson(map);
        log.info(String.format("[ZXGetExitStatus]：eis->zxMcs点位信息查询：%s", data));
        String result = newRestTemplate.postForObject(url, PrologHttpUtils.getRequestEntity(data), String.class);
        log.info(String.format("[ZXGetExitStatus]：eis->zxMcs点位信息查询：%s", result));

        Boolean success = JsonHelper.getBoolean("ret", result);
        String message = JsonHelper.getString("msg", result);
        Assert.isTrue(success, "eis->zxMcs点位信息查询异常：【{}】", message);
        List<ZxMcsExitResponseDto> exitResponseDto = JsonHelper.getKeyObjectList("data", result, ZxMcsExitResponseDto.class);
        Assert.isTrue(CollectionUtil.isNotEmpty(exitResponseDto), "eis->zxMcs点位信息查询返回data为null");
        return exitResponseDto;
    }

    @Override
    public void stackerRequest(StackerTaskDto taskDto) throws Exception{
        switch (taskDto.getType()) {
            case 1:
                //拆盘机
                break;
            case 2:
                //叠盘机
                stackerService.sendStore(taskDto);
                break;
        }
    }

    @Override
    public void alarmReport(AlarmReportDto taskDto) {
        Criteria criteria = new Criteria(LocationCfg.class);
        criteria.restrictionBuilder().in(LocationCfg::getType, Arrays.asList(70, 71)).build();
        List<LocationCfg> locationCfgList = locationCfgService.findByCriteria(criteria);
        if (CollectionUtil.isEmpty(locationCfgList)) {
            return;
        }
        List<AlarmReportReqDto> carryList = taskDto.getCarryList();
        for (AlarmReportReqDto alarmReportReqDto : carryList) {
            LocationCfg locationCfg = locationCfgList.stream().filter(item -> StrUtil.equals(alarmReportReqDto.getDevice(), item.getSqid())).findFirst().orElse(null);
            if (Objects.nonNull(locationCfg)) {
                Integer status = locationCfg.getStatus();
                //上报了叠盘机故障 表里数据状态为非故障 修改
                if (alarmReportReqDto.getStatus() == 3 && status == 1) {
                    locationCfg.setStatus(0);
                    locationCfgService.update(locationCfg);
                }
                if (alarmReportReqDto.getStatus() != 3 && status == 0) {
                    locationCfg.setStatus(1);
                    locationCfgService.update(locationCfg);
                }
            }
        }
    }
}
