package cokr.xit.ens.modules.common.ctgy.sys.mng.service;

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.ctgy.sys.mng.domain.TmpltMng;
import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.repository.TmpltMngRepository;
import cokr.xit.ens.modules.common.ctgy.sys.mng.model.TmpltMngDTO;
import cokr.xit.ens.modules.common.ctgy.sys.mng.model.TmpltMngSearchDTO;
import cokr.xit.ens.modules.common.ctgy.sys.mng.service.strategy.TmpltMngCacheSupport;
import cokr.xit.ens.modules.common.ctgy.sys.mng.service.strategy.TmpltMngStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

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

@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
public class TmpltMngService extends TmpltMngCacheSupport<TmpltMngDTO> {

    private final OrgMngService orgMngService;
    private final TmpltMngRepository tmpltMngRepository;

    private final Map<String, TmpltMngStrategy> mTmpltMngStrategy;
//    private final RedisTemplate redisTemplate;

    public EnsResponseVO<List<? extends TmpltMngDTO>> findAllBySearchDTO(TmpltMngSearchDTO searchDTO, String dType) {
        TmpltMngStrategy tmpltMngStrategy = mTmpltMngStrategy.get("tmpltMngStrategy_" + dType);
        if (tmpltMngStrategy == null)
            throw new EnsException(EnsErrCd.ERR405, "유효하지 않은 타입 또는 이용이 불가한 템플릿 타입 입니다.");
        return EnsResponseVO.<List<? extends TmpltMngDTO>>okBuilder()
                .resultInfo(tmpltMngStrategy.findAll(searchDTO))
                .build();

    }

    public EnsResponseVO find(String orgCd, String tmpltCd, String dType) {
        try {
            if (CmmnUtil.isEmpty(orgCd))
                throw new EnsException(EnsErrCd.ERR410, "기관코드는 필수 입력값 입니다.");
            if (CmmnUtil.isEmpty(tmpltCd))
                throw new EnsException(EnsErrCd.ERR410, "템플릿코드는 필수 입력값 입니다.");
            EnsResponseVO orgMng = orgMngService.find(orgCd);
            if(!EnsErrCd.OK.equals(orgMng.getErrCode()))
                throw new EnsException(EnsErrCd.ERR404, String.format("기관코드(%s)가 일치하는 자료가 없습니다.", orgCd));
            TmpltMngStrategy tmpltMngStrategy = mTmpltMngStrategy.get("tmpltMngStrategy_" + dType);
            if (tmpltMngStrategy == null)
                throw new EnsException(EnsErrCd.ERR405, "유효하지 않은 타입 또는 이용이 불가한 템플릿 타입 입니다.");
            return EnsResponseVO.okBuilder()
                    .resultInfo(tmpltMngStrategy.find(orgCd, tmpltCd)
                            .orElseThrow(() -> new EnsException(EnsErrCd.ERR404, String.format("기관코드(%s) 및 템플릿코드(%s)가 일치하는 자료가 없습니다.", orgCd, tmpltCd)))
                    )
                    .build();
        } catch (EnsException e) {
            return EnsResponseVO.errBuilder()
                    .errCode(e.getErrCd())
                    .errMsg(e.getMessage())
                    .build();
        } catch (Throwable e) {
            return EnsResponseVO.errBuilder()
                    .errCode(EnsErrCd.ERR999)
                    .errMsg(e.getMessage())
                    .build();
        }
    }


    public EnsResponseVO add(Map<String, Object> mParam, String dType) {
        try {

            mParam.put("useYn", "Y");
            TmpltMngStrategy tmpltMngStrategy = mTmpltMngStrategy.get("tmpltMngStrategy_" + dType);
            if (tmpltMngStrategy == null)
                throw new EnsException(EnsErrCd.ERR405, "유효하지 않은 타입 또는 이용이 불가한 템플릿 타입 입니다.");
            tmpltMngStrategy.add(mParam);


            return EnsResponseVO.okBuilder().build();
        } catch (EnsException e) {
            return EnsResponseVO.errRsltBuilder()
                    .errCode(e.getErrCd())
                    .errMsg(e.getMessage())
                    .resultInfo(e.getData())
                    .build();
        }

    }

    public EnsResponseVO modify(Map<String, Object> mParam, String dType) {
        try {

            mParam.put("useYn", "Y");
            TmpltMngStrategy tmpltMngStrategy = mTmpltMngStrategy.get("tmpltMngStrategy_" + dType);
            if (tmpltMngStrategy == null)
                throw new EnsException(EnsErrCd.ERR405, "유효하지 않은 타입 또는 이용이 불가한 템플릿 타입 입니다.");
            tmpltMngStrategy.modify(mParam);


            return EnsResponseVO.okBuilder().build();
        } catch (EnsException e) {
            return EnsResponseVO.errRsltBuilder()
                    .errCode(e.getErrCd())
                    .errMsg(e.getMessage())
                    .resultInfo(e.getData())
                    .build();
        }
    }

    public EnsResponseVO delete(String orgCd, String tmpltCd) {
        try {
            TmpltMng tmpltMng = tmpltMngRepository.findFetchByOrgCdAndTmpltCd(orgCd, tmpltCd).orElseThrow(() -> new EnsException(EnsErrCd.ERR404, String.format("기관코드(%s) 및 템플릿코드(%s)가 일치하는 자료가 없습니다.", orgCd, tmpltCd)));

            tmpltMng.setUseYn("N");

            return EnsResponseVO.okBuilder().build();
        } catch (EnsException e) {
            return EnsResponseVO.errBuilder()
                    .errCode(e.getErrCd())
                    .errMsg(e.getMessage())
                    .build();
        } finally {
//           
//            super.deleteCache(redisTemplate, orgCd, tmpltCd);
        }
    }

}
