package com.its.safe.service;

import com.its.app.utils.Elapsed;
import com.its.app.utils.SysUtils;
import com.its.safe.config.ServerConfig;
import com.its.safe.dao.mapper.its.VmsMapper;
import com.its.safe.dto.its.TbLinkDto;
import com.its.safe.dto.its.TbNodeDto;
import com.its.safe.entity.its.MakeTrafParam;
import com.its.safe.entity.its.TbLink;
import com.its.safe.entity.its.TbNode;
import com.its.safe.entity.its.TbNodeRgn;
import com.its.safe.process.DbmsData;
import com.its.safe.process.DbmsDataProcess;
import com.its.safe.process.DbmsDataType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.List;

@Slf4j
//@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = {Exception.class})
public class NodeLinkService {

    private final ServerConfig config;
    private final AppRepositoryService repoService;
    private final VmsMapper mapper;
    private final DbmsDataProcess dbmsDataProcess;

    @PostConstruct
    private void init() {
        log.info("NodeService.init: Start.");
        log.info("NodeService.init: ..End.");
    }

    public void loadDb() {
        loadNodeInfo();
        loadNodeRgnInfo();
        loadLinkInfo();
    }

    public void loadNodeInfo() {
        Elapsed elapsed = new Elapsed();

        try {
            List<TbNode> infoList  = this.mapper.selectNodeAll();
            log.info("NodeService.loadNodeInfo: {} EA", infoList.size());
            for (TbNode dto : infoList) {
//                log.info("NodeService.loadNodeInfo: {}.", dto);
                TbNodeDto nodeObj = dto.toDto();
                nodeObj.setBisRadius((float)this.config.getMaxDistance());
                this.repoService.putNodeMap(nodeObj);
            }
        }
        catch (Exception e) {
            log.error("NodeService.loadNodeInfo: {}.", e.toString());
        }

        this.repoService.getNodeMap().forEach((key, obj) -> {
            log.info("NodeService.loadNodeInfo:: {}.", obj.toString());
        });
        log.info("NodeService.loadNodeInfo: {} EA, {} ms.", this.repoService.getNodeMap().size(), elapsed.milliSeconds());
    }
    public void loadNodeRgnInfo() {
        Elapsed elapsed = new Elapsed();

        try {
            List<TbNodeRgn> infoList  = this.mapper.selectNodeRgnAll();
            log.info("NodeService.loadNodeRgnInfo: {} EA", infoList.size());
            for (TbNodeRgn dto : infoList) {
                log.info("NodeService.loadNodeRgnInfo: {}.", dto);
                TbNodeDto nodeObj = this.repoService.getNodeMap().get(dto.getNodeId());
                if (nodeObj != null) {
                    if (dto.getBisRad() < 10) {
                        dto.setBisRad(10);
                    }
                    nodeObj.setBisRadius(dto.getBisRad());
                    if (dto.getBisRad() > this.config.getMaxDistance()) {
                        this.config.setMaxDistance(dto.getBisRad());
                    }
                }
            }
        }
        catch (Exception e) {
            log.error("NodeService.loadNodeRgnInfo: {}.", e.toString());
        }
        log.info("NodeService.loadNodeRgnInfo: {} EA, {} ms.", this.repoService.getNodeMap().size(), elapsed.milliSeconds());
    }

    public void loadLinkInfo() {
        Elapsed elapsed = new Elapsed();

        try {
            List<TbLink> infoList  = this.mapper.selectLinkAll();
            log.info("NodeService.loadLinkInfo: {} EA", infoList.size());
            for (TbLink dto : infoList) {
//                log.info("NodeService.loadLinkInfo: {}.", dto);
                TbLinkDto linkObj = dto.toDto();
                this.repoService.putLinkMap(linkObj);
                this.repoService.putSectMap(linkObj);
            }
        }
        catch (Exception e) {
            log.error("NodeService.loadLinkInfo: {}.", e.toString());
        }

        this.repoService.getLinkMap().forEach((key, obj) -> {
            log.info("NodeService.loadLinkInfo:: {}.", obj.toString());
        });
        log.info("NodeService.loadLinkInfo: LINK: {} EA, SECT: {} EA, {} ms.", this.repoService.getLinkMap().size(), this.repoService.getSectMap().size(), elapsed.milliSeconds());
    }

    /**
     * BIS 구간 소통정보 생성
     */
    public void makeBisLinkTraf() {
        int historyMin = this.config.getHistoryMin();
        int minSpeed = this.config.getMinSpeed();
        int maxSpeed = this.config.getMaxSpeed();
        String currentTm = SysUtils.getSysTime();

        MakeTrafParam makeParam = MakeTrafParam.builder()
                .PRCN_DT(currentTm)
                .FROM_MIN(historyMin)
                .MIN_SPEED(minSpeed)
                .MAX_SPEED(maxSpeed)
                .build();
        this.dbmsDataProcess.add(new DbmsData(DbmsDataType.DBMS_DATA_CRT_BIS_LINK_TRAF, false, makeParam));
    }

}
