package com.yeejoin.equipmanage.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.component.feign.config.InnerInvokException;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.equipmanage.common.entity.*;
import com.yeejoin.equipmanage.common.enums.EquipStatusChecker;
import com.yeejoin.equipmanage.common.enums.EquipStatusEnum;
import com.yeejoin.equipmanage.common.enums.ScanTypeEnum;
import com.yeejoin.equipmanage.common.utils.ArrayUtil;
import com.yeejoin.equipmanage.common.utils.DateUtils;
import com.yeejoin.equipmanage.common.utils.ParsePropertyUtil;
import com.yeejoin.equipmanage.common.utils.StringUtil;
import com.yeejoin.equipmanage.common.vo.*;
import com.yeejoin.equipmanage.mapper.*;
import com.yeejoin.equipmanage.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 扫码装备知识
 *
 * @author as-wanglei
 *
 */
@Service("qREquipmentKnowledgeServiceImpl")
@Transactional
public class QREquipmentKnowledgeServiceImpl implements IQRCodeService<ScanResult<QREquipResponse>> {

	@Autowired
	private StockDetailMapper iStockDetailDao;
	@Autowired
	private EquipmentQrcodeMapper iEquipmentQRCodeDao;
	@Autowired
	private com.yeejoin.equipmanage.mapper.EquipmentMapper EquipmentMapper;
	@Autowired
	private RedisUtils redisUtils;
	@Autowired
	private EquipmentOnCarMapper iEquipmentOnCarDao;
	@Autowired
	private HttpServletRequest request;
	@Autowired
	private WarehouseMapper warehouseDao;
	@Autowired
	private StockMapper iStockDao;
	@Autowired
	private CarMapper iCarDao;
	@Autowired
	private UnitMapper unitMapper;
	@Autowired
	private EquPropertyMapper equPropertyMapper;
	@Autowired
	private EquipmentCategoryMapper equipmentCategoryMapper;
	@Autowired
	private WarehouseStructureMapper warehouseStructureMapper;
	@Autowired
	private IEquipmentDetailService iEquipmentDetailService;
	@Autowired
	private IEquipmentService iEquipmentService;
	@Autowired
	private IUnitService iUnitService;
	@Autowired
	private StockDetailMapper stockDetailMapper;
	@Autowired
	private CarMapper carMapper;
	@Autowired
	private EquipmentIndexMapper equipmentIndexMapper;
	@Autowired
	private EquipmentSpecificMapper equipmentSpecificMapper;
	@Autowired
	private IEquipmentSpecificSerivce equipmentSpecificSerivce;
	@Autowired
	private IStockDetailService iStockDetailService;
	 
	public ScanResult<QREquipResponse> scan(QRCodeRequest request) throws RuntimeException {
		try {
			String qrCode = StringUtil.splitQRCode(request)[1];
			Long warehouseId = Long.parseLong(request.getWarehouseId());
			QREquipResponse response = new QREquipResponse();

			ScanTypeEnum type = ScanTypeEnum.getEnum(request.getType());
			
			// 出库需要知道装备的附加信息
			response.setNeedEdditionalInfo(true);
			switch (type) {
			case EQUIPMENT_INSTOCK:
				checkInStockEquipInfo(qrCode, warehouseId);
				break;
			case EQUIPMENT_OUTSTOCK:
				checkOutStockEquipInfo(qrCode, warehouseId);
				break;
			case EQUIPMENT_LOSSOUTSTOCK:
				checkLossOutStockEquipInfo(qrCode, warehouseId);
				break;
			case EQUIPMENT_MAINTENANCE:
				checkEquipMaintenanceInfo(qrCode, warehouseId);
				break;
			case EQUIPMENT_REPAIR:
				checkEquipRepairInfo(qrCode, warehouseId);
				break;
			case EQUIPMENT_REPAIRCOMPLETE:
				checkEquipRepaircompleted(qrCode, warehouseId);
				break;
			case EQUIPMENT_SCRAP:
				checkEquipScrapInfo(qrCode, warehouseId);
				break;
			case EQUIPMENT_STOCK:
				break;
			case CAR_LOAD:
				checkLoadEquipInfo(qrCode, warehouseId);
				break;
			case CAR_UNINSTALL:
				checkUnLoadEquipInfo(qrCode, warehouseId);
				break;
			case EQUIP_BIND:
				checkEquipBindingrfidInfo(qrCode);
				break;
			default:
				response.setNeedEdditionalInfo(true);
				break;
			}

			// 生成扫码基本信息
			response.setEquipment(generateBasicInfo(qrCode));

			// 生成扫码附加信息
			response.setEquipEdditionalInfo(generateEdditionalInfo(qrCode, warehouseId));

			// 合并信息
			response.merge();

			// 设置类型
			response.setType(EQUIPMENT_TYPE);

			// 判断是否为灭火药剂
			String eqCode = response.getEquipment().getEquipmentCode();
			if (StringUtil.isNotEmpty(eqCode) && !eqCode.startsWith("4")) {
				String amount = response.getEquipment().getAmount().toString();
				amount = amount.split("\\.")[0];
				response.getEquipment().setAmount(amount);
			}

			return response;
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
			throw e;
		}

	}

	private void checkLossOutStockEquipInfo(String qrCode, Long warehouseId) {
		List<StockDetail> details = findAllStockDetails(qrCode, warehouseId);

		if (!isStockEquipment(details)) {
			throw new IllegalArgumentException("此装备不在本仓库中，无法出库！");
		}
	}

