package com.sw.mes.yb.agv.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.core.utils.BeanUtil;
import com.sw.mes.enumvalue.EnumValuesAgv;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.sw.mes.core.utils.StringUtils;
import com.sw.mes.utils.AGVHttpUtil;
import com.sw.mes.yb.agv.constant.AgvErrorType;
import com.sw.mes.yb.agv.dto.AgvCallDto;
import com.sw.mes.yb.agv.dto.AgvCancelDto;
import com.sw.mes.yb.agv.dto.AgvLockDto;
import com.sw.mes.yb.agv.dto.AgvReturnResult;
import com.sw.mes.yb.agv.entity.AgvDispatchDeploy;
import com.sw.mes.yb.agv.entity.AgvDispatchDeployRecord;
import com.sw.mes.yb.agv.exceptions.AgvCallException;
import com.sw.mes.yb.agv.service.AgvDispatchDeployRecordService;
import com.sw.mes.yb.agv.service.AgvDispatchDeployService;
import com.sw.mes.yb.agv.service.AgvDispatchService;

/**
 * @Author @Description：
 * @Date: Create in
 * @Modified By:
 */
@Service
@Transactional
public class AgvDispatchServiceImpl implements AgvDispatchService {

	@Autowired
	private AgvDispatchDeployService agvDispatchDeployService;
	@Autowired
	private AgvDispatchDeployRecordService agvDispatchDeployRecordService;

	@Autowired
	private DictionaryItemService dictionaryItemService;

	@Override
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public String callAgv(AgvCallDto agvCall) throws AgvCallException {
		if(agvCall==null)
			throw new AgvCallException(AgvErrorType.INVALID_PARAMS);

		//配置信息
		AgvDispatchDeploy deploy = agvDispatchDeployService.getByKeyword(agvCall.getKeyword());
		if(deploy==null)
			throw new AgvCallException(AgvErrorType.NOT_CONFIG);
		if ( EnumValuesAgv.AGVKeyword.圆棒送验.getValue().equals(agvCall.getKeyword()) ){
			List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndItemName("callAgvUrl", "url", true);
			if (dictionaryItems.size()>0){
				deploy.setUrl(dictionaryItems.get(0).getValue());
			}
		}else {
			if(StringUtils.isBlank(deploy.getUrl()))
				throw new AgvCallException(3003,"未配置AGV通信URL");
		}

		//初始化配置中参数 导入到 参数信息中
		initAgvCall(deploy,agvCall);

		int doubleCount = 1;
		try {
			if(deploy.getAgainTime()!=null) {
				doubleCount = Integer.valueOf(deploy.getAgainTime());
			}
		}catch (Exception e) {
			throw new AgvCallException(3003,"重发次数数据类型错误");
		}

		int timeout = 1000;
		try {
			if(deploy.getTimeout()!=null) {
				timeout = Integer.valueOf(deploy.getTimeout());
			}
		}catch (Exception e) {
			throw new AgvCallException(3003,"超时时间数据类型错误");
		}

		agvCall.setReqCode(UUID.randomUUID().toString());

		String param = JSON.toJSONString(agvCall);
		//发送AGV任务
		for (int i = 0; i < doubleCount; i++) {
			Date callTime = new Date();
			AgvReturnResult result = AGVHttpUtil.post(deploy.getUrl(), param,timeout);
			if(result.getCode().equals(200)) {
				AgvDispatchDeployRecord record = new AgvDispatchDeployRecord();
				BeanUtil.copyProperties(record, agvCall);
				record.setAutoResend(i+1);
				record.setInterfaceData(param);
				record.setResults(JSON.toJSONString(result));
				record.setCallTime(callTime);
				Date currentDate = new Date();
				long useTime = currentDate.getTime() - callTime.getTime();
				record.setUseTime((int) useTime);
				record.setDispatchDeployId(deploy.getId());
				record.setIsSuccess(1);
				agvDispatchDeployRecordService.saveOrUpdate(record);
				break;
			}else {
				AgvDispatchDeployRecord record = new AgvDispatchDeployRecord();
				BeanUtil.copyProperties(record, agvCall);
				record.setAutoResend(i+1);
				record.setInterfaceData(param);
				record.setResults(JSON.toJSONString(result));
				record.setCallTime(callTime);
				Date currentDate = new Date();
				long useTime = currentDate.getTime() - callTime.getTime();
				record.setUseTime((int) useTime);
				record.setDispatchDeployId(deploy.getId());
				record.setIsSuccess(0);
				agvDispatchDeployRecordService.saveOrUpdate(record);

				//请求失败
				if(i==(doubleCount-1)) {
					throw new AgvCallException(3009,result.getMessage());
				}
			}
		}

		return agvCall.getTaskCode();
	}


