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


import cn.hutool.core.collection.CollectionUtil;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.core.api.system.StoreFeignClients;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.base.factory.material.service.MaterialModelService;
import com.sw.mes.core.dto.store.LockInventoryDto;
import com.sw.mes.core.dto.store.WarehouseInventoryBo;
import com.sw.mes.core.enums.SeedMassageEnum;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
import com.sw.mes.dingTalk.service.DingTalkService;
import com.sw.mes.enumvalue.EnumValuesServer;
import com.sw.mes.mmcs.service.MMcsInterfaceService;
import com.sw.mes.utils.StringUtils;
import com.sw.mes.yb.plan.entity.ProductionSchedule;
import com.sw.mes.yb.plan.service.ProductionScheduleService;
import com.sw.mes.yb.production.dao.BlastFurnaceDetailDao;
import com.sw.mes.yb.production.dto.BlastFurnaceDetail.BlastFurnaceDetailDto;
import com.sw.mes.yb.production.dto.LoadingTask.LoadingTaskDto;
import com.sw.mes.yb.production.entity.BlastFurnaceDetail;
import com.sw.mes.yb.production.entity.LoadingTask;
import com.sw.mes.yb.production.service.BlastFurnaceDetailService;
import com.sw.mes.yb.production.service.LoadingTaskLogService;
import com.sw.mes.yb.production.service.LoadingTaskService;
import com.sw.mes.yb.production.service.ProductionCircleRecipeDetailService;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
* @Author
* @Description：
* @Date: Create in
* @Modified By:
*/
@Service
@Transactional
public class BlastFurnaceDetailServiceImpl extends BaseServiceImpl<BlastFurnaceDetail> implements BlastFurnaceDetailService {

	@Autowired
	ModelMapper modelMapper;
	@Autowired
	private LoadingTaskService loadingTaskService;

	@Autowired
	private MaterialModelService materialModelService;

	@Autowired
	private LoadingTaskLogService loadingTaskLogService;

	@Autowired
	@Lazy
	private MMcsInterfaceService mMcsInterfaceService;
	@Autowired
	private ProductionCircleRecipeDetailService productionCircleRecipeDetailService;

	@Autowired
	private StoreFeignClients storeFeignClients;

	@Autowired
	private DictionaryItemService dictionaryItemService;

	@Autowired
    private DingTalkService dingTalkService;

	@Autowired
	private ProductionScheduleService productionScheduleService;