	/**
	 * 检查装备是否可被报废
	 *
	 * @param qrCode
	 * @param warehouseId
	 */
	private void checkEquipScrapInfo(String qrCode, Long warehouseId) {
		List<StockDetail> details = findAllStockDetails(qrCode, warehouseId);
		List<StockDetail> aggregation = new ArrayList<>();

		if (details.isEmpty()) {
			throw new IllegalArgumentException("该装备不属于本仓库，不能报废！");
		}

		aggregation = filtering(details, warehouseId);
		if (!aggregation.isEmpty()) {
			EquipStatusEnum status = EquipStatusEnum.getEnum(Long.valueOf(aggregation.get(0).getStatus()));
			Result result = EquipStatusChecker.isScrapable(status);
			if (!result.isOk()) {
				throw new IllegalArgumentException(result.toString());
			}
		}
		// List<StockDetail> allocaEquips = filtering(details, warehouseId,
		// EquipStatusEnum.ALLOCATION);
		// if(!allocaEquips.isEmpty()){
		// throw new IllegalArgumentException("该装备已调入其他单位，不能报废！");
		// }

		// StockDetail lastDetail = filteringLastUpdate(details);
		// if (null != lastDetail) {
		// EquipStatusEnum status =
		// EquipStatusEnum.getEnum(lastDetail.getStatus());
		// Result result = EquipStatusChecker.isScrapable(status);
		// if (!result.isOk()) {
		// throw new IllegalArgumentException(result.toString());
		// }
		// }

	}

	/**
	 * 检查装备是否可被保养
	 *
	 * @param qrCode
	 * @param warehouseId
	 */
	private void checkEquipMaintenanceInfo(String qrCode, Long warehouseId) {
		if (StringUtil.isNotEmpty(qrCode)) {
			QueryWrapper<StockDetail> stockQueryWrapper = new QueryWrapper<>();
			stockQueryWrapper.eq("qr_code", qrCode);
			if (null == iStockDetailService.getOne(stockQueryWrapper)) {
				throw new RuntimeException("未入库的装备不能保养！");
			}
		}

		List<StockDetail> details = findAllStockDetails(qrCode, warehouseId);
		if (!details.isEmpty()) {
			EquipStatusEnum status = EquipStatusEnum.getEnum(Long.valueOf(details.get(0).getStatus()));
			Result result = EquipStatusChecker.isMaintenanceable(status);
			if (!result.isOk()) {
				throw new IllegalArgumentException(result.toString());
			}
		}

	}

	/**
	 * 获取装备二维码基本信息
	 *
	 * @param qrCode
	 * @return
	 * @throws IllegalArgumentException
	 */
	private ScanEquipmentBasicInfo generateBasicInfo(String qrCode) throws IllegalArgumentException {

		EquipmentSpecific equipmentSpecific = findEquipmentQRCode(qrCode);
		if (null == equipmentSpecific) {
			throw new IllegalArgumentException("该二维码不属于本系统！");
		}
		
//		if (equipmentSpecific.getSingle() == false){
//			throw new IllegalArgumentException("该功能只支持单件管理！");
//		}
		ScanEquipmentBasicInfo info = new ScanEquipmentBasicInfo();
		
		 Boolean flag = equipmentSpecificSerivce.equipmentgetIsSingleByQrcode(qrCode, null);
		 info.setSingleOrDouble(flag);
		
		// 获取装备信息
		EquipmentDetail equipmentDetail = iEquipmentDetailService.getOneById(equipmentSpecific.getEquipmentDetailId());
		Equipment equipmentOne = iEquipmentService.getById(equipmentDetail.getEquipmentId());
		//判断是否为灭后药剂
		Boolean isExtinguishant = this.justIsExtinguishant(equipmentOne.getCode());
		Unit unit = equipmentOne.getUnit();
		//装备
		if(!isExtinguishant){
			LambdaQueryWrapper<StockDetail> stockDetailQueryWrapper = new LambdaQueryWrapper<>();
			stockDetailQueryWrapper.eq(StockDetail::getQrCode,qrCode);
			StockDetail stockDetail = stockDetailMapper.selectOne(stockDetailQueryWrapper);
			if(stockDetail != null){
				String description = equipmentDetail.getArea();
				description = (description == null || "".equals(description)) ?  "" : "-"+description;
				//位置
				info.setDescription(warehouseDao.selectById(stockDetail.getWarehouseId()).getCompanyName()
						+"-"+
						warehouseStructureMapper.selectById(stockDetail.getWarehouseStructureId()).getFullName()
						+description);
				QueryWrapper<EquipmentOnCar> equipmentOnCarQueryWrapper = new QueryWrapper<>();
				equipmentOnCarQueryWrapper.eq("stock_detail_id",stockDetail.getId());
				EquipmentOnCar equipmentOnCar = iEquipmentOnCarDao.selectOne(equipmentOnCarQueryWrapper);
				if(equipmentOnCar!=null){
					Car car = carMapper.selectById(equipmentOnCar.getCarId());
					if(car!=null){
						info.setCarNum(car.getCarNum());
					}
				}
			}
		}

		ParsePropertyUtil.setting(info::setQrCode, () -> qrCode);
		ParsePropertyUtil.setting(info::setEquipName, equipmentDetail::getName);
		ParsePropertyUtil.setting(info::setEquipmentCode, equipmentDetail.getEquipment()::getCode);
		ParsePropertyUtil.setting(info::setEquipCate, equipmentDetail.getEquipment().getEquipmentCategory()::getName);
		ParsePropertyUtil.setting(info::setPerfQuota, equipmentDetail::getPerfQuotaStr);
		ParsePropertyUtil.setting(info::setEquipmentDetailId, equipmentSpecific::getEquipmentDetailId);
		ParsePropertyUtil.setting(info::setEquipmentId, equipmentDetail.getEquipment()::getId);
		ParsePropertyUtil.setting(info::setRemark, equipmentDetail.getEquipment()::getRemark);
		ParsePropertyUtil.setting(info::setUnit, unit::getName);
		ParsePropertyUtil.setting(info::setEquipCategoryCode, equipmentDetail::getCode);
		ParsePropertyUtil.setting(info::setStandard, equipmentDetail::getStandard);
		if(equipmentDetail.getManufacturerInfo()!=null){
			ParsePropertyUtil.setting(info::setManufacturer, equipmentDetail.getManufacturerInfo()::getName);
		}
		ParsePropertyUtil.setting(info::setBrand, equipmentDetail::getBrand);

		
		
		
		// ParsePropertyUtil.setting(info::setSupplier,
		// equipmentDetail::getSupplierName);
		ParsePropertyUtil.setting(info::setDateProduced, () -> DateUtils.date2LongStr(equipmentSpecific.getCreateDate()));
		ParsePropertyUtil.setting(info::setContractCode, equipmentDetail::getContractCode);

		// ParsePropertyUtil.setting(info::setSupplier,
		// equipmentDetail::getSupplierName);
		ParsePropertyUtil.setting(info::setDateProduced, () -> DateUtils.date2LongStr(equipmentSpecific.getCreateDate()));
		ParsePropertyUtil.setting(info::setContractCode, equipmentDetail::getContractCode);

		ParsePropertyUtil.setting(info::setFilm, () -> {
			System.err.println(equipmentDetail);
			if(equipmentDetail.getVideo()!=null && equipmentDetail.getVideo().size() != 0){
				if (null != equipmentDetail.getVideo().get(0).getUrl()) {
					return equipmentDetail.getVideo().get(0).getUrl();
				} else if (null != equipmentDetail.getEquipment().getVideo()) {
					return equipmentDetail.getEquipment().getVideo();
				} else {
					return null;
				}
			}else{
				return null;
			}
		});
		String img = iEquipmentService.getById(equipmentDetail.getEquipmentId()).getImg();
		info.setImg(img);
//		ParsePropertyUtil.setting(info::setImg, () -> {
//			if(equipmentDetail.getVideo()!=null && equipmentDetail.getVideo().size() != 0){
//				if (null != equipmentDetail.getImg().get(0).getUrl()) {
//					return equipmentDetail.getImg().get(0).getUrl();
//				} else if (null != equipmentDetail.getEquipment().getImg()) {
//					return equipmentDetail.getEquipment().getImg();
//				} else {
//					return null;
//				}
//			}else{
//				return null;
//			}
//		});
		ParsePropertyUtil.setting(info::setEquProperties, () -> {
			return parseEquipPerformance(findCarProperties(equipmentSpecific.getEquipmentDetailId()));
		});
		return info;
	}

