package cokr.xit.ens.modules.common.ctgy.intgrnnoti.service.support;

import cokr.xit.ens.core.aop.EnsResponseVO;
import cokr.xit.ens.core.exception.EnsException;
import cokr.xit.ens.core.exception.code.EnsErrCd;
import cokr.xit.ens.modules.common.biztmplt.EnsPhaseProcSupport;
import cokr.xit.ens.modules.common.code.StatCd;
import cokr.xit.ens.modules.common.ctgy.intgrnnoti.code.TryStatCd;
import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.IntgrnSendMast;
import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.repository.IntgrnSendDetailRepository;
import cokr.xit.ens.modules.common.ctgy.intgrnnoti.domain.repository.IntgrnSendMastRepository;
import cokr.xit.ens.modules.common.ctgy.intgrnnoti.model.IntgrnDetailStatVO;
import cokr.xit.ens.modules.common.ctgy.intgrnnoti.model.IntgrnNotiRsltRespDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.format.DateTimeFormatter;
import java.util.List;

@Slf4j
@Component
@RequiredArgsConstructor
public class IntgrnNotiRsltProvider implements EnsPhaseProcSupport<EnsResponseVO, Long> {

    private final IntgrnSendMastRepository intgrnSendMastRepository;
    private final IntgrnSendDetailRepository intgrnSendDetailRepository;

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public EnsResponseVO statReady(List<Long> args) {
        log.info("no process");
        return null;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public EnsResponseVO statBegin(Long arg) {
        log.info("no process");
        return null;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public EnsResponseVO execute(Long intSendMastId) {
        try {
            IntgrnSendMast intgrnSendMast = intgrnSendMastRepository.findById(intSendMastId)
                    .orElseThrow(() -> new EnsException(EnsErrCd.PRVD404, String.format("일치하는 통합발송마스터 자료가 없습니다. [ intSendMastId %s ]", intSendMastId)));
            List<IntgrnDetailStatVO> sendDetailStats = intgrnSendDetailRepository.findIntgrnDetailStatVOsByIntSendMastId(intSendMastId);


            IntgrnNotiRsltRespDTO respDTO = IntgrnNotiRsltRespDTO.builder()
                    .intSendMastId(intgrnSendMast.getIntSendMastId())
                    .statCd(intgrnSendMast.getStatCd())
                    .orgCd(intgrnSendMast.getOrgCd())
                    .tmpltCd(intgrnSendMast.getTmpltCd())
                    .postBundleTitle(intgrnSendMast.getPostBundleTitle())
                    .sendDt(intgrnSendMast.getSendDt().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")))
                    .closeDt(intgrnSendMast.getCloseDt().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")))
                    .closeAt(this.getCloseAt(intgrnSendMast))
                    .tryStatCd(intgrnSendMast.getTryStatCd())
                    .documents(sendDetailStats)
                    .build();


            return EnsResponseVO.okBuilder().resultInfo(respDTO).build();
        } catch (EnsException e) {
            return EnsResponseVO.errRsltBuilder()
                    .errCode(e.getErrCd())
                    .errMsg(e.getMessage())
                    .resultInfo(IntgrnNotiRsltRespDTO.builder()
                            .intSendMastId(intSendMastId)
                            .build())
                    .build();
        } catch (Exception e) {
            return EnsResponseVO.errRsltBuilder()
                    .errCode(EnsErrCd.ERR999)
                    .errMsg(String.format("전송결과 응답 처리 실패. 실패사유: %s", e.getMessage()))
                    .resultInfo(IntgrnNotiRsltRespDTO.builder()
                            .intSendMastId(intSendMastId)
                            .build())
                    .build();
        }

    }

    private boolean getCloseAt(IntgrnSendMast intgrnSendMast) {
        if (StatCd.close.equals(intgrnSendMast.getStatCd()))
            return true;
        else if (StatCd.sendfail.equals(intgrnSendMast.getStatCd())
                && TryStatCd.cmplt.equals(intgrnSendMast.getTryStatCd()))
            return true;
        else
            return false;
    }
}
