package com.its.op.service.its.dashboard;

import com.its.op.dao.mapper.its.dashboard.DashboardMapper;
import com.its.op.dao.repository.its.ifsc.TbIfscRepository;
import com.its.op.dto.its.dashboard.CmtrGradCountSttsDto;
import com.its.op.dto.its.dashboard.TrafPrcnStatDto;
import com.its.op.service.its.TrafPrcsTime;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@RequiredArgsConstructor
@Service
public class DashboardService {

    private final DashboardMapper mapper;
    private final TbIfscRepository repo;
    private final TrafPrcsTime prcsTime;

    protected void checkGradeRate(List<CmtrGradCountSttsDto> result) {
        result.forEach(obj -> {
            float total = obj.getLtc0() + obj.getLtc1() + obj.getLtc2() + obj.getLtc3();
            obj.setTotal((int)total);
            if (total == 0.0) {
                obj.setRateLtc1(0.0);
                obj.setRateLtc2(0.0);
                obj.setRateLtc3(0.0);
                obj.setRateLtc0(0.0);
            }
            else {
                double ltc0 = Double.parseDouble(String.format("%.1f", obj.getLtc0() / total * 100.0));
                double ltc1 = Double.parseDouble(String.format("%.1f", obj.getLtc1() / total * 100.0));
                double ltc2 = Double.parseDouble(String.format("%.1f", obj.getLtc2() / total * 100.0));
                double ltc3 = Double.parseDouble(String.format("%.1f", obj.getLtc3() / total * 100.0));

                double fSum = ltc0 + ltc1 + ltc2 + ltc3;
                double[] rates = { ltc0, ltc1, ltc2, ltc3 };
                if (fSum > 100.0) {
                    for (int ii = 0; ii < 4; ii++) {
                        if (rates[ii] > 0.0) {
                            rates[ii] -= (fSum - 100.0);
                            break;
                        }
                    }
                }
                if (fSum < 100.0) {
                    for (int ii = 0; ii < 4; ii++) {
                        if (rates[ii] > 0.0) {
                            rates[ii] += (100.0 - fSum);
                            break;
                        }
                    }
                }
                obj.setRateLtc0(rates[0]);
                obj.setRateLtc1(rates[1]);
                obj.setRateLtc2(rates[2]);
                obj.setRateLtc3(rates[3]);
            }
        });
    }

    /**
     * 소틍등급상태 링크
     * @return
     */
    @Transactional(readOnly = true)
    public List<CmtrGradCountSttsDto> findAllCmtrGradCountSttsLink() {
        List<CmtrGradCountSttsDto> result = this.mapper.findAllCmtrGradCountSttsLink();
        checkGradeRate(result);
        return result;
    }

    /**
     * 소틍등급상태 정보제공구간
     * @return
     */
    @Transactional(readOnly = true)
    public List<CmtrGradCountSttsDto> findAllCmtrGradCountSttsIfsc() {
        List<CmtrGradCountSttsDto> result = this.mapper.findAllCmtrGradCountSttsIfsc();
        checkGradeRate(result);
        return result;
    }

    /**
     * 소틍등급상태 도로
     * @return
     */
    @Transactional(readOnly = true)
    public List<CmtrGradCountSttsDto> findAllCmtrGradCountSttsRoad() {
        List<CmtrGradCountSttsDto> result = this.mapper.findAllCmtrGradCountSttsRoad();
        checkGradeRate(result);
        return result;
    }