	private Boolean justIsExtinguishant(String code) {
		//装备定义已4开头是灭火药剂、2开头为车辆、其他为装备
		return code.startsWith("4");
	}

	/**
	 * 查询装备下性能指标
	 *
	 * @param
	 * @return
	 */
	private List<EquProperty> findCarProperties(Long id) {
		Map<String, Object> columnMap = new HashMap<String, Object>();
		columnMap.put("equipment_detail_id", id);
		List<EquProperty> list = equPropertyMapper.selectByMap(columnMap);
		return list;
	}

	/**
	 * 解析性能指标
	 *
	 * @param
	 * @param equProperties
	 */
	public List<EquPropertyResponse> parseEquipPerformance(List<EquProperty> equProperties) {
		List<EquPropertyResponse> list = new ArrayList<>();

		for (EquProperty ep : equProperties) {
			if (ep == null) {
				continue;
			}

			// 获取性能参数
			EquipmentIndex equipmentIndex = equipmentIndexMapper.selectById(ep.getEquipmentIndexId());
			EquPropertyResponse epr = new EquPropertyResponse();
			ParsePropertyUtil.setting(epr::setName, () -> equipmentIndex.getPerfQuotaName());
			ParsePropertyUtil.setting(epr::setUnit, () -> equipmentIndex.getUnitName());
			ParsePropertyUtil.setting(epr::setIsImportentParameter, () -> true);
			ParsePropertyUtil.setting(epr::setTextLine, () -> {
				return equipmentIndex.getPerfQuotaName() + ":" + ep.getValue()+"("+equipmentIndex.getUnitName()+")";
			});
			epr.setValue(ep.getValue());
			list.add(epr);
		}
		return list;
	}

	// 车载

	private EquipmentOnCar findequipmentOnCar(Long id) {
		Map<String, Object> columnMap = new HashMap<String, Object>();
		columnMap.put("stock_detail_id", id);
		List<EquipmentOnCar> equipmentOnCar = iEquipmentOnCarDao.selectByMap(columnMap);
		if (equipmentOnCar != null && equipmentOnCar.size() > 0) {
			return equipmentOnCar.get(0);
		}
		return null;
	}

