package com.yeejoin.amos.boot.module.cylinder.flc.biz.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.google.common.collect.Sets;
import com.yeejoin.amos.boot.module.cylinder.api.enums.CylDictEnum;
import com.yeejoin.amos.boot.module.cylinder.flc.api.entity.CylinderFilling;
import com.yeejoin.amos.boot.module.cylinder.flc.api.entity.CylinderFillingCheck;
import com.yeejoin.amos.boot.module.cylinder.flc.api.entity.CylinderFillingRecord;
import com.yeejoin.amos.boot.module.cylinder.flc.api.entity.CylinderInfo;
import com.yeejoin.amos.boot.module.cylinder.flc.api.mapper.CylCylinderFillingCheckMapper;
import com.yeejoin.amos.boot.module.cylinder.flc.api.mapper.CylinderFillingCheckMapper;
import com.yeejoin.amos.boot.module.cylinder.flc.api.mapper.CylinderInfoMapper;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StopWatch;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CylSyncServiceImpl {

	@Autowired
	private CylinderSyncServiceImpl sourceFillingCheckServiceImpl;

	@Autowired
	private CylinderInfoMapper cylinderInfoMapper;


	@Autowired
	private CylinderFillingCheckMapper fillingCheckMapper;

	@Autowired
	private CylCylinderFillingCheckMapper cylCylinderFillingCheckMapper;

	@Scheduled(cron = "0 0 1 * * ?")
	@SchedulerLock(name = "syncFillingCheckInfo", lockAtMostFor = "PT10H", lockAtLeastFor = "PT60M")
	public void syncFillingCheckInfo() {
//		Integer totalSize = sourceFillingCheckServiceImpl.getFillCheckListTotal();
//		Integer times;
//		if (totalSize != 0) {
//			times = totalSize / 1000;
//			int last = totalSize % 1000;
//			if (last > 0) {
//				times++;
//			}
//		} else {
//			return;
//		}
//		for (int i = 0; i < times; i++) {
//			traverseSave();
//		}
		traverseSave();
	}

	@Transactional
	public void traverseSave() {
		List<CylinderFillingCheck> fillingChecks = sourceFillingCheckServiceImpl.getFillingCheckList();
		if (!ValidationUtil.isEmpty(fillingChecks)) {
			HashSet<String> fillingCheckIdList = Sets.newHashSet();
			HashSet<String> appIdList = Sets.newHashSet();
			fillingChecks.forEach(e -> {
				e.setAbnormalTemperature(Objects.requireNonNull(CylDictEnum.getEnum(e.getAbnormalTemperature(),
						CylDictEnum.abnormalTemperature_0.getKey())).getSeqNbr());
				e.setWithinScope(Objects.requireNonNull(CylDictEnum.getEnum(e.getWithinScope(),
						CylDictEnum.withinScope_0.getKey())).getSeqNbr());
				e.setWarningSign(Objects.requireNonNull(CylDictEnum.getEnum(e.getWarningSign(),
						CylDictEnum.warningSign_0.getKey())).getSeqNbr());
				e.setSealedState(Objects.requireNonNull(CylDictEnum.getEnum(e.getSealedState(),
						CylDictEnum.sealedState_0.getKey())).getSeqNbr());
				e.setDefective(Objects.requireNonNull(CylDictEnum.getEnum(e.getDefective(),
						CylDictEnum.defective_0.getKey())).getSeqNbr());

				fillingCheckIdList.add(e.getFillingCheckId());
				appIdList.add(e.getAppId());
			});
//			List<CylinderFillingCheck> clearList = Lists.newArrayList();
//			fillingChecks.stream().collect(Collectors.groupingBy(item -> item.getAppId() + "-" + item.getFillingCheckId(), Collectors.maxBy(Comparator.comparing(CylinderFillingCheck::getSyncDate))).forEach((k,v) -> {
//				clearList.add(v.get());
//			});
			//1.更新或插入业务表
			fillingCheckMapper.saveOrUpdateByCondition(fillingChecks);

			//2.更新源表
			sourceFillingCheckServiceImpl.updateBatch(appIdList, fillingCheckIdList);
			traverseSave();
		}
	}


	public boolean cylinderInfo() {
		Integer count = sourceFillingCheckServiceImpl.getCylinderInfoCount();
		Integer times = 0;
		if (count != 0) {
			times = count / 1000;
			int last = count % 1000;
			if (last > 0) {
				times++;
			}
		} else {
			return false;
		}
		for (int i = 0; i < times; i++) {
			LoopSaveCylinderInfo();
		}
		return true;
	}

	@Transactional(rollbackFor = {Exception.class})
	public void LoopSaveCylinderInfo() {
		List<CylinderInfo> cylinderInfoList = sourceFillingCheckServiceImpl.getCylinderInfoList();
		if (!ObjectUtils.isEmpty(cylinderInfoList)) {
			for (CylinderInfo cylinderInfo : cylinderInfoList) {
				cylinderInfo.setCylinderStatus(Objects.requireNonNull(CylDictEnum.getEnum(cylinderInfo.getCylinderStatus(),
						CylDictEnum.cylinder_Status_0.getKey())).getSeqNbr());
				cylinderInfo.setCylinderVariety(Objects.requireNonNull(CylDictEnum.getEnum(cylinderInfo.getCylinderVariety(),
						CylDictEnum.cylinder_Variety_1.getKey())).getSeqNbr());
			}
			cylinderInfoMapper.saveOrUpdateBatch(cylinderInfoList);
			List<Long> sequenceNbrS = cylinderInfoList.stream().map(CylinderInfo::getSequenceNbr).collect(Collectors.toList());
			sourceFillingCheckServiceImpl.updateBatch(sequenceNbrS);
		}
	}

	@Scheduled(cron = "0 0 1 * * ?")
	@SchedulerLock(name = "fillingSync", lockAtMostFor = "PT10H", lockAtLeastFor = "PT60M")
	public Object fillingSync() {
		try {
			StopWatch stopWatch = new StopWatch();
			stopWatch.start();
			List<CylinderFilling> unSyncFilling = sourceFillingCheckServiceImpl.queryUnSyncFilling();
			stopWatch.stop();
			System.out.println("查询时间："+stopWatch.getTotalTimeSeconds());
			while (!unSyncFilling.isEmpty()) {
				fillingDataProcessing(unSyncFilling);
				StopWatch stopWatch1 = new StopWatch();
				stopWatch1.start();
				unSyncFilling = sourceFillingCheckServiceImpl.queryUnSyncFilling();
				stopWatch1.stop();
				System.out.println("查询2时间："+stopWatch.getTotalTimeSeconds());
			}
		} catch (Exception ex) {
			return "failed";
		}
		return "success";
	}

	@Transactional(rollbackFor = {Exception.class})
	public void fillingDataProcessing(List<CylinderFilling> data) {
//		List<String> appIds = new ArrayList<>();
//		List<String> fillingBeforeIds = new ArrayList<>();
//		List<String> sequenceCodes = new ArrayList<>();
		List<Long> ids = data.stream().map(CylinderFilling::getSequenceNbr).collect(Collectors.toList());
		data.forEach(e -> {
//			appIds.add(e.getAppId());
//			fillingBeforeIds.add(e.getFillingBeforeId());
//			sequenceCodes.add(e.getSequenceCode());
			String isValid = e.getIsValid();
			if (!ObjectUtil.isEmpty(isValid) && ("1".equals(isValid) || "0".equals(isValid))) {
				CylDictEnum cylDictEnum = CylDictEnum.getEnum(Integer.valueOf(isValid), CylDictEnum.isValid_0.getKey());
				if (cylDictEnum != null) {
					e.setIsValid(cylDictEnum.getSeqNbr().toString());
				}
			}

			Integer same = e.getSame();
			if (!ObjectUtil.isEmpty(same) && (1 == same || 0 == same)) {
				CylDictEnum cylDictEnum = CylDictEnum.getEnum(same, CylDictEnum.same_0.getKey());
				if (cylDictEnum != null) {
					e.setSame(cylDictEnum.getSeqNbr());
				}
			}

			Integer isRegulations = e.getIsRegulations();
			if (!ObjectUtil.isEmpty(isRegulations) && (1 == isRegulations || 0 == isRegulations)) {
				CylDictEnum cylDictEnum = CylDictEnum.getEnum(isRegulations, CylDictEnum.isRegulations_0.getKey());
				if (cylDictEnum != null) {
					e.setIsRegulations(cylDictEnum.getSeqNbr());
				}
			}

			Integer isComplianceWithgbt = e.getIsComplianceWithgbt();
			if (!ObjectUtil.isEmpty(isComplianceWithgbt) && (1 == isComplianceWithgbt || 0 == isComplianceWithgbt)) {
				CylDictEnum cylDictEnum = CylDictEnum.getEnum(isComplianceWithgbt, CylDictEnum.isComplianceWithGBT_0.getKey());
				if (cylDictEnum != null) {
					e.setIsComplianceWithgbt(cylDictEnum.getSeqNbr());
				}
			}

			Integer haveStillPressure = e.getHaveStillPressure();
			if (!ObjectUtil.isEmpty(haveStillPressure) && (1 == haveStillPressure || 0 == haveStillPressure)) {
				CylDictEnum cylDictEnum = CylDictEnum.getEnum(haveStillPressure, CylDictEnum.haveStillPressure_0.getKey());
				if (cylDictEnum != null) {
					e.setHaveStillPressure(cylDictEnum.getSeqNbr());
				}
			}

			Integer isComplete = e.getIsComplete();
			if (!ObjectUtil.isEmpty(isComplete) && (1 == isComplete || 0 == isComplete)) {
				CylDictEnum cylDictEnum = CylDictEnum.getEnum(isComplete, CylDictEnum.isComplete_0.getKey());
				if (cylDictEnum != null) {
					e.setIsComplete(cylDictEnum.getSeqNbr());
				}
			}

			Integer haveSecurityDocuments = e.getHaveSecurityDocuments();
			if (!ObjectUtil.isEmpty(haveSecurityDocuments) && (1 == haveSecurityDocuments || 0 == haveSecurityDocuments)) {
				CylDictEnum cylDictEnum = CylDictEnum.getEnum(haveSecurityDocuments, CylDictEnum.SecurityDocuments_0.getKey());
				if (cylDictEnum != null) {
					e.setHaveSecurityDocuments(cylDictEnum.getSeqNbr());
				}
			}

		});
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		cylCylinderFillingCheckMapper.saveAndBatchInsert(data);
		stopWatch.stop();
		System.out.println("插入时间："+ stopWatch.getTotalTimeSeconds());
		StopWatch stopWatch1 = new StopWatch();
		stopWatch1.start();
		sourceFillingCheckServiceImpl.updataSyncFilling(ids);
		stopWatch1.stop();
		System.out.println("更新时间："+ stopWatch1.getTotalTimeSeconds());

	}


	@Scheduled(cron = "0 0 1 * * ?")
	@SchedulerLock(name = "fillingRecordSync", lockAtMostFor = "PT10H", lockAtLeastFor = "PT60M")
	public String fillingRecordSync() {
//		StopWatch stopWatch = new StopWatch();
//		stopWatch.start();
//		Long count = sourceFillingCheckServiceImpl.fillingRecordSync();
//		stopWatch.stop();
//		System.out.println("统计总数耗时："+ stopWatch.getTotalTimeSeconds());
		return fillingRecordMessage();
	}

	@Transactional
	String fillingRecordMessage(){
//		Long times = 0L;
//		if (count != 0) {
//			times = count / 1000;
//			Long last = count % 1000;
//			if (last > 0) {
//				times++;
//			}
//		} else {
//			return "no data sync";
//		}
//		times = 2L;
//		for (int i = 0; i < times; i++) {
			StopWatch stopWatch = new StopWatch();
			stopWatch.start();
			List<CylinderFillingRecord> cylinderFillingRecords = sourceFillingCheckServiceImpl.fillingRecordSyncRecords();
			stopWatch.stop();
			System.out.println("查询1000条记录耗时："+ stopWatch.getTotalTimeSeconds());
			if (!ObjectUtils.isEmpty(cylinderFillingRecords)){
				cylinderFillingRecords.forEach(item -> {
					item.setAbnormal(item.getAbnormal() == 1 ? 3140 : 3139);
					item.setSyncState(3);
				});
//			List<String> appIds = cylinderFillingRecords.stream().map(CylinderFillingRecord::getAppId).collect(Collectors.toList());
//			List<String> records = cylinderFillingRecords.stream().map(CylinderFillingRecord::getFillingRecordId).collect(Collectors.toList());
				List<Long> ids = cylinderFillingRecords.stream().map(CylinderFillingRecord::getSequenceNbr).collect(Collectors.toList());
				StopWatch stopWatch1 = new StopWatch();
				stopWatch1.start();
				cylCylinderFillingCheckMapper.batchInsertOrUpdate(cylinderFillingRecords);
				stopWatch1.stop();
				System.out.println("插入数据耗时："+ stopWatch1.getTotalTimeSeconds());
				StopWatch stopWatch2 = new StopWatch();
				stopWatch2.start();
				sourceFillingCheckServiceImpl.updateSyncState(ids);
				stopWatch2.stop();
				System.out.println("修改数据耗时："+ stopWatch2.getTotalTimeSeconds());
				fillingRecordMessage();
			}
		return "ok";
	}
}
