package com.its.vms.service;

import com.its.app.utils.Elapsed;
import com.its.vms.dao.mapper.VmsIfscMapper;
import com.its.vms.dto.TbVmsIfscTrafDto;
import com.its.vms.dto.TbVmsRltnIfscDto;
import com.its.vms.dto.TbVmsCtlrDto;
import com.its.vms.entity.TbVmsIfscTraf;
import com.its.vms.entity.TbVmsRltnIfsc;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
@Service
@RequiredArgsConstructor
public class VmsIfscService {

    private final VmsIfscMapper mapper;
    private final AppRepositoryService repoService;

    private final ConcurrentHashMap<Long, TbVmsIfscTrafDto> dataMap = new ConcurrentHashMap<>();

    public TbVmsIfscTrafDto find(Long vmsIfscId) {
        return this.dataMap.get(vmsIfscId);
    }

    public void loadDb() {
        loadVmsRltnIfsc();
        loadVmsIfscTrafInfo();
    }

    public void loadVmsRltnIfsc() {
        Elapsed elapsed = new Elapsed();
        this.repoService.getCtlrMap().forEach((nmbr, obj) -> {
            obj.getRltnIfscMap().forEach((ifscId, ifsc) -> {
                ifsc.setUsed(false);
            });
        });

        try {
            List<TbVmsRltnIfsc> infoList  = this.mapper.selectVmsRltnIfsc();
            log.info("VmsIfscService.loadVmsRltnIfsc: {} EA", infoList.size());
            infoList.forEach(data -> {
                TbVmsCtlrDto vmsObj = this.repoService.getCtrlMap(data.getVmsCtlrNmbr());
                if (vmsObj != null) {
                    TbVmsRltnIfscDto rltnIfsc = vmsObj.getRltnIfscMap().get(data.getVmsIfscId());
                    if (rltnIfsc == null) {
                        rltnIfsc = data.toDto();
                        vmsObj.getRltnIfscMap().put(data.getVmsIfscId(), rltnIfsc);
                    }
                    rltnIfsc.setUsed(true);
                    if (this.repoService.isStaticCycle()) {
                        // 정주기 데이터 조회 인 경우
                        // 정체판정 정보가 변경되었으면 정체판정횟수를 초기화한다.
                        boolean cngstCnfmYn = "Y".equals(data.getCngstCnfmYn());
                        Integer cngstCnfmSped = data.getCngstCnfmSped();
                        if (rltnIfsc.isCngstCnfmYn() != cngstCnfmYn || !Objects.equals(rltnIfsc.getCngstCnfmSped(), cngstCnfmSped)) {
                            rltnIfsc.setCngstCnt(0);
                        }
                    }
                    data.rltnIfscCopy(rltnIfsc);
                }
                else {
                    log.error("VmsIfscService.loadVmsRltnIfsc: Not Found VMS {}, IFSC ID {}.", data.getVmsCtlrNmbr(), data.getVmsIfscId());
                }
            });
        }
        catch (Exception e) {
            log.error("VmsIfscService.loadVmsRltnIfsc: {}.", e.toString());
        }
        log.info("VmsIfscService.loadVmsRltnIfsc: {} ms.", elapsed.milliSeconds());
    }

    public void loadVmsIfscTrafInfo() {
        Elapsed elapsed = new Elapsed();
        this.dataMap.forEach((ifscId, ifsc) -> {
            ifsc.setCmtrGradCd(0);
            ifsc.setSped(0);
            ifsc.setTrvlHh(0);
        });

        try {
            List<TbVmsIfscTraf> infoList  = this.mapper.selectVmsIfscTrafInfo();
            log.info("VmsIfscService.loadVmsIfscTrafInfo: {} EA", infoList.size());
            infoList.forEach(data -> {
                TbVmsIfscTrafDto obj = data.toDto();
                TbVmsIfscTrafDto oldObj = this.dataMap.get(data.getVmsIfscId());
                if (oldObj != null) {
                    obj.setCngstCnt(oldObj.getCngstCnt());
                    obj.setCngstDt(oldObj.getCngstDt());
                }
                if (obj.getCmtrGradCd() != 0 && obj.getTrvlHh() == 0) {
                    obj.setTrvlHh(1);
                }
                this.dataMap.put(data.getVmsIfscId(), obj);
            });
        }
        catch (Exception e) {
            log.error("VmsIfscService.loadVmsIfscTrafInfo: {}.", e.toString());
        }
        log.info("VmsIfscService.loadVmsIfscTrafInfo: {} ms.", elapsed.milliSeconds());
    }

}