	/**
	 * 获取装备的附加信息
	 *
	 * @param qrCode
	 * @param warehouseId
	 * @return
	 * @throws IllegalArgumentException
	 */
	private ScanEquipEdditionalInfo generateEdditionalInfo(String qrCode, Long warehouseId)
			throws IllegalArgumentException {
		ScanEquipEdditionalInfo info = new ScanEquipEdditionalInfo();
		List<StockDetail> details = findAllStockDetails(qrCode);
		// 检查该装备是否属于本仓库
		List<StockDetail> owners = ArrayUtil.filter(details, d -> d.getWarehouseId().longValue() == warehouseId);
		if (owners.isEmpty()) {
			ParsePropertyUtil.setting(info::setTotal, () -> countEquipments(0L, warehouseId));
		} else {
			ParsePropertyUtil.setting(info::setTotal,
					() -> countEquipments(owners.get(0).getEquipmentDetailId(), warehouseId));
		}
		List<StockDetail> aggregation = ArrayUtil.filter(details,
				d -> null != findequipmentOnCar(d.getId()) && 0 == d.getAmount());

		if (!aggregation.isEmpty()) {
			ParsePropertyUtil.setting(info::setIsCarLoad, () -> true);
			Optional.ofNullable(aggregation.get(0).getQrCode()).ifPresent(code -> {
				EquipmentOnCar equipmentOnCar = findEquipmentOnCar(code);
				// 车载equipmentOnCar
				Car car = iCarDao.selectById(equipmentOnCar.getCarId());
				// 库存明细
				StockDetail stockDetail = iStockDetailDao.selectById(equipmentOnCar.getStockDetailId());

				// 查询装备
				Equipment equipment = EquipmentMapper.selectById(car.getEquipmentId());
				// 分类
				EquipmentCategory equipmentCategory = equipmentCategoryMapper.selectById(equipment.getCategoryId());

				ParsePropertyUtil.setting(info::setCarId, equipmentOnCar::getCarId);
				ParsePropertyUtil.setting(info::setCarNum, car::getCarNum);
				ParsePropertyUtil.setting(info::setStockDetailId, equipmentOnCar::getStockDetailId);
				//设置二维码包含数量
				info.setAmount(stockDetail.getAmount());
				
				ParsePropertyUtil.setting(info::setStatus,
						() -> EquipStatusEnum.getEnum(Long.valueOf(stockDetail.getStatus())).getDescribe());
				ParsePropertyUtil.setting(info::setCarType, () -> {
					return equipmentCategory.getName();
				});
				ParsePropertyUtil.setting(info::setCarCompany,
						() -> getSelectedOrgInfo().getCompany().getCompanyName());
			});
		}
		// 数量大于0的
		aggregation = ArrayUtil.filter(details, d -> {
			// return d.getOrgCode().equals(getCompanyCode()) && d.getAmount() > 0;
			return d.getAmount() > 0;
		});
		//
		// //执勤装备非车载的装备
		// List<StockDetail> onDutyEquips = filteringOnDuty(details,
		// warehouseId);
		//

		if (!details.isEmpty()) {
			StockDetail orgCodeDetail = details.get(0);
			ParsePropertyUtil.setting(info::setCarCompany, getSelectedOrgInfo().getCompany()::getCompanyName);
			if (!aggregation.isEmpty()) {
				StockDetail detail1 = aggregation.get(0);
				// 获取货位
				WarehouseStructure warehouseStructure = warehouseStructureMapper
						.selectById(detail1.getWarehouseStructureId());
				// 获取仓库
				Warehouse warehouse = warehouseDao.selectById(detail1.getWarehouseId());
				
				
				//设置二维码包含数量
				info.setAmount(detail1.getAmount());
				ParsePropertyUtil.setting(info::setGoodsAllocationCode, warehouseStructure::getCode);
				ParsePropertyUtil.setting(info::setShelfCellId, detail1::getWarehouseStructureId);
				ParsePropertyUtil.setting(info::setStockDetailId, detail1::getId);
				ParsePropertyUtil.setting(info::setWarehouseName, warehouse::getName);
				ParsePropertyUtil.setting(info::setStatus,
						() -> EquipStatusEnum.getEnum(Long.valueOf(detail1.getStatus())).getDescribe());
				ParsePropertyUtil.setting(info::setCarCompany, getSelectedOrgInfo().getCompany()::getCompanyName);
				ParsePropertyUtil.setting(info::setCarType, () -> findCategoryNameByID(detail1.getId()));

			} else
				ParsePropertyUtil.setting(info::setStockDetailId, orgCodeDetail::getId);
			/*
			 * if(!onDutyEquips.isEmpty()){ StockDetail detail2 = onDutyEquips.get(0); //获取
			 * Stock stock=iStockDao.selectById(detail2.getStockId()); //获取仓库 Warehouse
			 * warehouse=warehouseDao.selectById(stock.getWarehouseId()) ;
			 * ParsePropertyUtil.setting(info::setStockDetailId, detail2::getId);
			 * ParsePropertyUtil.setting(info::setCount, detail2::getAmount);
			 * ParsePropertyUtil.setting(info::setWarehouseName, warehouse::getName);
			 * ParsePropertyUtil.setting(info::setStatus,
			 * ()->EquipStatusEnum.getEnum(detail2.getStatus()). getDescribe());
			 * ParsePropertyUtil.setting(info::setCarType, () ->
			 * findCategoryNameByID(detail2.getId()));
			 * ParsePropertyUtil.setting(info::setCarCompany,
			 * getSelectedOrgInfo().getCompany()::getCompanyName); }else
			 */ {
				List<StockDetail> lossEquips = ArrayUtil.filter(details,
						d -> EquipStatusEnum.getEnum(Long.valueOf(d.getStatus())) == EquipStatusEnum.LOSS);
				List<StockDetail> maintainEquips = ArrayUtil.filter(details,
						d -> EquipStatusEnum.getEnum(Long.valueOf(d.getStatus())) == EquipStatusEnum.REPAIR);
				List<StockDetail> maintainE = ArrayUtil.filter(details,
						d -> EquipStatusEnum.getEnum(Long.valueOf(d.getStatus())) == EquipStatusEnum.ONCAR);
				
				
				
				
				
				// List<StockDetail> retirementEquips =
				// ArrayUtil.filter(details, d ->
				// EquipStatusEnum.getEnum(Long.valueOf(d.getStatus())) ==
				// EquipStatusEnum.RETIREMENT);

				if (!lossEquips.isEmpty()) {
					//设置二维码包含数量
					info.setAmount(lossEquips.get(0).getAmount());
					ParsePropertyUtil.setting(info::setStatus, () -> EquipStatusEnum.LOSS.getDescribe());
					ParsePropertyUtil.setting(info::setStockDetailId, () -> lossEquips.get(0).getId());
					ParsePropertyUtil.setting(info::setCarType, () -> findCategoryNameByID(lossEquips.get(0).getId()));
					ParsePropertyUtil.setting(info::setCarCompany, getSelectedOrgInfo().getCompany()::getCompanyName);
				} else if (!maintainEquips.isEmpty()) {
					
					//设置二维码包含数量
					info.setAmount(maintainEquips.get(0).getAmount());
					ParsePropertyUtil.setting(info::setStatus, () -> EquipStatusEnum.REPAIR.getDescribe());
					ParsePropertyUtil.setting(info::setStockDetailId, () -> maintainEquips.get(0).getId());
					ParsePropertyUtil.setting(info::setCarType,
							() -> findCategoryNameByID(maintainEquips.get(0).getId()));
					ParsePropertyUtil.setting(info::setCarCompany, getSelectedOrgInfo().getCompany()::getCompanyName);
				}else if(!maintainE.isEmpty()){
					
					
					
					//查询车载数量
					EquipmentOnCar equipmentOnCar=	findEquipmentOnCarda(maintainE.get(0).getId());
					
					//设置二维码包含数量
					info.setAmount(equipmentOnCar.getAmount());
					
					ParsePropertyUtil.setting(info::setStatus, () -> EquipStatusEnum.ONCAR.getDescribe());
					ParsePropertyUtil.setting(info::setStockDetailId, () -> maintainE.get(0).getId());
					ParsePropertyUtil.setting(info::setCarType,
							() -> findCategoryNameByID(maintainE.get(0).getId()));
					ParsePropertyUtil.setting(info::setCarCompany, getSelectedOrgInfo().getCompany()::getCompanyName);
					
					
					
				}
				
				
				
				
				// else if (!retirementEquips.isEmpty()){
				// ParsePropertyUtil.setting(info::setStatus,
				// ()->EquipStatusEnum.RETIREMENT.getDescribe());
				// ParsePropertyUtil.setting(info::setStockDetailId, () ->
				// retirementEquips.get(0).getId());
				// ParsePropertyUtil.setting(info::setCarType, () ->
				// findCategoryNameByID(retirementEquips.get(0).getId()));
				// ParsePropertyUtil.setting(info::setCarCompany,getSelectedOrgInfo().getCompany()::getCompanyName);
				// }
			}

			info.setCount(info.getTotal());
		} else {

			Map<String, Object> columnMap = new HashMap<String, Object>();
//			columnMap.put("q_r_code", qrCode);
//			List<EquipmentQrcode> equipmentQRCode1 = iEquipmentQRCodeDao.selectByMap(columnMap);
			columnMap.put("qr_code", qrCode);
			List<EquipmentSpecific> equipmentSpecifics = equipmentSpecificMapper.selectByMap(columnMap);
			if (null != equipmentSpecifics && equipmentSpecifics.size() > 0) {
				EquipmentSpecific equipmentSpecific = equipmentSpecifics.get(0);
				Long equipmentDetailId = equipmentSpecific.getEquipmentDetailId();

				Stock stock = findStock(warehouseId, equipmentDetailId);
				ParsePropertyUtil.setting(info::setCarCompany, getSelectedOrgInfo().getCompany()::getCompanyName);
				if (null != stock) {
					// 获取仓库
					Warehouse warehouse = warehouseDao.selectById(stock.getWarehouseId());

					ParsePropertyUtil.setting(info::setTotal, stock::getAmount);
					ParsePropertyUtil.setting(info::setWarehouseName, warehouse::getName);
					List<StockDetail> otherDetails = findAllStockDetials(equipmentDetailId);
					if (!otherDetails.isEmpty()) {
						ParsePropertyUtil.setting(info::setCarType,
								() -> findCategoryNameByID(otherDetails.get(0).getId()));
					}
					Double total = 0d;
					total = otherDetails.stream().mapToDouble(d -> {
						if (Integer.valueOf(d.getStatus()) == 1 && d.getWarehouseId() == warehouseId) {
							return d.getAmount();
						} else {
							return 0d;
						}
					}).sum();
					info.setTotal(total);
					info.setCount(total);
				}
			}

		}

		return info;
	}

