package cokr.xit.ens.modules.kkomydoc.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.core.utils.CmmnUtil;
import cokr.xit.ens.modules.common.biztmplt.EnsPhaseProcSupport;
import cokr.xit.ens.modules.common.code.StatCd;
import cokr.xit.ens.modules.common.domain.SendMast;
import cokr.xit.ens.modules.common.domain.repository.SendMastRepository;
import cokr.xit.ens.modules.kkomydoc.domain.SendDetailKkoMydoc;
import cokr.xit.ens.modules.kkomydoc.domain.repository.SendDetailKkoMydocRepository;
import cokr.xit.ens.modules.kkomydoc.model.KkoMydocRsltRespDTO;
import cokr.xit.ens.modules.kkomydoc.model.config.KkoMydocStat;
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;
import java.util.stream.Collectors;

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

    private final SendMastRepository sendMastRepository;
    private final SendDetailKkoMydocRepository sendDetailKkoMydocRepository;

    @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 sendMastId) {
        try {
            SendMast sendMast = sendMastRepository.findById(sendMastId)
                    .orElseThrow(() -> new EnsException(EnsErrCd.PRVD404, String.format("일치하는 발송마스터 자료가 없습니다. [ sendMastId %s ]", sendMastId)));
            List<SendDetailKkoMydoc> sendDetailKkoMydocs = sendDetailKkoMydocRepository.findAllBySendMast(sendMast);


            KkoMydocRsltRespDTO respDTO = KkoMydocRsltRespDTO.builder()
                    .sendMastId(sendMast.getSendMastId())
                    .statCd(sendMast.getStatCd())
                    .orgCd(sendMast.getOrgCd())
                    .tmpltCd(sendMast.getTmpltCd())
                    .postBundleTitle(sendMast.getPostBundleTitle())
                    .sendDt(sendMast.getSendDt().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")))
                    .closeDt(sendMast.getCloseDt().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")))
                    .closeAt(this.getCloseAt(sendMast))
                    .documents(sendDetailKkoMydocs.stream()
                            .map(row -> KkoMydocStat.builder()
                                    .sendDetailId(row.getSendDetailId())
                                    .externalDocumentUuid(row.getPropExternalDocumentUuid())
                                    .documentBinderUuid(row.getDocumentBinderUuid())
                                    .kkoDocStat(row.getKkoDocStat())
                                    .kkoDocSentDt(row.getKkoDocSentDt())
                                    .kkoDocReceivedDt(row.getKkoDocReceivedDt())
                                    .kkoDocAuthFrstDt(row.getKkoDocAuthFrstDt())
                                    .kkoDocTokenVrfyFrstDt(row.getKkoDocTokenVrfyFrstDt())
                                    .kkoDocReadFrstDt(row.getKkoDocReadFrstDt())
                                    .kkoDocUserNotiedDt(row.getKkoDocUserNotiedDt())
                                    .errorCode(CmmnUtil.isEmpty(row.getError()) ? null : row.getError().getErrorCode())
                                    .errorMessage(CmmnUtil.isEmpty(row.getError()) ? null : row.getError().getErrorMessage())
                                    .build())
                            .collect(Collectors.toList()))
                    .build();

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

    }

    private boolean getCloseAt(SendMast sendMast) {
        if (StatCd.close.equals(sendMast.getStatCd()))
            return true;
        else if (StatCd.sendfail.equals(sendMast.getStatCd()))
            return true;
        else
            return false;
    }
}