    BlastFurnaceDetailDao dao;
	@Autowired
    public void setDao(BlastFurnaceDetailDao dao) {
        super.setBaseDao(dao);
        this.dao=dao;
    }

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void addBlastFurnace(LoadingTaskDto loadingTaskDto,List<BlastFurnaceDetailDto> blastFurnaceDetailDtos,Integer rawStatus,String operationName) {
		if(!rawStatus.equals(LoadingTaskDto.rawStatus_3) && !rawStatus.equals(LoadingTaskDto.rawStatus_4)) {
			throw new RuntimeException("接收错误完工信号");
		}

		Date currentDate = new Date();
		loadingTaskDto.setRawStatus(rawStatus);
		loadingTaskDto.setUserName(operationName);
		loadingTaskDto.setOperationTime(currentDate);

		LoadingTask loadingTask = fromDto(loadingTaskDto);
		loadingTaskService.saveOrUpdate(loadingTask);

		List<LockInventoryDto> lockInventoryList = new ArrayList<>();	// 锁定库存明细

		// 保存投料明细
		List<String> batchNos = new ArrayList<>();
		for(BlastFurnaceDetailDto dto: blastFurnaceDetailDtos){
			dto.setBlastFurnaceId(loadingTask.getId());
			dto.setUserName(operationName);
			dto.setInstallTime(currentDate);
			if(dto.getWeight() == null || dto.getWeight().compareTo(BigDecimal.ZERO) <= 0 ){
				throw new RuntimeException("重量不允许为0或者负数");
			}
			if(batchNos.contains(dto.getBatchNo())){
				throw new RuntimeException("物料有重复，请检查！");
			}
			dto.setMarkCrucible(false);
			if(dto.getMaterialName().contains("合金")){
				//如果无合金牌号和类型，提示必填
				if(StringUtils.isAnyBlank(loadingTaskDto.getAlloyBrand(),loadingTaskDto.getAlloyType())){
					throw new RuntimeException("无合金牌号或者类型");
				}
				dto.setAlloyBrand(loadingTaskDto.getAlloyBrand());
				dto.setAlloyType(loadingTaskDto.getAlloyType());
			}else if(dto.getMaterialName().contains("坩埚")) {
				if (dto.getWeight().compareTo(BigDecimal.ONE) != 0) {
					throw new RuntimeException("坩埚数量不对！");
				}
				dto.setMarkCrucible(true);
			}
			BlastFurnaceDetail blastFurnaceDetail = fromDto(dto);
			// 补充物料信息
			Result<WarehouseInventoryBo> result = storeFeignClients.getByBatchNoAndWarehouseCode(blastFurnaceDetail.getBatchNo(), blastFurnaceDetail.getStoreLocationName());
			WarehouseInventoryBo warehouse = result.getData();
			if (!ObjectUtils.isEmpty(warehouse)) {
				blastFurnaceDetail.setMaterialLevel(warehouse.getMaterialLevel());
				blastFurnaceDetail.setSuppliesGrain(warehouse.getSuppliesGrain());
				blastFurnaceDetail.setResistanceGear(warehouse.getMaterialGear());
			}
			saveOrUpdate(blastFurnaceDetail);

			// 物料唯一校验
			batchNos.add(dto.getBatchNo());

			// 组织锁定库存数据
			LockInventoryDto inventory = new LockInventoryDto();
			inventory.setMaterialModelCode(blastFurnaceDetail.getMaterialCode());
			inventory.setBatchNo(blastFurnaceDetail.getBatchNo());
			inventory.setUniqueCode(blastFurnaceDetail.getUniqueCode()==null? "": blastFurnaceDetail.getUniqueCode());
			inventory.setWarehouseId(blastFurnaceDetail.getStoreLocationId().longValue());
			inventory.setQuantity(blastFurnaceDetail.getWeight());
			lockInventoryList.add(inventory);
		}

		// 修改排程状态
		ProductionSchedule schedule = productionScheduleService.get(loadingTask.getScheduleId());
		schedule.setStatus(EnumValuesServer.ProductionScheduleStatus.已备料.getKey());
		schedule.setStatusInfo("配料任务完成");
		productionScheduleService.saveOrUpdate(schedule);

		// 锁定库存
		Result result = storeFeignClients.lockInventory(lockInventoryList);
		if (result.getCode() != ResultCode.SUCCESS.getCode()){
			throw new RuntimeException("线边仓锁定库存失败：" + result.getMessage());
		}

        seedMessage(loadingTask.getEquipmentCode());
		//装料任务记录
		loadingTaskLogService.saveByLoadingTask(loadingTask);
	}

