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

import cokr.xit.ens.core.exception.EnsException;
import cokr.xit.ens.core.exception.code.EnsErrCd;
import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng;
import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.TmpltMng;
import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.repository.OrgMngRepository;
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.model.struct.TmpltMngMapper;
import lombok.RequiredArgsConstructor;
import org.mapstruct.factory.Mappers;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.*;
import java.util.stream.Collectors;

@Component("tmpltMngStrategy_basic")
@RequiredArgsConstructor
public class TmpltMngStrategyBasic extends TmpltMngStrategyTemplate<Map<String, Object>, TmpltMngDTO> {
    private final OrgMngRepository orgMngRepository;
    private final TmpltMngRepository tmpltMngRepository;
    private TmpltMngMapper kkoMydocMapper = Mappers.getMapper(TmpltMngMapper.class);
//    private final RedisTemplate redisTemplate;

    public List<TmpltMngDTO> findAll(TmpltMngSearchDTO tmpltMngSearchDTO) {
        return tmpltMngRepository.findAllDtoBySearchDTO(tmpltMngSearchDTO);
    }

    @Override
    public Optional<TmpltMngDTO> find(String orgCd, String tmpltCd) {
        return tmpltMngRepository.findDtoByOrgCdAndTmpltCd(orgCd, tmpltCd);

//        String key = super.pushCache(redisTemplate, orgCd, tmpltCd, tmpltMngRepository);
//        HashOperations<String, String, TmpltMngDTO> hashOperations = redisTemplate.opsForHash();
//        return Optional.ofNullable(hashOperations.entries(KEY).get(key));
    }

    @Override
    protected TmpltMngDTO validate(Map<String, Object> params) {
        try {
            TmpltMngDTO dto = mapper.convertValue(params, TmpltMngDTO.class);

            final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
            Set<ConstraintViolation<TmpltMngDTO>> list = validator.validate(dto);
            if (list.size() > 0) {
                throw new EnsException(EnsErrCd.ERR410, "유효하지 않은 요청 값 입니다.", list.stream()
                        .map(row -> String.format("%s [ %s ]", row.getMessageTemplate(), row.getPropertyPath()))
                        .collect(Collectors.toList())
                );
            }
            return dto;
        } catch (IllegalArgumentException e) {
            throw new EnsException(EnsErrCd.ERR403, "유효하지 않은 파라미터 입니다. 사용가능한 파라미터는 resultInfo 를 참고하시기 바랍니다.", Arrays.stream(TmpltMngDTO.class.getDeclaredFields()).map(row -> row.getName()).collect(Collectors.toList()));
        }
    }

    @Override
    protected void addProc(TmpltMngDTO dto) {
        OrgMng orgMng = orgMngRepository.findById(dto.getOrgCd()).orElseThrow(() -> new EnsException(EnsErrCd.ERR404, String.format("기관코드(%s)가 일치하는 자료가 없습니다.", dto.getOrgCd())));
        tmpltMngRepository.findFetchByOrgCdAndTmpltCd(dto.getOrgCd(), dto.getTmpltCd())
                .ifPresent(tmpltMng -> {
                    throw new EnsException(EnsErrCd.ERR540, String.format("이미 등록된 템플릿코드[기관코드 %s 템플릿코드 %s] 입니다.", tmpltMng.getOrgMng().getOrgCd(), tmpltMng.getTmpltCd()));
                });

        TmpltMng tmpltMng = kkoMydocMapper.toEntity(dto);
        tmpltMng.setOrgMng(orgMng);
        tmpltMng.setRegistId("ENS_SYS");
        tmpltMngRepository.save(tmpltMng);
    }

    @Override
    protected void modifyProc(TmpltMngDTO tmpltMngDTO) {
        TmpltMng tmpltMng = tmpltMngRepository.findFetchByOrgCdAndTmpltCd((tmpltMngDTO).getOrgCd(), (tmpltMngDTO).getTmpltCd())
                .orElseThrow(() -> new EnsException(EnsErrCd.ERR404, String.format("기관코드(%s) 및 템플릿코드(%s)가 일치하는 자료가 없습니다.", tmpltMngDTO.getOrgCd(), tmpltMngDTO.getTmpltCd())));
        kkoMydocMapper.updateFromDto(tmpltMngDTO, tmpltMng);
        tmpltMng.setUpdId("ENS_SYS");

//        super.deleteCache(redisTemplate, tmpltMngDTO.getOrgCd(), tmpltMngDTO.getTmpltCd());
    }
}
