package com.its.api.its.service.unit;

import com.its.api.its.global.CodeManager;
import com.its.api.its.model.dto.unit.TbUnitSystDto;
import com.its.api.its.model.dto.unit.TbUnitSystSttsHsHistDto;
import com.its.api.its.model.dto.unit.TbUnitSystSttsHsStatDto;
import com.its.api.its.model.dto.unit.TbUnitSystSttsHsStatInf;
import com.its.api.its.model.entity.unit.TbUnitSystSttsHs;
import com.its.api.its.repository.unit.TbUnitSystSttsHsRepository;
import com.its.api.utils.SysUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@RequiredArgsConstructor
@Service
public class TbUnitSystSttsHsService {

    private final TbUnitSystSttsHsRepository repo;
    private final TbUnitSystService unitService;

    /**
     * 프로세스 상태 이력 조회
     * @param systId
     * @param crtnDt
     * @return
     */
    public List<TbUnitSystSttsHsHistDto> findAllHistByDateRange(String systId, String crtnDt) {
        String fromDt = crtnDt + "000000";
        String toDt = crtnDt + "235959";

        List<TbUnitSystSttsHsHistDto> result = new ArrayList<>();
        int idx = 1;
        for (int ii = 0; ii < 24; ii++) {
            for (int jj = 0; jj < 12; jj++) {
                String HHMM = String.format("%02d:%02d", ii, jj*5);
                TbUnitSystSttsHsHistDto info = new TbUnitSystSttsHsHistDto(idx++, HHMM, systId);
                result.add(info);
            }
        }

        List<TbUnitSystSttsHs> data = this.repo.findAllHistByDateRange(systId, fromDt, toDt);
        for (TbUnitSystSttsHs obj : data) {
            try {
                String HH = obj.getCrtnDt().substring(8, 10);
                String MI = obj.getCrtnDt().substring(10, 12);
                int crtnIdx = ((Integer.parseInt(HH) * 60 + Integer.parseInt(MI)) / 5);
                result.get(crtnIdx).setCrtnDt((obj.getCrtnDt()));
                result.get(crtnIdx).setSystSttsCd(obj.getSystSttsCd());
                result.get(crtnIdx).setSystSttsDesc(CodeManager.getCodeDesc(CodeManager.SYST_STTS_CD, obj.getSystSttsCd()));
            }
            catch (Exception e) {}
        }

        return result;
    }

    /**
     * 프로세스 상태 통계 조회
     * @param fromDt
     * @param toDt
     * @return
     */
    public List<TbUnitSystSttsHsStatDto> findAllStatByDateRange(String fromDt, String toDt) {

        int gapMin = SysUtils.gapTime(fromDt, toDt, Calendar.MINUTE);
        int stsTot = (gapMin+1)/5;

        Map<String, TbUnitSystSttsHsStatDto> unitMap = new HashMap<>();
        List<TbUnitSystDto> unit = this.unitService.findAllList();
        if (unit != null) {
            unit.forEach(obj -> {
                unitMap.put(obj.getSystId(),
                        TbUnitSystSttsHsStatDto.builder()
                                .systId(obj.getSystId())
                                .systNm(obj.getSystNm())
                                .stsTot(stsTot)
                                .cntSps0(0)
                                .cntSps1(0)
                                .cntSps2(0)
                                .cntSps3(0)
                                .cntSps4(0)
                                .runRate(0.)
                                .build());
            });
        }

        List<TbUnitSystSttsHsStatInf> statList = this.repo.findAllStatByDateRange(fromDt, toDt);
        if (statList != null) {
            statList.forEach(stat -> {
                TbUnitSystSttsHsStatDto unitDto = unitMap.get(stat.getSystId());
                log.error("{}, {}, {}", stat.getSystId(), stat.getSystSttsCd(), stat.getSttsCnt());
                if (unitDto == null) {
                    return;
                }

                if (("SPS0").equals(stat.getSystSttsCd())) {
                    unitDto.setCntSps0(stat.getSttsCnt());
                }
                else if (("SPS1").equals(stat.getSystSttsCd())) {
                    unitDto.setCntSps1(stat.getSttsCnt());
                }
                else if (("SPS2").equals(stat.getSystSttsCd())) {
                    unitDto.setCntSps2(stat.getSttsCnt());
                }
                else if (("SPS3").equals(stat.getSystSttsCd())) {
                    unitDto.setCntSps3(stat.getSttsCnt());
                }
                else if (("SPS4").equals(stat.getSystSttsCd())) {
                    unitDto.setCntSps4(stat.getSttsCnt());
                }
            });
        }
        List<TbUnitSystSttsHsStatDto> result = new ArrayList<>(unitMap.values());
        result.forEach(obj -> {
            // 가동율 계산
            obj.setRunRate(obj.getStsTot() > 0 ? (double)obj.getCntSps1() / (double)obj.getStsTot() * (double)100 : 0);
            if (obj.getRunRate() > 100.) {
                // 100% 가 넘는 경우 100% 맞춰주기 위해, 5분주기로 저장하게 돼 있으나 더 짧은 주기로 저장하기 때문에
                obj.setRunRate(100.);
                obj.setCntSps1(obj.getStsTot());
            }
        });
        return result;
    }
}