	/**
	 * 发送消息到精彩群
	 */
	private void seedMessage(String equipmentCode) {
		try {
			ArrayList<String> sceneList = new ArrayList<>();
			ArrayList<String> groupNameList = new ArrayList<>();
			sceneList.add("prod");
			groupNameList.add("母合金报料群");
			String content=equipmentCode + "炉台,系统以过账，需要领母合金"+"复投次数:0";
			String source="ipc确认投料";
			dingTalkService.robotSeedMessage(content, groupNameList, source, sceneList, SeedMassageEnum.GROUP);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	private void checkFromMark(LoadingTaskDto loadingTaskDto, List<BlastFurnaceDetailDto> blastFurnaceDetailDtos) {
		String productType = loadingTaskDto.getProductType();
		Date startDate ;
		DictionaryItem item = dictionaryItemService.findByThemeValueAndNameAndEnable("traceabilityTime","startTime",true);
		if(item == null){
			throw new RuntimeException("溯源卡控时间未维护！");
		} else{
			String startTime = item.getValue();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			try {
				startDate = sdf.parse(startTime);
			} catch (ParseException e) {
				throw new RuntimeException("溯源卡控时间格式不正确！");
			}
		}
		List<String> fromMarks = new ArrayList<>();
		if(productType.length() > 1  && startDate != null && startDate.compareTo(new Date()) < 0){
			String productCategory = productType.substring(0,1);
			if(productCategory != null){
				fromMarks = dictionaryItemService.findValuesByThemeValueAndItemName("fillMarkMap",productCategory);
				if(CollectionUtil.isEmpty(fromMarks)){
					throw new RuntimeException(productCategory+"的溯源卡控标识对应关系未维护！");
				}
			}
			for(BlastFurnaceDetailDto dto : blastFurnaceDetailDtos){
				String batchNo = dto.getBatchNo();
				if(!dto.getMaterialName().contains("坩埚") ){
					String fromMark = batchNo.substring(0,1);
					if(!fromMarks.contains(fromMark)){
						throw new RuntimeException("批次号"+batchNo+"溯源卡控不通过！工单溯源标识为"+productCategory);
					}
				}
			}
		}

	}


	private BigDecimal getWeight(List<BlastFurnaceDetailDto> blastFurnaceDetailDtos) {
		float total = 0;
		for (BlastFurnaceDetailDto blastFurnaceDetailDto : blastFurnaceDetailDtos) {
			total += (blastFurnaceDetailDto.getWeight()==null?0:blastFurnaceDetailDto.getWeight().floatValue());
		}
		return BigDecimal.valueOf(total);
	}

	@Override
	public LoadingTask findTaskByMaterialCode(String materialCode) {
		List<BlastFurnaceDetail> blastFurnaceDetails =  dao.findByMaterialCode(materialCode);
		for (BlastFurnaceDetail blastFurnaceDetail : blastFurnaceDetails) {
			LoadingTask task = loadingTaskService.get(blastFurnaceDetail.getBlastFurnaceId());
			if(task.getRawStatus().equals(LoadingTaskDto.rawStatus_3) || task.getRawStatus().equals(LoadingTaskDto.rawStatus_4)) {
				return task;
			}
		}
		return null;
	}

	@Override
	public List<LoadingTask> findTaskByMaterialCodes(String materialCode) {
		List<LoadingTask> tasks = new ArrayList<LoadingTask>();


		List<BlastFurnaceDetail> blastFurnaceDetails =  dao.findByMaterialCode(materialCode);
		for (BlastFurnaceDetail blastFurnaceDetail : blastFurnaceDetails) {
			LoadingTask task = loadingTaskService.get(blastFurnaceDetail.getBlastFurnaceId());
			if(task.getRawStatus().equals(LoadingTaskDto.rawStatus_3) || task.getRawStatus().equals(LoadingTaskDto.rawStatus_4)) {
				tasks.add(task);
			}
		}
		return tasks;
	}


	@Override
	public BlastFurnaceDetail getCrucibleInfo(Long taskId) {
		List<BlastFurnaceDetail> list = dao.findByTaskId(taskId);
		if(list.size()>0) {
			return list.get(0);
		}
		return null;
	}

	@Override
	public List<BlastFurnaceDetail> getBlastFurnaceDetailList(Long taskId) {
		return dao.findByTaskId(taskId);
	}

	@Override
	public List<Map<String, Object>> pullMaterialData() {
		return dao.pullMaterialData();
	}

	@Override
	public void updatePulledState(List<Long> idList) {
		dao.updatePulledState(idList);
	}

	@Override
	public List<BlastFurnaceDetail> findByLoadingTaskIds(List<Long> loadingTaskIdList) {
		return dao.findByLoadingTaskIds(loadingTaskIdList);
	}

	@Override
	public void deleteByLoadingTaskId(Long loadingTaskId) {
		dao.deleteByBlastFurnaceId(loadingTaskId);
	}

	public BlastFurnaceDetail fromDto(BlastFurnaceDetailDto dto) {
		BlastFurnaceDetail blastFurnaceDetail  = modelMapper.map(dto, BlastFurnaceDetail.class);
		blastFurnaceDetail.setId(null);
		return blastFurnaceDetail;
	}

	public LoadingTask fromDto(LoadingTaskDto dto) {
		return modelMapper.map(dto, LoadingTask.class);
	}

}
