package com.its.api.its.service.link;

import com.its.api.its.model.dto.link.LinkParaClctSystDto;
import com.its.api.its.model.dto.link.LinkPrcsParaDto;
import com.its.api.its.model.entity.link.TbLinkParaClctSyst;
import com.its.api.its.model.entity.link.TbLinkParaDetl;
import com.its.api.its.model.entity.link.TbLinkParaStup;
import com.its.api.its.model.entity.link.TbLink;
import com.its.api.its.repository.dao.LinkPrcsParaDao;
import com.its.api.its.repository.link.TbLinkParaClctSystRepository;
import com.its.api.its.repository.link.TbLinkParaDetlRepository;
import com.its.api.its.repository.link.TbLinkParaStupRepository;
import com.its.api.its.repository.link.TbLinkRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.List;
import java.util.Optional;

@Slf4j
@RequiredArgsConstructor
@Service
public class LinkPrcsParaService {

    private final TbLinkParaStupRepository stupRepo;
    private final TbLinkParaDetlRepository detlRepo;
    private final TbLinkParaClctSystRepository systRepo;

    private final TbLinkRepository linkRepo;
    private final LinkPrcsParaDao dao;

    public LinkPrcsParaDto.LinkPrcsParaInfo findListById(Long id) {

        LinkPrcsParaDto.LinkPrcsParaInfo result = null;
        try {
            TbLinkParaStup stup = null;
            TbLinkParaDetl detl = null;
            Optional<TbLinkParaStup> stupOpt = this.stupRepo.findById(id);
            Optional<TbLinkParaDetl> detlOpt = this.detlRepo.findById(id);
            List<TbLinkParaClctSyst> systOpt = this.systRepo.findListById(id);
            if (stupOpt.isPresent()) {
                stup = stupOpt.get();
            }
            if (detlOpt.isPresent()) {
                detl = detlOpt.get();
            }
            result = new LinkPrcsParaDto.LinkPrcsParaInfo(stup, detl, systOpt);
        }
        catch (Exception e) {
            log.error("{}.findById: Object: {}, Exception: {}", getClass().getSimpleName(), id, e.getMessage());
        }
        return result;
    }

    @Transactional
    public LinkPrcsParaDto.LinkPrcsParaUpdateReq mergeById(List<Long> ids, LinkPrcsParaDto.LinkPrcsParaUpdateReq req) {
        try {
            for (Long id : ids) {
                TbLinkParaStup stup = new TbLinkParaStup(id);
                stup.updateInfo(req.getStup());
                this.stupRepo.save(stup);

                TbLinkParaDetl detl = new TbLinkParaDetl(id);
                detl.updateInfo(req.getDetl());
                this.detlRepo.save(detl);

                this.systRepo.deleteListById(id);
                for (LinkParaClctSystDto.LinkParaClctSystUpdateReq obj : req.getSystList()) {
                    if (obj != null) {
                        TbLinkParaClctSyst syst = new TbLinkParaClctSyst(id);
                        syst.updateInfo(obj);
                        this.systRepo.save(syst);
                    }
                }
            }
        }
        catch (Exception e) {
            log.error("{}.mergeInfo: Object: {}, Exception: {}", getClass().getSimpleName(), req, e.getMessage());
        }
        return req;
    }

    @Transactional
    public LinkPrcsParaDto.LinkPrcsParaUpdateReq mergeAll(LinkPrcsParaDto.LinkPrcsParaUpdateReq req) {
        try {
            List<TbLink> links = this.linkRepo.findAll();
            this.dao.mergeAll(req, links);
        }
        catch (Exception e) {
            log.error("{}.mergeAll: Object: {}, Exception: {}", getClass().getSimpleName(), req, e.getMessage());
        }
        return req;
    }
}
