package com.prolog.cs.biz.inbound.service.impl;

import com.prolog.cs.biz.inbound.constant.BizConstant;
import com.prolog.cs.biz.inbound.dao.rcv.RcvLinesMapper;
import com.prolog.cs.biz.inbound.dao.task.TaskQcDetailMapper;
import com.prolog.cs.biz.inbound.dto.CargoChangeIn;
import com.prolog.cs.biz.inbound.dto.rcv.RcvHeadersDTO;
import com.prolog.cs.biz.inbound.dto.rcv.RcvLinesDTO;
import com.prolog.cs.biz.inbound.dto.rqc.RqcDTO;
import com.prolog.cs.biz.inbound.dto.rqc.RqcHeadersDTO;
import com.prolog.cs.biz.inbound.dto.rqc.RqcLinesDTO;
import com.prolog.cs.biz.inbound.dto.task.TaskQcDetailDTO;
import com.prolog.cs.biz.inbound.remote.ControlRemoteCaller;
import com.prolog.cs.biz.inbound.service.impl.processor.Helper.TaskHelper;
import com.prolog.cs.biz.inbound.service.rqc.RqcHeadersService;
import com.prolog.cs.biz.inbound.service.rqc.WmsInRqcSampleService;
import com.prolog.cs.biz.inbound.utils.ObjectUtils;
import com.prolog.framework.authority.core.dto.UserDTO;
import com.prolog.framework.beans.BeanUtils;
import com.prolog.framework.bz.common.search.SearchApi;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Slf4j
@Lazy
@Service
public class AutoRqcHandler {

	@Lazy
	@Resource
	private RqcHeadersService rqcHeadersService;

	@Resource
	private RcvLinesMapper rcvLinesMapper;

	@Resource
	private TaskQcDetailMapper taskQcDetailMapper;

	@Resource
	private AutoStockHandler autoStockHandler;

	@Resource
	private ControlRemoteCaller controlRemoteCaller;

	@Value("${prolog.wms.enableAutoGenSupervise:false}")
	private boolean enableAutoGenSupervise;

	@Value("${prolog.wms.enableAutoGenSample:true}")
	private boolean enableAutoGenSample;

	@Value("${prolog.wms.enableAutoGenLocatorByInventory:false}")
	private boolean enableAutoGenLocatorByInventory;

	@Value("${prolog.wms.enableAutoFixedAreaCategoryCode:false}")
	private boolean enableAutoFixedAreaCategoryCode;

	@Resource
	private WmsInRqcSampleService sampleService;

	@Resource
	private SearchApi searchApi;

	@Resource
	private TaskHelper taskHelper;