	@Override
	public String cancelAgv(AgvCancelDto agvCancel) throws AgvCallException {
		if(agvCancel==null)
			throw new AgvCallException(AgvErrorType.INVALID_PARAMS);

		//配置信息
		AgvDispatchDeploy deploy = agvDispatchDeployService.getByKeyword(agvCancel.getKeyword());
		if(deploy==null)
			throw new AgvCallException(AgvErrorType.NOT_CONFIG);
		else if(StringUtils.isBlank(deploy.getUrl()))
			throw new AgvCallException(3003,"未配置AGV通信URL");


		//初始化配置中参数 导入到 参数信息中
		initAgvCancel(deploy,agvCancel);


		int doubleCount = 1;
		try {
			if(deploy.getAgainTime()!=null) {
				doubleCount = Integer.valueOf(deploy.getAgainTime());
			}
		}catch (Exception e) {
			throw new AgvCallException(3003,"重发次数数据类型错误");
		}

		int timeout = 1000;
		try {
			if(deploy.getTimeout()!=null) {
				timeout = Integer.valueOf(deploy.getTimeout());
			}
		}catch (Exception e) {
			throw new AgvCallException(3003,"超时时间数据类型错误");
		}

		//发送AGV任务

		agvCancel.setReqCode(UUID.randomUUID().toString());

		String param = JSON.toJSONString(agvCancel);

		for (int i = 0; i < doubleCount; i++) {
			Date callTime = new Date();
			AgvReturnResult result = AGVHttpUtil.post(deploy.getUrl(), param,timeout);
			if(result.getCode().equals(200)) {
				AgvDispatchDeployRecord record = new AgvDispatchDeployRecord();
				BeanUtil.copyProperties(record, agvCancel);
				record.setAutoResend(i+1);
				record.setInterfaceData(param);
				record.setResults(JSON.toJSONString(result));
				record.setCallTime(callTime);
				Date currentDate = new Date();
				long useTime = currentDate.getTime() - callTime.getTime();
				record.setUseTime((int) useTime);
				record.setDispatchDeployId(deploy.getId());
				record.setIsSuccess(1);
				agvDispatchDeployRecordService.saveOrUpdate(record);
				break;
			}else {
				AgvDispatchDeployRecord record = new AgvDispatchDeployRecord();
				BeanUtil.copyProperties(record, agvCancel);
				record.setAutoResend(i+1);
				record.setInterfaceData(param);
				record.setResults(JSON.toJSONString(result));
				record.setCallTime(callTime);
				Date currentDate = new Date();
				long useTime = currentDate.getTime() - callTime.getTime();
				record.setUseTime((int) useTime);
				record.setDispatchDeployId(deploy.getId());
				record.setIsSuccess(0);
				agvDispatchDeployRecordService.saveOrUpdate(record);

				//请求失败
				if(i==(doubleCount-1)) {
					throw new AgvCallException(3009,result.getMessage());
				}
			}
		}


		return agvCancel.getTaskCode();
	}



