package com.shkj.wcs.third.dps;

import com.alibaba.fastjson.JSON;
import com.shkj.common.core.domain.Result;
import com.shkj.common.core.domain.entity.BaseConsignor;
import com.shkj.plc.sdk.device.PLCReadAndWrite;
import com.shkj.plc.sdk.device.PlcHelper;
import com.shkj.plc.sdk.device.PlcOperate;
import com.shkj.system.service.ISysParameterService;
import com.shkj.wcs.bo.AGVTaskBo;
import com.shkj.wcs.bo.DpsStatesBo;
import com.shkj.wcs.domain.WcsPlcConnect;
import com.shkj.wcs.domain.WcsPlcProperty;
import com.shkj.wcs.plc.PlcInit;
import com.shkj.wcs.service.IWcsPlcConnectService;
import com.shkj.wcs.service.IWcsPlcPropertyService;
import com.shkj.wcs.third.dps.dto.BullBarsArrivalDto;
import com.shkj.wcs.third.rcs.RCSUtil;
import com.shkj.wcs.third.rcs.dto.RcsCreateTaskDto;
import com.shkj.wcs.third.rcs.dto.RcsIdList;
import com.shkj.wms.constants.ParameterConstants;
import com.shkj.wms.domain.BaseBarcodesIn;
import com.shkj.wms.domain.BusinDataTask;
import com.shkj.wms.service.IBaseBarcodesInService;
import com.shkj.wms.service.IBaseGoodsDataService;
import com.shkj.wms.service.IBusinDataTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class DpsCallUtil {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RCSUtil rcsUtil;

    @Autowired
    IBaseBarcodesInService iBaseBarcodesInService;

    @Autowired
    IBusinDataTaskService iBusinDataTaskService;

    @Autowired
    IWcsPlcConnectService iWcsPlcConnectService;

    @Autowired
    IWcsPlcPropertyService iWcsPlcPropertyService;

    @Autowired
    PLCReadAndWrite plcReadAndWrite;

    @Autowired
    ISysParameterService isysParameterService;

    @Autowired
    IBaseGoodsDataService iBaseGoodsDataService;

    @Autowired
    PlcInit plcInit;

    /**
     * AGV同输送线握手时，读取输送线的状态
     *
     * @param bo AGV携带信息
     * @return
     */
    public Result<DpsStatesBo> getDpsStatus(AGVTaskBo bo){

        Result<BaseConsignor> result = iBaseGoodsDataService.getErpConsignorId();
        if (!Result.isOk(result)){
            log.error(result.getMsg());
        }
        //获取仓库ID
        BaseConsignor baseConsignor = result.getData();
        Long branchId = baseConsignor.getBranchId();

        Long taskId = bo.getTaskId();
        //根据任务编号找到PLC信息
        BusinDataTask businDataTask = iBusinDataTaskService.getById(taskId);
        Long plcId = businDataTask.getPlcId();
        WcsPlcConnect conn = iWcsPlcConnectService.selectWcsPlcConnectById(plcId);
        String address="" ;
        String valueType="";

        List<WcsPlcProperty> propertyList = iWcsPlcPropertyService.getWcsPlcPropertyByPlcId(plcId);
        for (WcsPlcProperty wcsPlcProperty : propertyList) {
            //点位类型=1，是否允许放料
            if (wcsPlcProperty.getPointType().equals("1")){
                address=wcsPlcProperty.getAddress();
                valueType=wcsPlcProperty.getValueType();
            }
        }

        Map readMap = new HashMap(1);
        readMap.put(address,valueType);
        String readPoint = JSON.toJSONString(readMap);
        PlcOperate plcOperate = plcInit.getPlcOperateByIp(conn.getPlcIp());
        Map<String, Object> pointMap = plcReadAndWrite.readPlcData(plcOperate, readPoint);
        return Result.ok().data(pointMap.get(address));

    }




    public Result<DpsStatesBo> getDpsStatusTemp(){

        Result<BaseConsignor> result = iBaseGoodsDataService.getErpConsignorId();
        if (!Result.isOk(result)){
            log.error(result.getMsg());
        }
        //获取仓库ID
        BaseConsignor baseConsignor = result.getData();
        Long branchId = baseConsignor.getBranchId();

        Long plcId = Long.valueOf(isysParameterService.selectConfigByKey(ParameterConstants.ParameterSystem.plc_id));

        WcsPlcConnect conn = iWcsPlcConnectService.selectWcsPlcConnectById(plcId);
        String address="" ;
        String valueType="";

        List<WcsPlcProperty> propertyList = iWcsPlcPropertyService.getWcsPlcPropertyByPlcId(plcId);
        for (WcsPlcProperty wcsPlcProperty : propertyList) {
            //点位类型=1，是否允许放料
            if (wcsPlcProperty.getPointType().equals("1")){
                address=wcsPlcProperty.getAddress();
                valueType=wcsPlcProperty.getValueType();
            }
        }

        Map readMap = new HashMap(1);
        readMap.put(address,valueType);
        String readPoint = JSON.toJSONString(readMap);

        PlcHelper plcHelper = new PlcHelper(conn.getPlcType(),conn.getPlcIp(),conn.getPlcFactory(),conn.getPort());
        PlcOperate plcOperate = plcHelper.getAutomation();
        Map<String, Object> pointMap = plcReadAndWrite.readPlcData(plcOperate, readPoint);
        return Result.ok().data(pointMap.get(address));

    }

    /**
     * 输送线到达接驳点回调
     *
     * @param dto 出库信息
     * @return
     */
    public ResultCallback dpsContainerArrived(BullBarsArrivalDto dto) {
        List<RcsIdList> targets = new ArrayList<>();

        //输送线立库接驳口，呼叫AGV搬运
        if ("1".equals(dto.getDockingPoint())) {
            //点位列表
            RcsIdList start = new RcsIdList();
            start.setId("");
            targets.add(start);
            RcsIdList end = new RcsIdList();

            RcsCreateTaskDto rcsDto = new RcsCreateTaskDto();

            //根据任何编号及条码信息，给AGV下发命令
            String qrCode = dto.getQrCode();
            if (null == qrCode) {
                //未识别到条码信息，AGV搬运到条码异常区
                //获取异常区设定的接驳点，
                end.setId("1");
                targets.add(end);
                rcsDto.setMapId(1);
                //rcsDto.setTaskId("异常不生成任务");
                rcsDto.setTaskType(23);
                rcsDto.setTargets(targets);
                Result result = rcsUtil.rcsCreateTask(rcsDto);
                if (!Result.isOk(result)) {

                }

            } else {
                //获取条码信息
                BaseBarcodesIn baseBarcodesIn = iBaseBarcodesInService.getBaseBarcodesByQrCode(qrCode);
                //获取任务信息
                BusinDataTask businDataTask = iBusinDataTaskService.getBusinDataTaskByQrCode(qrCode);
                //根据条码信息，是否冲孔，是否维修，是否已冲孔 给AGV下命令
                String isPunching = baseBarcodesIn.getIsPunching(); //是否冲孔
                String isRepair = baseBarcodesIn.getIsRepair(); //是否维修
                String punchingResult = baseBarcodesIn.getPunchingResult(); //是否已冲孔
                //需要冲孔，但是未冲孔的并且不是维修的保险杠，搬运到冲孔机
                if ("1".equals(isPunching) && "0".equals(punchingResult) && "1".equals(isRepair)) {
                    //获取入库下料点位置 TODO
                    //获取冲孔机位置,需判断冲孔机是否启动，是否自动，是否大于等待数量 TODO
                    end.setId("");
                    targets.add(end);

                    rcsDto.setMapId(1);
                    //rcsDto.setTaskId(businDataTask.getTaskCode());
                    rcsDto.setTaskType(23);
                    rcsDto.setTargets(targets);
                    Result result = rcsUtil.rcsCreateTask(rcsDto);
                    if (!Result.isOk(result)) {
                        //return  result;
                    }
                }
                //需要维修，搬运到维修区
                else if ("1".equals(isRepair)) {
                    //获取维修区设定的接驳点，
                    end.setId("1");
                    targets.add(end);
                    rcsDto.setMapId(1);
                    rcsDto.setTaskId(businDataTask.getId().toString());
                    rcsDto.setTaskType(23);
                    rcsDto.setTargets(targets);
                    Result result = rcsUtil.rcsCreateTask(rcsDto);
                    if (!Result.isOk(result)) {
                        //return  result;
                    }
                }
                //正常入库
                else {
                    //根据条码确定物料信息，查看立库种库存分布，分配货位

                    //根据货位匹配对应的巷道信息，获取巷道对应的输送线是否正常


                }
            }
        }
        //立库接驳口，1入立库，则呼叫堆垛机
        else if ("2".equals(dto.getDockingPoint()) && "1".equals(dto.getDpsDirection())) {
            //根据输送线与堆垛机的关系，确定堆垛机并下发命令
        }
        //立库接驳口，根据输送线的方向，-1出立库，则呼叫AGV搬运
        else if ("2".equals(dto.getDockingPoint()) && "-1".equals(dto.getDpsDirection())) {
            //根据任务类型，呼叫AGV
            RcsIdList start = new RcsIdList();
            start.setId("");
            targets.add(start);
            RcsIdList end = new RcsIdList();

        }
        return null;

    }




}
