package com.icomsys.main_vm.db.jpa.repo.system.dsl;


import com.google.gson.Gson;
import com.icomsys.main_vm.biz.rcp.conversation.vo.SynonymWordListVo;
import com.icomsys.main_vm.biz.rcp.conversation.vo.synonym.ExcelSynonymListVo;
import com.icomsys.main_vm.biz.rcp.conversation.vo.synonym.SelectSynonymList2Vo;
import com.icomsys.main_vm.biz.rcp.conversation.vo.synonym.SelectSynonymListVo;
import com.icomsys.main_vm.db.jpa.entity.conversation.QTbSynonymMaster;
import com.icomsys.main_vm.db.jpa.entity.conversation.QTbSynonymWord;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;

@Aspect
@Slf4j
@RequiredArgsConstructor
public class TbSynonymMasterRepoDslImpl implements TbSynonymMasterRepoDsl {

    private final JPAQueryFactory queryFactory;
    private QTbSynonymMaster qTbSynonymMaster = QTbSynonymMaster.tbSynonymMaster;
    private QTbSynonymWord qTbSynonymWord = QTbSynonymWord.tbSynonymWord;

    @Override
    public List<SelectSynonymListVo> selectSynonymList(String oprMngCode, String repWord) {
        List<SelectSynonymListVo> result = null;

            var query = queryFactory.select(Projections.fields(
                                    SelectSynonymListVo.class,
                                    qTbSynonymMaster.seq,
                                    qTbSynonymMaster.idivWord,
                                    qTbSynonymMaster.repWord
                                    //Expressions.stringTemplate("group_concat({0})", qTbSynonymWord.seq, ",").as("synonymSeqs"),
                                    //Expressions.stringTemplate("group_concat({0})", qTbSynonymWord.synonymWord, ",").as("synonymWords")
                            )
                    )
                    .from(qTbSynonymMaster)
                    .leftJoin(qTbSynonymWord).on(qTbSynonymMaster.seq.eq(qTbSynonymWord.masterSeq)
                            .and(qTbSynonymWord.useYn.eq("Y")))
                    .where(qTbSynonymMaster.useYn.eq("Y")
                            .and(qTbSynonymWord.useYn.eq("Y")
                            .and(qTbSynonymMaster.oprMngCode.eq(oprMngCode))));
            if (repWord != null && !(repWord.equals(""))) {
                query.where(qTbSynonymMaster.repWord.like("%".concat(repWord).concat("%")));
            }
            query.groupBy(qTbSynonymMaster.seq, qTbSynonymMaster.idivWord, qTbSynonymMaster.repWord);
            query.orderBy(qTbSynonymMaster.updateDate.desc());
            result = query.fetch();

        return result;
    }

    
    //사용안함
    @Override
    public List<SelectSynonymList2Vo> selectSynonymList2(String opr, String repWord) {
        log.info("Synonym2 dsl impl");

        //서브쿼리 리스트 바인딩이..
        var result = queryFactory.select(Projections.fields(
                                SelectSynonymList2Vo.class,
                                qTbSynonymMaster.seq,
                                qTbSynonymMaster.idivWord,
                                qTbSynonymMaster.repWord,
//                       qTbSynonymWord.seq.stringValue().as("synonymSeqs"),
                                ExpressionUtils.as(
                                        JPAExpressions
                                                .select(qTbSynonymWord.seq)
                                                .from(qTbSynonymWord)
                                                .where(qTbSynonymWord.masterSeq.eq(qTbSynonymMaster.seq)),
                                        "synonymSeqs"),
//                       qTbSynonymWord.synonymWord.stringValue().as("synonymWords")
                                ExpressionUtils.as(JPAExpressions
                                                .select(qTbSynonymWord.synonymWord)
                                                .from(qTbSynonymWord)
                                                .where(qTbSynonymWord.masterSeq.eq(qTbSynonymMaster.seq)),
                                        "synonymWords")
                        )
                )
                .from(qTbSynonymMaster)
                .leftJoin(qTbSynonymWord).on(qTbSynonymMaster.seq.eq(qTbSynonymWord.masterSeq)
                        .and(qTbSynonymWord.useYn.eq("Y"))
                )
                .where(
                        qTbSynonymMaster.useYn.eq("Y")
                                .and(qTbSynonymWord.useYn.eq("Y"))
                ).groupBy(qTbSynonymMaster.seq)
                .fetch();
        return result;
    }