	@Override
	public String storeLock(AgvLockDto agvLock) throws AgvCallException {
		if(agvLock==null)
			throw new AgvCallException(AgvErrorType.INVALID_PARAMS);

		//配置信息
		AgvDispatchDeploy deploy = agvDispatchDeployService.getByKeyword(agvLock.getKeyword());

		if(deploy==null)
			throw new AgvCallException(AgvErrorType.NOT_CONFIG);
		else if(StringUtils.isBlank(deploy.getUrl()))
			throw new AgvCallException(3003,"未配置AGV通信URL");

		//初始化配置中参数 导入到 参数信息中
		initAgvCall(deploy,agvLock);

		int doubleCount = 1;
		try {
			if(deploy.getAgainTime()!=null) {
				doubleCount = Integer.valueOf(deploy.getAgainTime());
			}
		}catch (Exception e) {
			throw new AgvCallException(3003,"重发次数数据类型错误");
		}

		int timeout = 1000;
		try {
			if(deploy.getTimeout()!=null) {
				timeout = Integer.valueOf(deploy.getTimeout());
			}
		}catch (Exception e) {
			throw new AgvCallException(3003,"超时时间数据类型错误");
		}


		String param = JSON.toJSONString(agvLock);
		//发送AGV任务
		for (int i = 0; i < doubleCount; i++) {
			Date callTime = new Date();
			AgvReturnResult result = AGVHttpUtil.post(deploy.getUrl(), param,timeout);
			if(result.getCode().equals(200)) {
				AgvDispatchDeployRecord record = new AgvDispatchDeployRecord();
				BeanUtil.copyProperties(record, agvLock);
				record.setAutoResend(i+1);
				record.setInterfaceData(param);
				record.setResults(JSON.toJSONString(record));
				record.setCallTime(callTime);
				Date currentDate = new Date();
				long useTime = currentDate.getTime() - callTime.getTime();
				record.setUseTime((int) useTime);
				record.setDispatchDeployId(deploy.getId());
				record.setIsSuccess(1);
				agvDispatchDeployRecordService.saveOrUpdate(record);
				break;
			}else {
				AgvDispatchDeployRecord record = new AgvDispatchDeployRecord();
				BeanUtil.copyProperties(record, agvLock);
				record.setAutoResend(i+1);
				record.setInterfaceData(param);
				record.setResults(JSON.toJSONString(result));
				record.setCallTime(callTime);
				Date currentDate = new Date();
				long useTime = currentDate.getTime() - callTime.getTime();
				record.setUseTime((int) useTime);
				record.setDispatchDeployId(deploy.getId());
				record.setIsSuccess(0);
				agvDispatchDeployRecordService.saveOrUpdate(record);

				//请求失败
				if(i==(doubleCount-1)) {
					throw new AgvCallException(3009,result.getMessage());
				}
			}
		}

		return agvLock.getTaskCode();
	}





	private void initAgvCall(AgvDispatchDeploy deploy, AgvLockDto agvLock) {
		if(deploy.getOtherTaskId()!=null || deploy.getOtherTaskId().equals("日期时间随机数")) {
			agvLock.setTaskCode(getTaskIdByRondom());
		}else if(deploy.getOtherTaskId().equals("UUID")) {
			agvLock.setTaskCode(getUUID());
		}

		if(agvLock.getLocked()==null) {
			if(!StringUtils.isBlank(deploy.getLocked())) {
				Integer locked = null;
				if(deploy.getLocked().equals("1")) {
					locked = 1;
				}else if(deploy.getLocked().equals("0")) {
					locked = 0;
				}else if(deploy.getLocked().equals("true") || deploy.getLocked().equals("True")) {
					locked = 1;
				}else if(deploy.getLocked().equals("false") || deploy.getLocked().equals("False")) {
					locked = 0;
				}
				if(locked!=null)
					agvLock.setLocked(locked);
			}
		}

		if(StringUtils.isBlank(agvLock.getPosCode())  && StringUtils.isNotBlank(deploy.getPosCode())) {
			agvLock.setReqCode(deploy.getPosCode());
		}
	}


	private void initAgvCancel(AgvDispatchDeploy deploy, AgvCancelDto agvCancel) {
		if(deploy.getOtherTaskId()!=null || deploy.getOtherTaskId().equals("日期时间随机数")) {
			agvCancel.setTaskCode(getTaskIdByRondom());
		}else if(deploy.getOtherTaskId().equals("UUID")) {
			agvCancel.setTaskCode(getUUID());
		}

		if(StringUtils.isBlank(agvCancel.getReqCode()) && StringUtils.isNotBlank(deploy.getReqCode())) {
			agvCancel.setReqCode(deploy.getReqCode());
		}
	}


