package com.its.op.service.its.vms;

import com.its.op.dao.repository.its.vms.TbVmsMonitoringRepository;
import com.its.op.dto.its.common.MonitoringInfoDto;
import com.its.op.dto.its.common.MonitoringListDto;
import com.its.op.dto.its.common.MonitoringListInf;
import com.its.op.dto.its.vms.TbVmsCtlrDto;
import com.its.op.dto.its.vms.TbVmsMonitoringDto;
import com.its.op.entity.its.vms.TbVmsMonitoring;
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 TbVmsMonitoringService {

    private final TbVmsMonitoringRepository repo;
    private final TbVmsCtlrService ctlrService;

    // 전체 데이터 조회
    @Transactional(readOnly = true)
    public List<TbVmsMonitoringDto> findAll() {
        List<TbVmsMonitoringDto> result = new ArrayList<>();
        List<TbVmsMonitoring> data = this.repo.findAll();
        for (TbVmsMonitoring entity : data) {
            result.add(entity.toDto());
        }
        return result;
    }

    // 모니터링 유형에 속한 모든 데이터 조회
    @Transactional(readOnly = true)
    public List<TbVmsMonitoringDto> findAllMonitoring(Integer monitoringType) {
        List<TbVmsMonitoringDto> result = new ArrayList<>();
        List<TbVmsMonitoring> data = this.repo.findAllMonitoring(monitoringType);
        if (data != null) {
            data.forEach(obj -> {
                result.add(obj.toDto());
            });
        }
        return result;
    }

    // 모니터링 이름으로 모니터링목록 조회
    @Transactional(readOnly = true)
    public List<TbVmsMonitoringDto> findByName(Integer monitoringType, String name) {

        //	모니터링유형(1:현시,2,시나리오,3,영상,4:모듈상태)
        List<TbVmsMonitoringDto> result = new ArrayList<>();
        List<TbVmsMonitoring> data = this.repo.findByName(monitoringType, name.trim());
        if (data != null) {
            data.forEach(obj -> {
                result.add(obj.toDto());
            });
        }
        return result;
    }

    // 정보 삭제-개별, 데이터 존재하지 않으면 Exception
    @Transactional
    public List<TbVmsMonitoringDto> deleteByName(Integer monitoringType, String name) {

        List<TbVmsMonitoringDto> result = findByName(monitoringType, name.trim());
        if (result != null) {
            this.repo.deleteByName(monitoringType, name.trim());
        }
        return result;
    }

    // 데이터 변경 또는 생성-개별(데이터가 존재하면 업데이트 없으면 신규로 생성)
    public List<TbVmsMonitoringDto> mergeInfo(Integer monitoringType, String name, TbVmsMonitoringDto.TbVmsMonitoringUpdReq req) {

        // Repository 에서 Transaction 처리를 수행

        // 이름에 해당하는 데이터 삭제
        this.repo.deleteByName(monitoringType, req.getOrgMonitoringNm().trim());

        // 이름에 해당하는 모든 데이터 저장
        for (MonitoringInfoDto reqObj : req.getInfos()) {
            TbVmsMonitoring obj = TbVmsMonitoring.builder()
                    .monitoringType(monitoringType)
                    .monitoringNm(name.trim())
                    .monitoringSeq(reqObj.getMonitoringSeq())
                    .vmsCtlrNmbr(reqObj.getCtlrNmbr())
                    .build();
            obj.setType(monitoringType);
            this.repo.save(obj);
        }

        // 저장된 데이터 리턴
        return findByName(monitoringType, name);
    }

    /**
     * 모니터링 화면 리스트 소회
     * @param monitoringType
     * @return
     */
    public List<MonitoringListDto> findAllMonitoringList(Integer monitoringType) {
        List<MonitoringListDto> result = new ArrayList<>();
        List<MonitoringListInf> data = this.repo.findAllMonitoringList(monitoringType);
        data.forEach(obj -> {
            result.add(MonitoringListDto.builder()
                    .monitoringType(monitoringType)
                    .monitoringNm(obj.getName().trim())
                    .count(obj.getCount().intValue())
                    .build());
        });

        if (result.size() == 0) {
            // 모니터링 화면이 없으면 Default 화면 목록을 만든다
            List<TbVmsCtlrDto> ctlrList = this.ctlrService.findAllList();
            int seq = 1;
            for (int ii = 0; ii < ctlrList.size(); ii++) {
                TbVmsCtlrDto obj = ctlrList.get(ii);
                TbVmsMonitoring entity = TbVmsMonitoring.builder()
                        .monitoringType(monitoringType)
                        .monitoringNm("Default")
                        .monitoringSeq(seq++)
                        .vmsCtlrNmbr(obj.getVmsCtlrNmbr())
                        .build();
                this.repo.save(entity);
                if (seq == 17) {
                    break;
                }
            }
            result.add(MonitoringListDto.builder()
                    .monitoringType(monitoringType)
                    .monitoringNm("Default")
                    .count(seq-1)
                    .build());
        }
        return result;
    }
}