    @Override
    public Long dupIndivWord(HashMap eMap) {
        Long result = null;
        String oprMngCode = eMap.get("custCode") + "_RCP_" + eMap.get("serviceGroup");
        var query = queryFactory.select(
                        qTbSynonymMaster.count()
                ).from(qTbSynonymMaster)
                .where(qTbSynonymMaster.idivWord.eq(eMap.get("idivWord").toString())
                        .and(qTbSynonymMaster.useYn.eq("Y"))
                        .and(qTbSynonymMaster.oprMngCode.eq(oprMngCode)));

                if(eMap.get("seq") != null && !(eMap.get("seq").equals(""))) {
                    query.where(qTbSynonymMaster.seq.ne(Long.valueOf(String.valueOf(eMap.get("seq")))));
                }
                result = query.fetchOne();
        return result;
    }


    @Override
    public Long dupRepWord(HashMap eMap) {
        Long result = null;
        String oprMngCode = eMap.get("custCode") + "_RCP_" + eMap.get("serviceGroup");

        var query = queryFactory.select(
                        qTbSynonymMaster.count()
                ).from(qTbSynonymMaster)
                .where(qTbSynonymMaster.repWord.eq(eMap.get("repWord").toString())
                        .and(qTbSynonymMaster.useYn.eq("Y"))
                        .and(qTbSynonymMaster.oprMngCode.eq(oprMngCode)));
        if(eMap.get("seq") != null && !(eMap.get("seq").equals(""))) {
            query.where(qTbSynonymMaster.seq.ne(Long.valueOf(String.valueOf(eMap.get("seq")))));
        }
        result = query.fetchOne();
        return result;
    }

    @Override
    public Long selectSynonymMaster(HashMap eMap) {
        String oprMngCode = eMap.get("custCode") + "_RCP_" + eMap.get("serviceGroup");

        var query = queryFactory.select(
                qTbSynonymMaster.seq
        ).from(qTbSynonymMaster)
                .where(qTbSynonymMaster.oprMngCode.eq(oprMngCode)
                        .and(qTbSynonymMaster.idivWord.eq(eMap.get("idivWord").toString())))
                .fetchOne();

        return query;
    }

    @Override
    public Long dupRepWordN(HashMap eMap) {
        Long result = null;
        String oprMngCode = eMap.get("custCode") + "_RCP_" + eMap.get("serviceGroup");

        var query = queryFactory.select(
                        qTbSynonymMaster.count()
                ).from(qTbSynonymMaster)
                .where(qTbSynonymMaster.repWord.eq(eMap.get("repWord").toString())
                        .and(qTbSynonymMaster.oprMngCode.eq(oprMngCode)));
        if(eMap.get("seq") != null && !(eMap.get("seq").equals(""))) {
            query.where(qTbSynonymMaster.seq.ne(Long.valueOf(String.valueOf(eMap.get("seq")))));
        }
        result = query.fetchOne();
        return result;
    }