	// 自动质检&上架
	public void autoRqc(List<RcvLinesDTO> rcvLinesDTOList, RcvHeadersDTO rcvDTO,
						UserDTO userDTO, boolean autoAdd, CargoChangeIn cargoChangeIn) {

		// 获取自动时间的间隔
		String autoTimeInterval = taskHelper.getBusinessControlValue(rcvDTO.getWarehouseId(), rcvDTO.getMtlOwnerId(),
				"15-30", BizConstant.AUTO_BILL_INTERVAL_TIME);
		if (StringUtils.isBlank(autoTimeInterval)) {
			autoTimeInterval = "15-30";
		}
		String[] split = autoTimeInterval.split("-");
		Integer downLimit = 15;
		Integer upLimit = 30;
		try {
			downLimit = Integer.parseInt(split[0]);
			upLimit = Integer.parseInt(split[1]);
		} catch (NumberFormatException e1) {
			e1.printStackTrace();
		}

		RqcDTO rqcDTO = new RqcDTO();
		Date rcvDate = rcvDTO.getRcvDate();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(rcvDate);
		int nextInt = new Random().nextInt(downLimit);
		calendar.add(Calendar.MINUTE, nextInt + upLimit - downLimit);
		Date time = calendar.getTime();
		RqcHeadersDTO RqcHeadersDTO = new RqcHeadersDTO();
		BeanUtils.copyProperties(rcvDTO, RqcHeadersDTO);
		rqcDTO.setAutoTime(time);// 15到30分钟内任意取值,待取数据字典
		rqcDTO.setRqcHeadersDTO(RqcHeadersDTO);
		rqcDTO.setAutoTimeInterval(autoTimeInterval);
		RqcHeadersDTO.setRemark("auto");
		RqcHeadersDTO.setBillDate(calendar.getTime());
		RqcHeadersDTO.setIsInstockPrint(0); // 不打印
		RqcHeadersDTO.setDataSrcType("auto");
		RqcHeadersDTO.setAutoTimeInterval(autoTimeInterval);

		String qcOperator1 = userDTO.getUsername();
		String enterpriseId = userDTO.getEnterpriseId();
		String warehouseId = rcvDTO.getWarehouseId();
		String qcOperator2 = null;
		List<Map> searchForMap = null;
		try {
			Map<String, Object> queryMap = new HashMap<>();
			queryMap.put("enterpriseId", enterpriseId);
			queryMap.put("warehouseId", warehouseId);
			queryMap.put("bussinessType", "1010");
			searchForMap = searchApi.searchForMap("selectWorker", queryMap);
		} catch (Exception e) {
			log.info("随机获取质检操作员接口异常", e);
		}

		TaskQcDetailDTO queryVo = new TaskQcDetailDTO();
		String rcvHeaderId = rcvDTO.getRcvHeaderId();
		queryVo.setRcvHeaderId(rcvHeaderId);
		List<TaskQcDetailDTO> list = taskQcDetailMapper.findListWithNoExcuter(queryVo);
		String rcvType = rcvDTO.getRcvType();
		List<RqcLinesDTO> lineList = new ArrayList<>();
		List<RqcLinesDTO> isSuperviseList = new ArrayList<>();
		Set<String> areaCategoryCodeSet = new HashSet<>();
		for (int i = 0; i < list.size(); i++) {
//			TaskQcDetail p=new TaskQcDetail();
			TaskQcDetailDTO p = list.get(i);
			RqcLinesDTO target = new RqcLinesDTO();
			BeanUtils.copyProperties(p, target);
			target.setRcvType(rcvType);

			String rqcReportNo = target.getRqcReportNo();
			if (StringUtils.isBlank(rqcReportNo)) {
				// 自动生成质检单号
//				long id = SnowFlakeUtils.getId();
//				target.setRqcReportNo("auto" + String.valueOf(id));
			}
			target.setStockStatus("0");
			String categoryId = target.getCategoryId();
			if (!ObjectUtils.isNull(searchForMap)) {
				String qcOpcode = getQcOpcode(searchForMap, categoryId);
				if (!StringUtils.isBlank(qcOpcode)) {
					qcOperator1 = qcOpcode;
				}
			}
			target.setQcResult1("0");
			target.setQcDate1(calendar.getTime());

			target.setQcOpcode1(qcOperator1);
			Integer itemHealthIsDouble = p.getItemHealthIsDouble();
			if (itemHealthIsDouble != null && 1 == itemHealthIsDouble) {
				// 双人质检,选择下一人
				qcOperator2 = getOtherOp(qcOperator1, searchForMap);
				if (StringUtils.isBlank(qcOperator2)) {
					qcOperator2 = qcOperator1;
				}
				target.setQcOpcode2(qcOperator2);
				target.setQcResult2("0");
				Calendar calendar2 = Calendar.getInstance();
				calendar2.add(Calendar.MINUTE, new Random().nextInt(15) + 15);
				target.setQcDate2(calendar2.getTime());
			}
			String categoryName = p.getCategoryName();
			if (!StringUtils.isBlank(categoryName)) {
				if (categoryName.contains("冷藏")) {
					target.setRqcTemperature("2");
				}
				if (categoryName.contains("冷冻")) {
					target.setRqcTemperature("-1");
				}
			} else {
				p.setCategoryName("常温");
				target.setCategoryName("常温");
			}

			target.setRemarks("autoGen");

			// 执行单据额外处理
			excuteHandleRcvType(target, rcvType, userDTO, p, areaCategoryCodeSet);

			// 是否执行扫描监管码逻辑
			Integer isSupervise = p.getIsSupervise();
			if (null != isSupervise && 1 == isSupervise) {
				isSuperviseList.add(target);
			}

			lineList.add(target);

		}
		// 是否自动生成扫描监管码记录,可配置,暂时用配置文件代替
		excuteGenSupervise(isSuperviseList, rcvType, userDTO);
		// 自动生成抽检记录
		excuteGenSample(lineList, rcvType, cargoChangeIn, userDTO);

		rqcDTO.setRqcLinesDTOList(lineList);
		rqcDTO.getRqcHeadersDTO().setQcOperator1(qcOperator1);
		rqcDTO.getRqcHeadersDTO().setQcOperator2(qcOperator2);
		if (autoAdd) {
			rqcHeadersService.addWithRelatedAuto(rqcDTO);
		} else {
			rqcHeadersService.addWithRelated(rqcDTO);
		}

		RqcHeadersDTO rqcHeadersDTO = new RqcHeadersDTO();
		BeanUtils.copyProperties(rcvDTO, rqcHeadersDTO);

		if (enableAutoFixedAreaCategoryCode) {
			if (rcvType.equals(BizConstant.BLANK_IN) || rcvType.equals(BizConstant.BLANK_RETURN_IN)
					|| rcvType.equals(BizConstant.BLANK_ENTITY_IN) || rcvType.equals(BizConstant.BLANK_RETURN_ENTITY_IN)
					|| rcvType.equals(BizConstant.ACCOUNT_REG_IN)) {
				areaCategoryCodeSet.add(BizConstant.KRK);
				autoStockHandler.autoStock(rqcHeadersDTO, lineList, userDTO, areaCategoryCodeSet, rqcHeadersDTO.getBillDate());
			}
		} else {
			if (rcvType.equals(BizConstant.BLANK_IN) || rcvType.equals(BizConstant.BLANK_RETURN_IN)
					|| rcvType.equals(BizConstant.BLANK_ENTITY_IN) || rcvType.equals(BizConstant.BLANK_RETURN_ENTITY_IN)
					|| rcvType.equals(BizConstant.ACCOUNT_REG_IN)) {
				autoStockHandler.autoStock(rqcHeadersDTO, lineList, userDTO, areaCategoryCodeSet, rqcHeadersDTO.getBillDate());
			}
		}
		boolean autoGen = rcvDTO.getAutoGen();
		if (autoGen) {
			// 货主转换
			autoStockHandler.autoStock(rqcHeadersDTO, lineList, userDTO, areaCategoryCodeSet, rqcHeadersDTO.getBillDate());
		}

	}
//	//自动质检&上架
//	public void autoRqc(List<RcvLinesDTO> rcvLinesDTOList, RcvHeadersDTO rcvDTO, UserDTO userDTO){
//		RqcDTO rqcDTO=new RqcDTO();
//		Calendar calendar = Calendar.getInstance();
//		calendar.add(Calendar.MINUTE, new Random().nextInt(15) + 15);
//		RqcHeadersDTO RqcHeadersDTO=new RqcHeadersDTO();
//		BeanUtils.copyProperties(rcvDTO, RqcHeadersDTO);
//		rqcDTO.setAutoTime(calendar.getTime());//15到30分钟内任意取值,待取数据字典
//		rqcDTO.setRqcHeadersDTO(RqcHeadersDTO);
//		String qcOperator1=userDTO.getUsername();
//		String enterpriseId = userDTO.getEnterpriseId();
//		String warehouseId = rcvDTO.getWarehouseId();
//		
//		List<Map> searchForMap = null;
//		try {
//			Map<String, Object> queryMap = new HashMap<>();
//			queryMap.put("enterpriseId", enterpriseId);
//			queryMap.put("warehouseId", warehouseId);
//			queryMap.put("bussinessType", "1010");
//			searchForMap = searchApi.searchForMap("selectWorker", queryMap);
//			
//			// 此接口有问题
////			RestMessage<UserDTO> rest = controlRemoteCaller.getRandomUserDTOByWorkGroup("1010",
////						rcvDTO.getWarehouseId(),userDTO.getEnterpriseId());
////			if (rest != null && rest.isSuccess() && rest.getData()!=null && StringUtils.isNotBlank(rest.getData().getUsername())) {
////				qcOperator1=rest.getData().getUsername();
////			}
//		} catch (Exception e) {
//			log.error("随机获取质检操作员接口异常",e);
//		}
//		
//		TaskQcDetailDTO queryVo = new TaskQcDetailDTO();
//		String rcvHeaderId = rcvDTO.getRcvHeaderId();
//		queryVo.setRcvHeaderId(rcvHeaderId);
//		List<TaskQcDetailDTO> findListWithNoExcuter = taskQcDetailMapper.findListWithNoExcuter(queryVo);
//		
//		List<TaskQcDetail> list = taskQcDetailMapper.findByMap(MapUtils.put("rcvHeaderId",rcvDTO.getRcvHeaderId()).getMap(),TaskQcDetail.class);
//		List<RcvLines> rcvLines = rcvLinesMapper.findByMap(MapUtils.put("rcvHeaderId",rcvDTO.getRcvHeaderId()).getMap(),RcvLines.class);
//		List<RqcLinesDTO> lineList=new ArrayList<>();
//		for (int i = 0; i < list.size(); i++) {
////			TaskQcDetail p=new TaskQcDetail();
//			TaskQcDetail p= list.get(i);
//			
//			RqcLinesDTO target = new RqcLinesDTO();
//			BeanUtils.copyProperties(p, target);
//			target.setRcvType(rcvDTO.getRcvType());
//			if(p.getQty().compareTo(BigDecimal.ONE)<0){
//				target.setOddPieceQty(p.getPieceQty());
//				target.setOddCaseQty(BigDecimal.ZERO);
//			}else{
//				target.setOddPieceQty(BigDecimal.ZERO);
//				target.setOddCaseQty(p.getQty());
//			}
//			RcvLines itemBaseInfoVO = rcvLines.stream().filter(item -> item.getRcvLineId().equals(p.getRcvLineId())).findFirst().orElse(null);
//			if (itemBaseInfoVO != null) {
//				target.setBatchExpiredDate(itemBaseInfoVO.getBatchExpiredDate());
//				target.setBatchProductionDate(itemBaseInfoVO.getBatchProductionDate());
//			}
//			target.setStockStatus("0");
//			target.setQcOpcode1(qcOperator1);
//			lineList.add(target);
//		}
//		rqcDTO.setRqcLinesDTOList(lineList);
//		rqcDTO.getRqcHeadersDTO().setQcOperator1(qcOperator1);
//		rqcHeadersService.addWithRelated(rqcDTO);
//		RqcHeadersDTO rqcHeadersDTO=new RqcHeadersDTO();
//		BeanUtils.copyProperties(rcvDTO, rqcHeadersDTO);
//		if(rcvDTO.getRcvType().equals(BizConstant.BLANK_IN) || rcvDTO.getRcvType().equals(BizConstant.BLANK_RETURN_IN)){
//			autoStockHandler.autoStock(rqcHeadersDTO,lineList,userDTO,"KRK");
//		}
//	}

