package com.utic.center.utic.stat.server.service;

import com.utic.center.common.annotation.ProcessingElapsed;
import com.utic.center.common.service.AbstractProcessService;
import com.utic.center.common.utils.LogUtils;
import com.utic.center.utic.stat.server.dao.repository.UticStat05MinFltrRepository;
import com.utic.center.utic.stat.server.dao.repository.UticStatPatternRepository;
import com.utic.center.utic.stat.server.dto.CodeValueDto;
import com.utic.center.utic.stat.server.dto.HolidayDto;
import com.utic.center.utic.stat.server.repository.ApplicationRepository;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Getter
@RequiredArgsConstructor
@Service
public class UticStat05MinFltrService implements AbstractProcessService {

    private final UticStatParamService paramService;
    private final UticStat05MinFltrRepository fltrRepo;
    private final UticStatPatternRepository patternRepo;

    @ProcessingElapsed(type="05MIN", name="정주기 5분 링크필터 생성", starting = false)
    @Override
    public boolean processing() {

        String past25Min = ApplicationRepository.past25Min;
        String past30Min = ApplicationRepository.past30Min;

        log.info("[INF] {}: past25Min[{}], past30Min[{}]", LogUtils.elapsedLog("05분 링크필터"), past25Min, past30Min);

        CodeValueDto code0 = this.paramService.getCodeValue(UticStatParamService.CodeValueKey.CODE_00);
        CodeValueDto code1 = this.paramService.getCodeValue(UticStatParamService.CodeValueKey.CODE_01);
        CodeValueDto code2 = this.paramService.getCodeValue(UticStatParamService.CodeValueKey.CODE_02);
        CodeValueDto code5 = this.paramService.getCodeValue(UticStatParamService.CodeValueKey.CODE_05);
        CodeValueDto code6 = this.paramService.getCodeValue(UticStatParamService.CodeValueKey.CODE_06);
        CodeValueDto code7 = this.paramService.getCodeValue(UticStatParamService.CodeValueKey.CODE_07);
        CodeValueDto code8 = this.paramService.getCodeValue(UticStatParamService.CodeValueKey.CODE_08);
        CodeValueDto code9 = this.paramService.getCodeValue(UticStatParamService.CodeValueKey.CODE_09);

        // STAT_LOCAL 데이터 입력
        // STAT_LOCAL 초기화
        this.fltrRepo.truncateStatLocal();

        // 수도권 지역센터 연계 교통정보 입력
        this.fltrRepo.insertStatLocalRcvLinkTraffic(past25Min, past30Min);

        // LINK_FILTER 데이터 입력
        // LINK_FILTER 초기화
        this.fltrRepo.truncateLinkFilter();

        // LINK_FILTER 표준편차 입력
//        log.info("[INF] {}: {}, {}", LogUtils.elapsedLog("LINK_FILTER(표준편차 필터링)"), code0, code5);
        this.fltrRepo.insertLinkFilterStdDev(past25Min, code0.getCodeValue(), code5.getCodeValue());

        // 패턴 최대최소값 UPDATE
        if ("Y".equals(code1.getCodeValue())) {
            log.info("[INF] {}: LINK_FILTER 통계 최대최소 필터링 사용", LogUtils.elapsedLog("LINK_FILTER(패턴 필터링)"));
            HolidayDto holiday = this.patternRepo.findHoliday(past25Min);
            if (holiday != null) {
                runLinkFilterPatternUpdate(past25Min, holiday, code2);
            }
        }
        else {
            log.info("[INF] {}: LINK_FILTER 통계 최대최소 필터링 사용안함", LogUtils.elapsedLog("LINK_FILTER(패턴 필터링)"));
        }

        // 도로등급별 최대최소값 UPDATE
        // LINK_FILTER 도로등급 입력
        this.fltrRepo.updateLinkFilterRoadRank();

        // LINK_FILTER 도로등급별 최대최소 속도 입력
        if ("Y".equals(code2.getCodeValue())) {
            log.info("[INF] {}: LINK_FILTER 도로등급 최대최소 필터링 사용", LogUtils.elapsedLog("LINK_FILTER(도로등급 필터링)"));
            this.fltrRepo.updateLinkFilterMinMax(
                    code6.getMinValue(), code6.getMaxValue(),
                    code7.getMinValue(), code7.getMaxValue(),
                    code8.getMinValue(), code8.getMaxValue(),
                    code9.getMinValue(), code9.getMaxValue());
        }
        else {
            log.info("[INF] {}: LINK_FILTER 도로등급 최대최소 필터링 사용안함", LogUtils.elapsedLog("LINK_FILTER(도로등급 필터링)"));
        }

        // 전국 이력저장
        this.fltrRepo.insertStatLocalLog();

        return true;
    }

    private void runLinkFilterPatternUpdate(String prcsPast25Min, HolidayDto holiday, CodeValueDto codeValue2) {
        String logTable, fromTable;
        if (holiday.getHCnt() > 0) {
            logTable = "(휴일)PATN_HOLIDAY";
            fromTable = "PATN_HOLIDAY";
        }
        else {
            switch(holiday.getWDay()) {
                case 1: // 일요일 패턴
                    logTable = "(일요일)PATN_SUN";
                    fromTable = "PATN_SUN";
                    break;
                case 2: // 월요일 패턴
                    logTable = "(월요일)PATN_MON";
                    fromTable = "PATN_MON";
                    break;
                case 6: // 금요일 패턴
                    logTable = "(금요일)PATN_FRI";
                    fromTable = "PATN_FRI";
                    break;
                case 7: // 토요일 패턴
                    logTable = "(토요일)PATN_SAT";
                    fromTable = "PATN_SAT";
                    break;
                default: // 평일 패턴(3,4,5)
                    logTable = "(평일)PATN_WEEK";
                    fromTable = "PATN_WEEK";
                    break;
            }
        }

        this.fltrRepo.updateLinkFilterPattern(fromTable, prcsPast25Min, codeValue2.getMinValue(), codeValue2.getMaxValue(), logTable);
        this.fltrRepo.updateLinkFilterSpeedNull();
    }

}