	private void otherCompanyEquipHandler(ScanEquipEdditionalInfo info, List<StockDetail> details) {

	}

	public String findCategoryNameByID(long id) {
		List<Map<String, Object>> list = iStockDetailDao.findCategoryNameByID(id);
		if (list != null && list.size() > 0) {
			return list.get(0).get("name").toString();
		}
		return "";
	}

	/**
	 * 装备维修检查
	 *
	 * @param qrCode
	 * @param warehouseId
	 */
	private void checkEquipRepairInfo(String qrCode, Long warehouseId) throws IllegalArgumentException {
		List<StockDetail> details = findAllStockDetails(qrCode, warehouseId);

		if (details.isEmpty()) {
			throw new IllegalArgumentException("该装备不属于本仓库，不能维修！");
		}

		if (!details.isEmpty() && isRepairEquipment(details.get(0))) {
			throw new IllegalArgumentException("该装备正在维修中，不能重复维修！");
		}

		if (!details.isEmpty()) {
			EquipStatusEnum equipStatusEnum = EquipStatusEnum.getEnum(Long.valueOf(details.get(0).getStatus()));
			Result result = EquipStatusChecker.isRepairable(equipStatusEnum);
			if (!result.isOk()) {
				throw new IllegalArgumentException(result.toString());
			}
		}

	}

	/**
	 * 装备维修完成检查
	 *
	 * @param qrCode
	 * @param warehouseId
	 */
	private void checkEquipRepaircompleted(String qrCode, Long warehouseId) {
		List<StockDetail> details = findAllStockDetails(qrCode, warehouseId);

		if (details.isEmpty()) {
			throw new IllegalArgumentException("该装备未记录在本系统，不能维修完成！");
		}
		if (!isRepairEquipment(details.get(0))) {
			throw new IllegalArgumentException("该装备未在维修，不能维修完成！");
		}

	}