	/**
	 * 自动生成抽检记录
	 * 
	 * @param lineList
	 * @param rcvType
	 * @param userDTO
	 */
	private void excuteGenSample(List<RqcLinesDTO> lineList, String rcvType, CargoChangeIn cargoChangeIn, UserDTO userDTO) {
		if (enableAutoGenSample) {
			sampleService.autoGen(lineList, rcvType, cargoChangeIn, userDTO);
		}

	}

	/**
	 * 自动生成监管码信息
	 * 
	 * @param isSuperviseList
	 * @param rcvType
	 * @param userDTO
	 */
	private void excuteGenSupervise(List<RqcLinesDTO> isSuperviseList, String rcvType, UserDTO userDTO) {
		if (enableAutoGenSupervise) {

		}

	}

	/**
	 * 执行额外特殊单据处理,比如是否选择特定库别及库区等等
	 * 
	 * @param target
	 * @param rcvType
	 * @param userDTO
	 * @param areaCategoryCodeSet
	 * @param p
	 */
	private void excuteHandleRcvType(RqcLinesDTO target, String rcvType, UserDTO userDTO, TaskQcDetailDTO p,
			Set<String> areaCategoryCodeSet) {
		if (!enableAutoGenLocatorByInventory) {
			if (rcvType.equals(BizConstant.BLANK_IN) || rcvType.equals(BizConstant.BLANK_RETURN_IN)
					|| rcvType.equals(BizConstant.BLANK_ENTITY_IN)
					|| rcvType.equals(BizConstant.BLANK_RETURN_ENTITY_IN)) {
				target.setWhAreaCategory("KRK");
			}
		}
		// 自动单据给出库别集合
		String itemIsPieceOrCase = p.getItemIsPieceOrCase();
		if (!StringUtils.isBlank(itemIsPieceOrCase) && "0".equals(itemIsPieceOrCase.trim())) {
			areaCategoryCodeSet.add(BizConstant.HYK);
			target.setWhAreaCategory(BizConstant.HYK);
		}
		if (!StringUtils.isBlank(itemIsPieceOrCase) && "1".equals(itemIsPieceOrCase.trim())) {
			boolean flag = isCase(target);
			if (flag) {
				areaCategoryCodeSet.add(BizConstant.ZJK);
				target.setWhAreaCategory(BizConstant.ZJK);
			}else {
				areaCategoryCodeSet.add(BizConstant.LHK);
				target.setWhAreaCategory(BizConstant.LHK);
			}
		}
	}