    /**
     * 정보제공구간소통등급현황조회
     * @return
     */
    @Transactional(readOnly = true)
    public List<TrafPrcnStatDto> findAllTrafPrcnStatAll() {
        List<TrafPrcnStatDto> result = new ArrayList<>();
        Integer total = this.repo.findAllCount();
        TrafPrcnStatDto dto0 = TrafPrcnStatDto.initBuilder(0, total);
        TrafPrcnStatDto dto1 = TrafPrcnStatDto.initBuilder(1, total);
        TrafPrcnStatDto dto2 = TrafPrcnStatDto.initBuilder(2, total);
        result.add(0, dto0);
        result.add(1, dto1);
        result.add(2, dto2);

        this.prcsTime.init();
        String prcs05M = this.prcsTime.getPrcsFiveMin().substring(8, 12);
        String prcs10M = this.prcsTime.getPrcs10Min().substring(8, 12);
        String prcnTM = prcs05M;
        int[] ltc00 = { 0, 0, 0};
        int[] ltc01 = { 0, 0, 0};
        int[] ltc02 = { 0, 0, 0};

        int[] ltc10 = { 0, 0, 0};
        int[] ltc11 = { 0, 0, 0};
        int[] ltc12 = { 0, 0, 0};

        List<TrafPrcnStatDto.TrafPrcnStatVo> data = this.mapper.findAllTrafPrcnStatAll();
        for(TrafPrcnStatDto.TrafPrcnStatVo obj : data) {
            TrafPrcnStatDto dto = result.get(obj.getPRCN_TYPE());
            if (dto != null) {
                dto.getTraf().add(TrafPrcnStatDto.TrafPrcnStatVo.builder()
                        .PRCN_TYPE(obj.getPRCN_TYPE())
                        .PRCN_TM(obj.getPRCN_TM())
                        .LTC1(obj.getLTC1())
                        .LTC2(obj.getLTC2())
                        .LTC3(obj.getLTC3())
                        .LTC0(Math.max(0, total-obj.getLTC1()-obj.getLTC2()-obj.getLTC3()))
                        .build());

                if (prcs05M.equals(obj.getPRCN_TM())) {
                    if (obj.getPRCN_TYPE() == 0) {
                        ltc00[0] = obj.getLTC1();
                        ltc00[1] = obj.getLTC2();
                        ltc00[2] = obj.getLTC3();
                    } else if (obj.getPRCN_TYPE() == 1) {
                        ltc01[0] = obj.getLTC1();
                        ltc01[1] = obj.getLTC2();
                        ltc01[2] = obj.getLTC3();
                    } else if (obj.getPRCN_TYPE() == 2) {
                        ltc02[0] = obj.getLTC1();
                        ltc02[1] = obj.getLTC2();
                        ltc02[2] = obj.getLTC3();
                    }
                }
                if (prcs10M.equals(obj.getPRCN_TM())) {
                    if (obj.getPRCN_TYPE() == 0) {
                        ltc10[0] = obj.getLTC1();
                        ltc10[1] = obj.getLTC2();
                        ltc10[2] = obj.getLTC3();
                    } else if (obj.getPRCN_TYPE() == 1) {
                        ltc11[0] = obj.getLTC1();
                        ltc11[1] = obj.getLTC2();
                        ltc11[2] = obj.getLTC3();
                    } else if (obj.getPRCN_TYPE() == 2) {
                        ltc12[0] = obj.getLTC1();
                        ltc12[1] = obj.getLTC2();
                        ltc12[2] = obj.getLTC3();
                    }
                }
            }
        }

        /**
         * 가공시각이 엇나갔을 경우 대비(쓸데 없는 짓)
         */
//        log.error("{}, {}, {}, {}", ltc00[0], ltc00[1], ltc00[2], prcs05M);
//        log.error("{}, {}, {}, {}", ltc10[0], ltc10[1], ltc10[2], prcs10M);
        if (ltc00[0] == 0 && ltc00[1] == 0 && ltc00[2] == 0) {
            if (ltc10[0] != 0 || ltc10[1] != 0 || ltc10[2] != 0) {
                for (int ii = 0; ii < 3; ii++) {
                    ltc00[ii] = ltc10[ii];
                    ltc01[ii] = ltc11[ii];
                    ltc02[ii] = ltc12[ii];
                }
                prcnTM = prcs10M;
            }
        }
//        log.error("{}, {}, {}, {}", ltc00[0], ltc00[1], ltc00[2], prcnTM);
//        log.error("{}, {}, {}, {}", ltc10[0], ltc10[1], ltc10[2], prcnTM);

        List<TrafPrcnStatDto.TrafClctStatVo> clct = this.mapper.findAllTrafClctStatAll();
        for(TrafPrcnStatDto.TrafClctStatVo obj : clct) {
            dto0.getClct().add(obj);
            if (prcnTM.equals(obj.getPRCN_TM())) {
                dto0.setOper01(obj.getOper01());
                dto0.setUtis01(obj.getUtis01());
                dto0.setUtis02(obj.getUtis02());
                dto0.setVds01(obj.getVds01());
                dto0.setDsrc01(obj.getDsrc01());
                dto0.setGits01(obj.getGits01());
                dto0.setMoct01(obj.getMoct01());
            }
        }
        dto0.calcGradeRate(prcnTM, ltc00[0], ltc00[1], ltc00[2]);
        dto1.calcGradeRate(prcnTM, ltc01[0], ltc01[1], ltc01[2]);
        dto2.calcGradeRate(prcnTM, ltc02[0], ltc02[1], ltc02[2]);

        return result;
    }

}