	/**
	 * 入库前检查
	 *
	 * @param qrCode
	 * @param warehouseId
	 * @param
	 * @throws IllegalArgumentException
	 */
	private void checkInStockEquipInfo(String qrCode, Long warehouseId) throws IllegalArgumentException {
		// 判断此QRCode是否已经在库
		List<StockDetail> details = findAllStockDetails(qrCode);
		if (isCarEquipment(details)) {
			throw new IllegalArgumentException("该装备已装载在车辆上，不能入库！");
		}

		if (isStockEquipment(details, warehouseId)) {
			throw new IllegalArgumentException("此装备已在本仓库中，无法重复入库！");
		}

		// if (isStockEquipment(details) && !isReturnable(details)) {
		// throw new IllegalArgumentException("此装备已在其他仓库中，无法重复入库！");
		// }

		List<StockDetail> lossDetails = ArrayUtil.filter(details,
				(d) -> Long.valueOf(d.getStatus()) == EquipStatusEnum.LOSS.getCode().longValue());
		if (!lossDetails.isEmpty()) {
			throw new IllegalArgumentException("此装备已损耗，无法入库！");
		}
	}

	/**
	 * 出库前检查
	 *
	 * @param qrCode
	 * @param warehouseId
	 * @param
	 * @throws IllegalArgumentException
	 */
	private void checkOutStockEquipInfo(String qrCode, Long warehouseId) throws IllegalArgumentException {
		List<StockDetail> details = findAllStockDetails(qrCode);
		if (isCarEquipment(details)) {
			throw new IllegalArgumentException("该装备已装载在车辆上，不能出库！");
		}

		if (!isStockEquipment(details)) {
			throw new IllegalArgumentException("此装备不在本仓库中，无法出库！");
		}

		List<StockDetail> aggregation = filtering(details, warehouseId);
		if (aggregation.isEmpty()) {
			throw new IllegalArgumentException("此装备不在本仓库中，无法出库！");
		}

		EquipStatusEnum equipStatusEnum = EquipStatusEnum.getEnum(Long.valueOf(aggregation.get(0).getStatus()));
		Result result = EquipStatusChecker.isOutStockable(equipStatusEnum);
		if (!result.isOk()) {
			throw new IllegalArgumentException(result.toString());
		}

	}

	/**
	 * 是否可绑定rfid
	 *
	 * @param qrCode
	 * @param
	 * @throws IllegalArgumentException
	 */
	private void checkEquipBindingrfidInfo(String qrCode) throws IllegalArgumentException {
		List<StockDetail> details = findAllStockDetails(qrCode);
		if (details == null || details.isEmpty()) {
			throw new IllegalArgumentException("该装备不存在！");
		}
	}

	/**
	 * 车载装备检查
	 *
	 * @param qrCode
	 * @throws IllegalArgumentException
	 */
	private void checkLoadEquipInfo(String qrCode, Long warehouseId) throws IllegalArgumentException {
		int count = equipmentSpecificSerivce.count(new QueryWrapper<EquipmentSpecific>().like("qr_code", qrCode));
		if (count ==0){
			throw  new BadRequest("请输入正确的装备编码");
		}
		List<StockDetail> details = findAllStockDetails(qrCode);
		if (isCarEquipment(details)) {
			throw new IllegalArgumentException("该装备已装载在车辆上，不能重复装载！");
		}

		List<StockDetail> aggregation = filtering(details, warehouseId);
		if (!aggregation.isEmpty()) {
			StockDetail detail = aggregation.get(0);
			Long eqid = detail.getEquipmentDetailId();
			EquipmentDetail oneById = iEquipmentDetailService.getOneById(eqid);
			if (oneById.getCode().startsWith("4")){
				throw new IllegalArgumentException("请扫描正确的装备二维码！");
			}
			if (EquipStatusEnum.REPERTORY.getCode().longValue() == Long.valueOf(detail.getStatus())) {
				return;
			} else {
				EquipStatusEnum status = EquipStatusEnum.getEnum(Long.valueOf(detail.getStatus()));
				Result result = EquipStatusChecker.isLoadable(status);
				if (!result.isOk()) {
					throw new IllegalArgumentException(result.toString());
				}

			}
		}

		if (!isStockEquipment(details, warehouseId)) {
			throw new IllegalArgumentException("此装备库存量不足，无法装载到车辆上！");
		}

	}

	/**
	 * 卸载装备检查
	 *
	 * @param qrCode
	 * @param warehouseId
	 * @throws IllegalArgumentException
	 */
	private void checkUnLoadEquipInfo(String qrCode, Long warehouseId) throws IllegalArgumentException {
		String type = equipmentSpecificSerivce.getEquipSpeTypeByQrcode(qrCode);
		if ("agent".equals(type)) {
			throw new IllegalArgumentException("灭火药剂不能通过装备卸载操作来完成！");
		}
		List<StockDetail> details = findAllStockDetails(qrCode);
		if (!isCarEquipment(details)) {
			throw new IllegalArgumentException("该装备未被装载在车辆上，不能卸载！");
		}

//		StockDetail detail = ArrayUtil.any(details,
//				d -> d.getOrgCode().equals(getSelectedOrgInfo().getCompany().getOrgCode())
//						&& Long.valueOf(d.getStatus()) == EquipStatusEnum.ONCAR.getCode().longValue());
//		if (null == detail) {
//			throw new IllegalArgumentException("该装备不属于本单位，不能卸载！");
//		}
	}