	private void initAgvCall(AgvDispatchDeploy deploy, AgvCallDto agvCall) {
		if(deploy.getOtherTaskId()!=null || deploy.getOtherTaskId().equals("日期时间随机数")) {
			agvCall.setTaskCode(getTaskIdByRondom());
		}else if(deploy.getOtherTaskId().equals("UUID")) {
			agvCall.setTaskCode(getUUID());
		}

		if(StringUtils.isBlank(agvCall.getPriority()) && StringUtils.isNotBlank(deploy.getPriority())) {
			agvCall.setPriority(deploy.getPriority());
		}

//		if(StringUtils.isBlank(agvCall.getStartCode()) && StringUtils.isBlank(agvCall.getStartPoint()) && StringUtils.isBlank(deploy.getStartCode()) && StringUtils.isBlank(deploy.getStartPoint())) {
//			throw new AgvCallException(3001,"未传入或配置起始位置编号(或开始工作位)");
//		}

		if(StringUtils.isNotBlank(agvCall.getStartCode())) {
			agvCall.setStartPoint(agvCall.getStartCode());
		}
//		if(StringUtils.isBlank(agvCall.getStartPoint()) && StringUtils.isNotBlank(deploy.getStartPoint())) {
//			agvCall.setStartPoint(deploy.getStartCode());
//		}

//		if(StringUtils.isBlank(agvCall.getEndCode()) && StringUtils.isBlank(agvCall.getTargetPoint()) && StringUtils.isBlank(deploy.getEndCode()) && StringUtils.isBlank(deploy.getTargetPoint())) {
//			throw new AgvCallException(3001,"未传入或配置结束位置编号(或结束工作位)");
//		}
		if(StringUtils.isBlank(agvCall.getEndCode()) && StringUtils.isNotBlank(deploy.getEndCode())) {
			agvCall.setEndCode(deploy.getEndCode());
		}
		if(StringUtils.isBlank(agvCall.getTargetPoint()) && StringUtils.isNotBlank(deploy.getTargetPoint())) {
			agvCall.setTargetPoint(deploy.getTargetPoint());
		}

		if(StringUtils.isBlank(agvCall.getAgvTaskType()) && StringUtils.isNotBlank(deploy.getAgvTaskType())) {
			agvCall.setAgvTaskType(deploy.getAgvTaskType());
		}

		if(StringUtils.isBlank(agvCall.getFrockCode()) && StringUtils.isNotBlank(deploy.getFrockCode())) {
			agvCall.setFrockCode(deploy.getFrockCode());
		}

		if(StringUtils.isBlank(agvCall.getFrockType()) && StringUtils.isNotBlank(deploy.getFrockType())) {
			agvCall.setFrockType(deploy.getFrockType());
		}


//		if(StringUtils.isBlank(deploy.getCrystalNo()) && deploy.getCrystalNo().equals("必填") && StringUtils.isBlank(agvCall.getCrystalNo())) {
//			throw new AgvCallException(3001,"单晶编号要求必填");
//		}
//
//		if(StringUtils.isBlank(deploy.getRecipeId()) && deploy.getRecipeId().equals("必填") && StringUtils.isBlank(agvCall.getRecipeId())) {
//			throw new AgvCallException(3001,"配方ID要求必填");
//		}
//
//		if(StringUtils.isBlank(deploy.getWeightId()) && deploy.getWeightId().equals("必填") && StringUtils.isBlank(agvCall.getWeightId())) {
//			throw new AgvCallException(3001,"配方ID要求必填");
//		}


		if(StringUtils.isBlank(agvCall.getCallbackMsg()) && validateUrl(deploy.getCallbackMsg())) {
			agvCall.setCallbackMsg(deploy.getCallbackMsg());
		}

	}



	private boolean validateUrl(String callbackMsg) {
		//1. 校验是否存在回调地址

		//2. 校验URL是否有效
		//懒得做的，自己人配置的 。。。。放弃   ^_^
		return true;
	}

	private String getTaskIdByRondom() {
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmssSSS");
	    StringBuffer sb = new StringBuffer();

	    int random = (int)((Math.random()*9+1)*10000);

	    sb.append(df.format(new Date()));
	    sb.append(random);

	    return sb.toString();
	}

	private String getUUID() {
		return UUID.randomUUID().toString().replace("-", "").toLowerCase();
	}

}
