package com.its.op.service.its.facility;

import com.its.op.dao.repository.its.facility.TbFcltFailActRepository;
import com.its.op.dao.repository.its.facility.TbFcltFailRepository;
import com.its.op.dto.its.common.NewIdLongDto;
import com.its.op.dto.its.facility.TbFcltFailActDto;
import com.its.op.entity.its.facility.TbFcltFailAct;
import com.its.op.entity.its.facility.TbFcltFailActKey;
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;
import java.util.NoSuchElementException;
import java.util.Optional;

@Slf4j
@RequiredArgsConstructor
@Service
public class TbFcltFailActService {

    private final TbFcltFailActRepository repo;
    private final TbFcltFailRepository failRepo;

    // 데이터 1건 조회, 없으면 exception
    private TbFcltFailAct requireOne(TbFcltFailActKey failNo) throws NoSuchElementException {
        Optional<TbFcltFailAct> info = this.repo.findById(failNo);
        if (info.isPresent()) {
            return info.get();
        }
        else {
            throw new NoSuchElementException("데이터가 존재하지 않습니다: " + failNo);
        }
    }

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

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

    // 데이터 변경 또는 생성-개별(데이터가 존재하면 업데이트 없으면 신규로 생성)
    @Transactional
    public TbFcltFailActDto mergeInfo(TbFcltFailActDto.TbFcltFailActUpdReq req) {
        TbFcltFailAct obj = req.toEntity();
        this.repo.save(obj);
        if ("ACT2".equals(req.getStepCd())) {
            this.failRepo.updateComplete(req.getFailNo(), req.getActDt());
        }
        else {
            this.failRepo.updateStepCd(req.getFailNo(), req.getStepCd());
        }
        return obj.toDto();
    }

    // 정보 삭제-개별, 데이터 존재하지 않으면 Exception
    @Transactional
    public TbFcltFailActDto deleteById(TbFcltFailActKey failNo) {
        TbFcltFailAct entity = requireOne(failNo);
        this.repo.deleteById(failNo);
        return entity.toDto();
    }

    @Transactional(readOnly = true)
    public NewIdLongDto getNewActSeq(String failNo) {
        Long newId = this.repo.getNewActSeq(failNo);
        return NewIdLongDto.builder().newId(newId).build();
    }

    @Transactional(readOnly = true)
    public List<TbFcltFailActDto> findActListByFailNo(String failNo) {
        List<TbFcltFailActDto> result = new ArrayList<>();
        List<TbFcltFailAct> data = this.repo.findActListByFailNo(failNo);
        for (TbFcltFailAct entity : data) {
            result.add(entity.toDto());
        }
        return result;
    }
}