	/**
	 * 获取车辆装备
	 *
	 * @param qrCode
	 * @return
	 */
	private EquipmentOnCar findEquipmentOnCar(String qrCode) {
		Map<String, Object> columnMap = new HashMap<String, Object>();
		columnMap.put("qr_code", qrCode);
		List<StockDetail> equipmentOnCar = iStockDetailDao.selectByMap(columnMap);
		if (equipmentOnCar != null && equipmentOnCar.size() > 0) {
			columnMap.clear();
			columnMap.put("stock_detail_id", equipmentOnCar.get(0).getId());
			List<EquipmentOnCar> list = iEquipmentOnCarDao.selectByMap(columnMap);
			if (list != null && list.size() > 0) {
				return list.get(0);
			} else {
				return null;
			}
		} else {
			return null;
		}

	}

	/**
	 * 获取所有明细账
	 *
	 * @param qrCode
	 * @return
	 */
	private List<StockDetail> findAllStockDetails(String qrCode) {
		QueryWrapper queryWrapper = new QueryWrapper();
		queryWrapper.like("qr_code",qrCode);
//		Map<String, Object> columnMap = new HashMap<String, Object>();
//		columnMap.put("qr_code", qrCode);
		List<StockDetail> stockDetail = iStockDetailDao.selectList(queryWrapper);

		// return iStockDetailDao.findAllByQrCodeOrderByDateUpdatedDesc(qrCode);
		return stockDetail;

	}

	/**
	 * 获取该仓库下的明细账
	 *
	 * @param qrCode
	 * @param warehouseId
	 * @return
	 */
	private List<StockDetail> findAllStockDetails(String qrCode, Long warehouseId) {
		Map<String, Object> columnMap = new HashMap<String, Object>();
		columnMap.put("qr_code", qrCode);
		columnMap.put("warehouse_id", warehouseId);
		List<StockDetail> stockDetail = iStockDetailDao.selectByMap(columnMap);

		// return
		// iStockDetailDao.findAllByQrCodeAndWarehouseIdOrderByDateUpdatedDesc(qrCode,
		// warehouseId);
		return stockDetail;
	}

	/**
	 * 获取二维码对应信息
	 *
	 * @param qrCode
	 * @return
	 */
	private EquipmentSpecific findEquipmentQRCode(String qrCode) {
		Map<String, Object> columnMap = new HashMap<String, Object>();
//		columnMap.put("q_r_code", qrCode);
//		List<EquipmentQrcode> equipmentQRCode1 = iEquipmentQRCodeDao.selectByMap(columnMap);
//		columnMap.clear();
		columnMap.put("qr_code", qrCode);
		List<EquipmentSpecific> equipmentSpecifics = equipmentSpecificMapper.selectByMap(columnMap);
		if (equipmentSpecifics != null && equipmentSpecifics.size() > 0) {
			return equipmentSpecifics.get(0);
		}

		return null;
		// return iEquipmentQRCodeDao.findOneByQRCode(qrCode);

	}

	/**
	 * 是否为库存装备
	 *
	 * @param details
	 * @return
	 */
	private boolean isStockEquipment(List<StockDetail> details) {
		return !details.parallelStream().filter(detail -> detail.getAmount() > 0).collect(Collectors.toList())
				.isEmpty();
	}

	/**
	 * 是否为库存装备
	 *
	 * @param details
	 * @param warehouseId
	 * @return
	 */
	private boolean isStockEquipment(List<StockDetail> details, Long warehouseId) {
		return !filtering(details, warehouseId).isEmpty();
	}

	/**
	 * 过滤有数量的库存明细账
	 *
	 * @param details
	 * @param warehouseId
	 * @return
	 */
	private List<StockDetail> filtering(List<StockDetail> details, Long warehouseId) {
		return details.parallelStream().filter(
				detail -> detail.getAmount() > 0 && detail.getWarehouseId().longValue() == warehouseId.longValue())
				.collect(Collectors.toList());
	}

	/**
	 * 获取特定的值
	 *
	 * @param details
	 * @param warehouseId
	 * @return
	 */
	private List<StockDetail> filtering(List<StockDetail> details, Long warehouseId, EquipStatusEnum status) {
		return ArrayUtil.filter(details, (detail) -> {
			return detail.getAmount() == 0d && detail.getWarehouseId().longValue() == warehouseId.longValue()
					&& status == EquipStatusEnum.getEnum(Long.valueOf(detail.getStatus()));
		});
	}

	private EquipmentOnCar findEquipmentOnCarda(Long id) {
		Map<String, Object> columnMap = new HashMap<String, Object>();
		columnMap.put("stock_detail_id", id);
		List<EquipmentOnCar> equipmentOnCar = iEquipmentOnCarDao.selectByMap(columnMap);

		if (equipmentOnCar != null && equipmentOnCar.size() > 0) {
			return equipmentOnCar.get(0);
		}

		return null;

	}

	/**
	 * 是否为车辆装备
	 *
	 * @param details
	 * @return
	 */
	private boolean isCarEquipment(List<StockDetail> details) {
		List<StockDetail> list = ArrayUtil.filter(details,
				(detail) -> null != findEquipmentOnCarda(detail.getId()) && 0 == detail.getAmount());
		return !list.isEmpty();
	}

	/**
	 * 获取仓库信息
	 *
	 * @param warehouseId
	 * @return
	 */
	private Warehouse findWarehouse(Long warehouseId) {

		return warehouseDao.selectById(warehouseId);
	}

	/**
	 * 是否是维修状态
	 *
	 * @param detail
	 * @return
	 */
	private boolean isRepairEquipment(StockDetail detail) {
		Long value = Long.valueOf(detail.getStatus());
		return value.longValue() == EquipStatusEnum.REPAIR.getCode().longValue();
	}

	/**
	 * 车载装备是否为维修状态
	 *
	 * @param equipmentOnCar
	 * @return
	 */
	private boolean isRepairEquipmentOnCar(EquipmentOnCar equipmentOnCar) {
		if (null == equipmentOnCar) {
			return false;
		}
		StockDetail stockDetail = iStockDetailDao.selectById(equipmentOnCar.getStockDetailId());
		Long value = Long.valueOf(stockDetail.getStatus());
		return value.longValue() == EquipStatusEnum.REPAIR.getCode().longValue();
	}

