package cokr.xit.ens.modules.ktsigntalk.gibis.domain.repository;

import cokr.xit.ens.core.utils.CmmnUtil;
import cokr.xit.ens.modules.common.ctgy.sys.mng.model.TmpltMngSearchDTO;
import cokr.xit.ens.modules.ktsigntalk.gibis.domain.TmpltMngKtGibis;
import cokr.xit.ens.modules.ktsigntalk.gibis.model.TmpltMngKtGibisDTO;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.QBean;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;

import java.util.List;
import java.util.Optional;

import static cokr.xit.ens.modules.common.ctgy.sys.mng.domain.QOrgMng.orgMng;
import static cokr.xit.ens.modules.ktsigntalk.gibis.domain.QTmpltMngKtGibis.tmpltMngKtGibis;

@RequiredArgsConstructor
public class TmpltMngKtGibisRepositoryImpl implements TmpltMngKtGibisRepositoryCustom {

    private final JPAQueryFactory query;

    @Override
    public Optional<TmpltMngKtGibis> findFetchByOrgCdAndTmpltCd(String orgCd, String tmpltCd) {
        return Optional.ofNullable(query.selectFrom(tmpltMngKtGibis)
                .where(tmpltMngKtGibis.orgMng.orgCd.eq(orgCd)
                        .and(tmpltMngKtGibis.tmpltCd.eq(tmpltCd)))
                .fetchOne());
    }

    @Override
    public List<TmpltMngKtGibis> findAllFetchBySearchDTO(TmpltMngSearchDTO searchDTO) {
        return query.selectFrom(tmpltMngKtGibis)
                .innerJoin(tmpltMngKtGibis.orgMng, orgMng)
                .fetchJoin()
                .where(eqSearchDTO(searchDTO))
                .fetch();
    }

    @Override
    public Optional<TmpltMngKtGibisDTO> findDtoByOrgCdAndTmpltCd(String orgCd, String tmpltCd) {
        return Optional.ofNullable(query.select(mappedDto())
                .from(tmpltMngKtGibis)
                .where(tmpltMngKtGibis.orgMng.orgCd.eq(orgCd)
                        .and(tmpltMngKtGibis.tmpltCd.eq(tmpltCd)))
                .fetchOne());
    }


    @Override
    public List<TmpltMngKtGibisDTO> findAllDtoBySearchDTO(TmpltMngSearchDTO searchDTO) {
        return query.select(mappedDto())
                .from(tmpltMngKtGibis)
                .innerJoin(tmpltMngKtGibis.orgMng, orgMng)
                .where(eqSearchDTO(searchDTO))
                .fetch();
    }

    private QBean<TmpltMngKtGibisDTO> mappedDto() {
        return Projections.fields(TmpltMngKtGibisDTO.class
                , tmpltMngKtGibis.dtype
                , tmpltMngKtGibis.orgMng.orgCd
                , tmpltMngKtGibis.orgMng.orgNm
                , tmpltMngKtGibis.tmpltCd
                , tmpltMngKtGibis.title
                , tmpltMngKtGibis.message
                , tmpltMngKtGibis.useYn

                , tmpltMngKtGibis.msgCd
                , tmpltMngKtGibis.mtype
                , tmpltMngKtGibis.msgType
                , tmpltMngKtGibis.optType
                , tmpltMngKtGibis.sndTelNo
                , tmpltMngKtGibis.sendTel
                , tmpltMngKtGibis.ciTransUseYn
                , tmpltMngKtGibis.tmpltMsgUseYn
                , tmpltMngKtGibis.tmpltCsInfoUseYn
                , tmpltMngKtGibis.pryMessage
        );
    }

    @Override
    public Optional<TmpltMngKtGibis> findFetchByOrgCdAndTmpltCdAndUseYn(String orgCd, String tmpltCd, String useYn) {
        return Optional.ofNullable(
                query.selectFrom(tmpltMngKtGibis)
                        .innerJoin(tmpltMngKtGibis.orgMng, orgMng)
                        .fetchJoin()
                        .where(
                                tmpltMngKtGibis.orgMng.orgCd.eq(orgCd)
                                        .and(tmpltMngKtGibis.tmpltCd.eq(tmpltCd))
                                        .and(tmpltMngKtGibis.useYn.eq(useYn))
                        )
                        .fetchOne());
    }

    private BooleanBuilder eqSearchDTO(TmpltMngSearchDTO searchDTO) {
        BooleanBuilder builder = new BooleanBuilder();

        if (!CmmnUtil.isEmpty(searchDTO.getSchOrgCd()))
            builder.and(tmpltMngKtGibis.orgMng.orgCd.eq(searchDTO.getSchOrgCd()));

        if (!CmmnUtil.isEmpty(searchDTO.getSchTmpltCd()))
            builder.and(tmpltMngKtGibis.tmpltCd.eq(searchDTO.getSchTmpltCd()));

        if (!CmmnUtil.isEmpty(searchDTO.getSchTitle()))
            builder.and(tmpltMngKtGibis.title.like(searchDTO.getSchTitle() + "%"));


        return builder;
    }

}
