package com.its.op.service.its.common;

import com.its.op.dto.its.common.CongestTrafficDto;
import com.its.op.dto.its.common.DetlTrafIfscDto;
import com.its.op.dto.its.common.DetlTrafLinkDto;
import com.its.op.dto.its.common.DetlTrafRoadDto;
import com.its.op.dto.its.ifsc.TbIfscDto;
import com.its.op.dto.its.link.TbLinkDto;
import com.its.op.dto.its.road.TbRoadDto;
import com.its.op.dao.mapper.its.common.CommonMapper;
import com.its.op.service.its.ifsc.TbIfscService;
import com.its.op.service.its.link.TbLinkService;
import com.its.op.service.its.road.TbRoadService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@RequiredArgsConstructor
@Service
public class CommonService {

    private final CommonMapper repo;
    private final TbLinkService linkService;
    private final TbIfscService ifscService;
    private final TbRoadService roadService;

    /**
     * 지정체구간 소통정보 조회
     * @return
     */
    public List<CongestTrafficDto> findAllCongestTraffic() {
        List<CongestTrafficDto> result = this.repo.findAllCongestTraffic();
        return result;
    }

    /**
     * 링크 소통정보 상세 조회
     * @param linkId
     * @return
     */
    public DetlTrafLinkDto findAllDetailTrafficLink(Long linkId) throws NoSuchElementException {
        TbLinkDto dto = null;
        try {
            dto = this.linkService.findById(linkId);
        }
        catch (NoSuchElementException e) {
            log.error("findAllDetailTrafficLink: Not Fond, {}", linkId);
            throw e;
        }
        DetlTrafLinkDto result = DetlTrafLinkDto.builder()
                .linkId(linkId)
                .levl(1)
                .sectLngt(dto.getLinkLeng())
                .fNodeId(dto.getFNodeId())
                .fNodeNm(dto.getFromNodeInfo())
                .tNodeId(dto.getTNodeId())
                .tNodeNm(dto.getToNodeInfo())
                .roadName(dto.getRoadName())
                .sectGradCd(dto.getSectGradCd())
                //.traf(new DetlTrafLinkDto.DetlTrafLinkInfo())
                .trafHs(new ArrayList<>())
                .build();

        Map<String, Long> param = new HashMap<>();
        param.put("ID", linkId);
        DetlTrafLinkDto.DetlTrafLinkInfo traf = this.repo.findAllDetlTrafLink(param);
        if (traf != null) {
            result.setTraf(traf);
        } else {
            result.setTraf(DetlTrafLinkDto.DetlTrafLinkInfo.builder().build());
        }

        List<DetlTrafLinkDto.DetlTrafLinkInfo> trafHs = this.repo.findAllDetlTrafLinkHs(param);
        result.setTrafHs(trafHs);

        return result;
    }

    /**
     * 정보제공구간 소통정보 상세 조회
     * @param ifscId
     * @return
     */
    public DetlTrafIfscDto findAllDetailTrafficIfsc(Long ifscId) {
        TbIfscDto dto = this.ifscService.findById(ifscId);
        DetlTrafIfscDto result = DetlTrafIfscDto.builder()
                .ifscId(ifscId)
                .levl(2)
                .sectLngt(dto.getSectLngt())
                .fNodeId(dto.getFNodeId())
                .fNodeNm(dto.getFromNodeInfo())
                .tNodeId(dto.getTNodeId())
                .tNodeNm(dto.getToNodeInfo())
                .roadName(dto.getIfscNm())
                .sectGradCd(dto.getSectGradCd())
                //.traf(new DetlTrafIfscDto.DetlTrafIfscInfo())
                .trafHs(new ArrayList<>())
                .build();

        Map<String, Long> param = new HashMap<>();
        param.put("ID", ifscId);
        DetlTrafIfscDto.DetlTrafIfscInfo traf = this.repo.findAllDetlTrafIfsc(param);
        if (traf != null) {
            result.setTraf(traf);
        } else {
            result.setTraf(DetlTrafIfscDto.DetlTrafIfscInfo.builder().build());
        }

        List<DetlTrafIfscDto.DetlTrafIfscInfo> trafHs = this.repo.findAllDetlTrafIfscHs(param);
        result.setTrafHs(trafHs);

        return result;
    }

    /**
     * 도로 소통정보 상세 조회
     * @param roadId
     * @return
     */
    public DetlTrafRoadDto findAllDetailTrafficRoad(Long roadId) {
        TbRoadDto dto = this.roadService.findById(roadId);
        DetlTrafRoadDto result = DetlTrafRoadDto.builder()
                .roadId(roadId)
                .levl(3)
                .sectLngt(dto.getSectLngt())
                .fNodeId(dto.getFNodeId())
                .fNodeNm(dto.getFromNodeInfo())
                .tNodeId(dto.getTNodeId())
                .tNodeNm(dto.getToNodeInfo())
                .roadName(dto.getRoadNm())
                .sectGradCd(dto.getSectGradCd())
                //.traf(new DetlTrafRoadDto.DetlTrafRoadInfo())
                .trafHs(new ArrayList<>())
                .build();

        Map<String, Long> param = new HashMap<>();
        param.put("ID", roadId);
        DetlTrafRoadDto.DetlTrafRoadInfo traf = this.repo.findAllDetlTrafRoad(param);
        if (traf != null) {
            result.setTraf(traf);
        } else {
            result.setTraf(DetlTrafRoadDto.DetlTrafRoadInfo.builder().build());
        }

        List<DetlTrafRoadDto.DetlTrafRoadInfo> trafHs = this.repo.findAllDetlTrafRoadHs(param);
        result.setTrafHs(trafHs);

        return result;
    }

    /**
     * 기상정보 조회
     * @return
     */
//    public List<WeatherInfoDto> findAllWeatherInfo() {
//        List<WeatherInfoDto> result = this.repo.findAllWeatherInfo();
//        return result;
//    }
}