    @Override
    public Long dupSynonymY(HashMap eMap) {
        Long result = null;
        String oprMngCode = eMap.get("custCode") + "_RCP_" + eMap.get("serviceGroup");

            var query = queryFactory.select(
                            qTbSynonymWord.count()
                    ).from(qTbSynonymWord)
                    .where(qTbSynonymWord.synonymWord.eq(eMap.get("synonymWord").toString())
                            .and(qTbSynonymWord.useYn.eq("Y"))
                            .and(qTbSynonymWord.oprMngCode.eq(oprMngCode)));
            if (eMap.get("seq") != null && !(eMap.get("seq").equals(""))) {
                query.where(qTbSynonymWord.masterSeq.ne(Long.valueOf(String.valueOf(eMap.get("seq")))));
            }
            result = query.fetchOne();
            return result;

    }

    @Override
    public Long dupSynonymN(HashMap eMap) {
        String oprMngCode = eMap.get("custCode") + "_RCP_" + eMap.get("serviceGroup");

        var query = queryFactory.select(
                        qTbSynonymWord.count()
                ).from(qTbSynonymWord)
                .where(qTbSynonymWord.synonymWord.eq(eMap.get("synonymWord").toString())
                        .and(qTbSynonymWord.oprMngCode.eq(oprMngCode)))
                .fetchOne();
        return query;
    }

    @Override
    public List<SynonymWordListVo> insertSynonymWord(HashMap eMap) {
        String oprMngCode = eMap.get("custCode") + "_RCP_" + eMap.get("serviceGroup");

        var query = queryFactory.select(
                Projections.fields(SynonymWordListVo.class,
                        qTbSynonymMaster.seq))
                .from(qTbSynonymMaster)
                .where(qTbSynonymMaster.idivWord.eq(eMap.get("idivWord").toString())
                        .and(qTbSynonymMaster.oprMngCode.eq(oprMngCode)))
                .fetch();
        return query;
    }

    @Override
    public int deleteSynonyms(HashMap eMap) {
        var query = queryFactory.update(qTbSynonymMaster)
                .set(qTbSynonymMaster.useYn, "N")
                .where(qTbSynonymMaster.seq.eq(Long.valueOf(String.valueOf(eMap.get("seq")))));
            return (int) query.execute();

    }

    @Override
    public void updateSynonymMaster(HashMap eMap) {
            var query = queryFactory.update(qTbSynonymMaster)
                        .set(qTbSynonymMaster.idivWord, eMap.get("idivWord").toString())
                        .set(qTbSynonymMaster.repWord, eMap.get("repWord").toString())
                        .set(qTbSynonymMaster.useYn, "Y")
                        .set(qTbSynonymMaster.updateId, eMap.get("userId").toString())
                        .set(qTbSynonymMaster.updateDate, LocalDateTime.now())
                    .where(qTbSynonymMaster.seq.eq((Long) eMap.get("seq")))
                    .execute();

    }

    /*@Override
    public List<ExcelSynonymListVo> excelSynonymList(String opr, String repWord) {
        List<ExcelSynonymListVo> result = null;

        var query = queryFactory.select(Projections.fields(
                                ExcelSynonymListVo.class,
                                qTbSynonymMaster.idivWord,
                                qTbSynonymMaster.repWord
                                //Expressions.stringTemplate("group_concat({0})", qTbSynonymWord.synonymWord, ",").as("synonymWords")
                        )
                )
                .from(qTbSynonymMaster)
                .leftJoin(qTbSynonymWord).on(qTbSynonymMaster.seq.eq(qTbSynonymWord.masterSeq)
                        .and(qTbSynonymWord.useYn.eq("Y")))
                .where(qTbSynonymMaster.useYn.eq("Y")
                        .and(qTbSynonymWord.useYn.eq("Y")
                                .and(qTbSynonymMaster.oprMngCode.eq(opr))));
        if (repWord != null && !(repWord.equals(""))) {
            query.where(qTbSynonymMaster.repWord.like("%".concat(repWord).concat("%")));
        }
        query.groupBy(qTbSynonymMaster.seq, qTbSynonymMaster.idivWord, qTbSynonymMaster.repWord);
        query.orderBy(qTbSynonymMaster.updateDate.desc());
        result = query.fetch();

        return result;
    }*/


}
