package cokr.xit.ens.modules.nvsigntalk.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.nvsigntalk.domain.SendDetailNvSigntalk;
import cokr.xit.ens.modules.nvsigntalk.domain.repository.SendDetailNvSigntalkRepository;
import cokr.xit.ens.modules.nvsigntalk.model.NvSigntalkRsltRespDTO;
import cokr.xit.ens.modules.nvsigntalk.model.config.NvSigntalkStat;
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 NvSigntalkRsltProvider implements EnsPhaseProcSupport<EnsResponseVO, Long> {

    private final SendMastRepository sendMastRepository;
    private final SendDetailNvSigntalkRepository sendDetailNvSigntalkRepository;

    @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<SendDetailNvSigntalk> sendDetailNvSigntalks = sendDetailNvSigntalkRepository.findAllBySendMast(sendMast);


            NvSigntalkRsltRespDTO respDTO = NvSigntalkRsltRespDTO.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(sendDetailNvSigntalks.stream()
                            .map(row -> NvSigntalkStat.builder()
                                    .sendDetailId(row.getSendDetailId())
                                    .clientDocId(row.getClientDocId())
                                    .docId(row.getDocId())
                                    .nvDocStat(row.getNvDocStat())
                                    .nvDocSentDt(row.getNvDocSentDt())
                                    .nvDocReceivedDt(row.getNvDocReceivedDt())
                                    .nvDocAuthFrstDt(row.getNvDocAuthFrstDt())
                                    .nvDocTokenVrfyFrstDt(row.getNvDocTokenVrfyFrstDt())
                                    .nvDocReadFrstDt(row.getNvDocReadFrstDt())
                                    .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(NvSigntalkRsltRespDTO.builder()
                            .sendMastId(sendMastId)
                            .build())
                    .build();
        } catch (Exception e) {
            return EnsResponseVO.errRsltBuilder()
                    .errCode(EnsErrCd.ERR999)
                    .errMsg(String.format("전송결과 응답 처리 실패. 실패사유: %s", e.getMessage()))
                    .resultInfo(NvSigntalkRsltRespDTO.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;
    }
}