	private boolean isCase(RqcLinesDTO target) {
		BigDecimal pieceQty = target.getPieceQty();
		BigDecimal conversionRate = target.getConversionRate();
		BigDecimal oddCaseQty = pieceQty.divide(conversionRate, 0, RoundingMode.DOWN);
		BigDecimal oddPieceQty = pieceQty.subtract(oddCaseQty.multiply(conversionRate));
		// 判断数据的整散
		if (null != oddPieceQty && oddPieceQty.compareTo(BigDecimal.ZERO) == 0) {
			return true;
		}
		return false;
	}
	/**
	 * 获取其它验收员
	 * 
	 * @param qcOperator1
	 * @param searchForMap
	 * @return
	 */
	private String getOtherOp(String qcOperator1, List<Map> searchForMap) {
		String personName = null;
		if (ObjectUtils.isNull(searchForMap)) {
			return personName;
		}
		for (Map smap : searchForMap) {
			personName = (String) smap.get("personName");
			if (!StringUtils.isBlank(personName) && !personName.equals(qcOperator1)) {
				return personName;
			}
		}
		return personName;
	}

	/**
	 * 匹配合适验收员
	 * 
	 * @param searchForMap
	 * @param categoryId
	 * @return
	 */
	private String getQcOpcode(List<Map> searchForMap, String categoryId) {
		String personName = null;
		for (Map smap : searchForMap) {
			String itemCategoryCodes = (String) smap.get("itemCategoryCodes");
			if (!StringUtils.isBlank(itemCategoryCodes)) {
				String[] split = itemCategoryCodes.split(",");
				List<String> asList = Arrays.asList(split);
				if (asList.contains(categoryId)) {
					personName = (String) smap.get("personName");
					return personName;
				}
			}
		}
		return personName;
	}

}
