package net.vtstar.zhongtong.avi.monitoring.job;

import lombok.extern.slf4j.Slf4j;
import net.vtstar.scada.base.gather.job.GatherJob;
import net.vtstar.zhongtong.avi.equipment.domain.PaintshopArea;
import net.vtstar.zhongtong.avi.equipment.domain.PaintshopStation;
import net.vtstar.zhongtong.avi.equipment.service.RunRecordService;
import net.vtstar.zhongtong.avi.global.constant.Constant;
import net.vtstar.zhongtong.avi.monitoring.domain.Skid;
import net.vtstar.zhongtong.avi.monitoring.domain.Warning;
import net.vtstar.zhongtong.avi.monitoring.domain.enums.BusType;
import net.vtstar.zhongtong.avi.monitoring.domain.enums.DateType;
import net.vtstar.zhongtong.avi.monitoring.domain.enums.StationState;
import net.vtstar.zhongtong.avi.monitoring.domain.vo.CarStatisticsVO;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.cache.Cache;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class RedisToCacheJob extends GatherJob {

    public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy:MM:dd");
    @Resource(name = "redisTemplate")
    private ValueOperations valueOperations;
    @Resource(name = "redisTemplate")
    private RedisTemplate redisTemplate;
    @Resource(name = "webStationCache")
    private Cache webStationCache;
    @Resource(name = "warningCache")
    private Cache warningCache;
    @Autowired
    private RunRecordService runRecordService;

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        log.info("______________");
        log.info("RedisToCacheJob start");


        //处理报警
        Set<String> warningKeys = redisTemplate.keys(Constant.WARNING_PREFIX + "*");

        Map<String, List<String>> warningKeyMap = warningKeys.stream().collect(Collectors.groupingBy(a -> a.split(":")[1]));
        List<Warning> list = new ArrayList<>();
        for (Map.Entry<String, List<String>> warningKey : warningKeyMap.entrySet()) {
            String key = warningKey.getKey();
            List<Warning> warnings = new ArrayList<>();
            List<String> value = warningKey.getValue();
            for (String s : value) {
                Integer state = (Integer) valueOperations.get(s);
                if (state == 1) {
                    String[] split = s.split(":");
                    String warningCode = split[2];
                    Warning warning = warningCache.get(warningCode, Warning.class);
                    warning.setEquipName(warning.getName().split(" ")[0]);
                    warning.setTime(new SimpleDateFormat("HH:mm").format(new Date()));
                    warnings.add(warning);
                }
            }
            warningCache.put(Constant.LED_PREFIX + key, warnings);
            list.addAll(warnings);
        }
        log.debug("当前检测到异常报警: {}条", list.size());
        warningCache.put(Constant.LED_PREFIX + "ALL", list);
        runRecordService.refreshWarning(list);
        //处理进出车信息
        Set<String> keys = redisTemplate.keys(Constant.STATION_PREFIX + "*");
        List<PaintshopStation> stations = new ArrayList<>();

        for (String key : keys) {
            PaintshopStation station = (PaintshopStation) valueOperations.get(key);
            stations.add(station);
        }
        Map<Long, List<PaintshopStation>> listMap = stations.stream().collect(Collectors.groupingBy(PaintshopStation::getAreaId));

        Calendar instance = Calendar.getInstance();
        String today = dateFormat.format(instance.getTime());
        instance.add(Calendar.DATE, -1);
        String previous = dateFormat.format(instance.getTime());

        List<CarStatisticsVO> vos = new ArrayList<>();
        addStatistics(today, vos, "0", DateType.TODAY);
        addStatistics(previous, vos, "0", DateType.YESTERDAY);

        //处理工位信息
        List<PaintshopArea> areas = webStationCache.get("stationList", ArrayList.class);
        for (PaintshopArea area : areas) {
            Long id = area.getId();
            List<PaintshopStation> stationList = listMap.get(id);
            Map<String, PaintshopStation> collect = stationList.stream().collect(Collectors.toMap(PaintshopStation::getCode, sta -> sta, (key1, key2) -> key1));
            for (Map.Entry<String, PaintshopStation> entry : collect.entrySet()) {
                PaintshopStation value = entry.getValue();
                Skid skid = value.getSkid();
                if (null != skid) {
                    value.setState(StationState.USE);
                    value.setBusNo(skid.getBusNo());
                    value.setWorkOrderNo(skid.getWorkOrderNo());
                    value.setBusType(skid.getBusType());
                }
            }

            area.setStationMap(collect);
            addStatistics(today, vos, area.getCode(), DateType.TODAY);
        }
        webStationCache.put("busSta", vos);
        webStationCache.put("stationList", areas);
    }

    private void addStatistics(String today, List<CarStatisticsVO> vos, String code, DateType dateType) {

        Random r = new Random();
        int i = r.nextInt(20);

        CarStatisticsVO vo = new CarStatisticsVO();
        vo.setAreaNo(code);
        Integer todaySize = (Integer) valueOperations.get(Constant.BUS_SIZE_IN + code + ":" + today);
        vo.setDateType(dateType);
        if (null == todaySize) {
//            if (code.equals("0")) {
//                vo.setSize(BigDecimal.valueOf(40));
//            } else {
            vo.setSize(BigDecimal.ZERO);
//                vo.setSize(BigDecimal.valueOf(10).add(new BigDecimal(r.nextInt(20))));
//            }
        } else {
            vo.setSize(BigDecimal.valueOf(todaySize));
        }
        vo.setBusType(BusType.IN);

        CarStatisticsVO out = new CarStatisticsVO();
        out.setAreaNo(code);
        Integer todayOut = (Integer) valueOperations.get(Constant.BUS_SIZE_OUT + code + ":" + today);
        out.setDateType(dateType);
        if (null == todayOut) {
//            if (code.equals("0")) {
//                out.setSize(BigDecimal.valueOf(40));
//            } else {
            out.setSize(BigDecimal.ZERO);
//                out.setSize(BigDecimal.valueOf(10).add(new BigDecimal(r.nextInt(20))));
//            }
        } else {
            out.setSize(BigDecimal.valueOf(todayOut));
        }
        out.setBusType(BusType.OUT);

        vos.add(vo);
        vos.add(out);
    }
}