	public List<StockDetail> findAllStockDetials(Long equipmentDetailId) {

		Map<String, Object> columnMap = new HashMap<String, Object>();
		columnMap.put("org_code", getSelectedOrgInfo().getCompany().getOrgCode());
		columnMap.put("equipment_detail_id", equipmentDetailId);
		List<StockDetail> stockDetail = iStockDetailDao.selectByMap(columnMap);

		return stockDetail;
		// return
		// iStockDetailDao.findAllByEquipmentDetailIdAndOrgCode(equipmentDetailId,
		// getSelectedOrgInfo().getCompany().getOrgCode())
		// .parallelStream()
		// .map(array -> {
		// StockDetail sd = new StockDetail();
		// if (StringUtil.isNotEmpty(array[0])) {
		// sd.setAmount(Double.valueOf(array[0].toString()));
		// sd.setStatus(Long.valueOf(array[1].toString()));
		// sd.setWarehouseId(Long.valueOf(array[2].toString()));
		// }
		// return sd;
		// }).collect(Collectors.toList());

	}

	/**
	 * 查询库存台账
	 *
	 * @param warehouseId
	 * @param equipmentDetailId
	 * @return
	 */
	private Stock findStock(Long warehouseId, Long equipmentDetailId) {
		Map<String, Object> columnMap = new HashMap<String, Object>();
		columnMap.put("warehouse_id", warehouseId);
		columnMap.put("equipment_detail_id", equipmentDetailId);
		List<Stock> list = iStockDao.selectByMap(columnMap);
		if (null != list && list.size() > 0) {
			return list.get(0);
		}
		return null;
	}

	// /**
	// * 过滤执勤非车载装备
	// *
	// * @param details
	// * @param warehouseId
	// * @return
	// */
	// private List<StockDetail> filteringOnDuty(List<StockDetail> details, Long
	// warehouseId) {
	// return details.parallelStream()
	// .filter(detail -> null ==
	// equipmentOnCarDao.findByStockDetailId(detail.getId())
	// && detail.getAmount() == 0d
	// && detail.getWarehouseId().longValue() == warehouseId.longValue()
	// && detail.getStatus()==EquipStatusEnum.ONDUTY.getCode())
	// .collect(Collectors.toList());
	// return null;
	// }

	// private boolean isRetireEquip(Long id){
	// return true;
	// //return iScrapDetailDao.findAllByStockDetailId(id).isEmpty()?false:true;
	// }

	// private StockDetail filteringLastUpdate(List<StockDetail> details) {
	// if (null == details || details.isEmpty())
	// return null;
	//
	// details = details.stream().sorted((detail1, detail2) -> {
	// if (null == detail1.getDateUpdated() || null == detail2.getDateUpdated())
	// {
	// return 1;
	// } else if (detail1.getDateUpdated().getTime() >=
	// detail2.getDateUpdated().getTime()) {
	// return -1;
	// } else if (detail1.getDateUpdated().getTime() <
	// detail2.getDateUpdated().getTime()) {
	// return 1;
	// } else {
	// return 0;
	// }
	// }).collect(Collectors.toList());
	//
	// return details.get(0);
	//
	// }

	private Double countEquipments(Long equipmentDetailId, Long warehouseId) {

		Map<String, Object> columnMap = new HashMap<String, Object>();
		columnMap.put("status", 1);
		columnMap.put("equipment_detail_id", equipmentDetailId);
		columnMap.put("warehouse_id", warehouseId);
		List<StockDetail> stockDetail = iStockDetailDao.selectByMap(columnMap);
		Double num =0.0;
		if (stockDetail != null) {
			for (int i = 0; i < stockDetail.size(); i++) {
				 num = num+stockDetail.get(i).getAmount();
			}			
		}
		return num;

	}

	/**
	 * 当前登录用户信息
	 */
	/**
	 * 当前登录用户信息
	 */

	protected ReginParams getSelectedOrgInfo() {
		return JSONObject.parseObject(redisUtils.get(buildKey(getUserId(), getToken())).toString(), ReginParams.class);
	}

	protected String getToken() {
		String authToken = request.getHeader("token");
		if (authToken == null) {
			authToken = request.getHeader("X-Access-Token");
		}
		return authToken;
	}

	protected String getProduct() {
		String authToken = request.getHeader("product");
		if (authToken == null) {
			authToken = request.getParameter("product");
		}
		return authToken;
	}

	protected String getAppKey() {
		String authToken = request.getHeader("appKey");
		if (authToken == null) {
			authToken = request.getParameter("appKey");
		}
		return authToken;
	}

	protected String getChannelType() {
		String channelType = request.getHeader("channelType");
		if (channelType == null) {
			channelType = request.getParameter("channelType");
		}
		return channelType;
	}

	/**
	 * 当前登录用户信息
	 */
	protected AgencyUserModel getUserInfo() {
		AgencyUserModel userModel = null;
		if (getToken() != null) {
			RequestContext.setToken(getToken());
			RequestContext.setProduct(getProduct());
			RequestContext.setAppKey(getAppKey());
			FeignClientResult<?> feignClientResult;
			try {
				feignClientResult = Privilege.agencyUserClient.getme();
				userModel = (AgencyUserModel) feignClientResult.getResult();

			} catch (InnerInvokException e) {
				throw new RuntimeException(e.getMessage());
			}

		}
		return userModel;

	}

	protected String getUserId() {
		String userId = null;
		if (getUserInfo() != null) {
			userId = getUserInfo().getUserId();
		}
		return userId;
	}

	// redi缓存选择的用户信息
	private String buildKey(String userId, String token) {
		 return RedisKey.buildReginKey(userId, token);
	}
}
