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

import com.icomsys.main_vm.biz.common.login.service.LoginService;
import com.icomsys.main_vm.biz.rcp.conversation.vo.*;
import com.icomsys.main_vm.db.jpa.entity.scenario.QTbCommonNode;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;

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

/**
 * Name : TbCommonNodeRepoDslImpl 
 * date : 2023-02-13 
 * author :  Mong
 * description :
 * ===========================================================
 * DATE                 AUTHOR                NOTE
 * -----------------------------------------------------------
 * 2023-02-13                Mong             최초 생성
 */
@Aspect
@Slf4j
@RequiredArgsConstructor
public class TbCommonNodeRepoDslImpl implements TbCommonNodeRepoDsl{

    private final JPAQueryFactory queryFactory;

    private QTbCommonNode qTbCommonNode = QTbCommonNode.tbCommonNode;

    private final LoginService loginService;

    @Override
    public QueryResults<ConversationCmmNodeInfoRes> serachCmmNodeList(ConversationCmmNodeInfoReq dto) {

        QueryResults<ConversationCmmNodeInfoRes> result =
                queryFactory.select(
                        Projections.fields(
                                ConversationCmmNodeInfoRes.class,
                                qTbCommonNode.seq,
                                qTbCommonNode.nodeName,
                                qTbCommonNode.updateDate,
                                qTbCommonNode.updateId
                        )
                ).from(qTbCommonNode)
                .where(scenarioNameEq(dto)
                        ,oprMngCodeEq(dto)
                        ,(qTbCommonNode.useYn.eq("Y"))
                )
                .fetchResults();
        return result;
    }

    @Override
    public void updateCmmNode(ConversationCmmNodeEditReq dto) {

        String userId = loginService.getUserVo().getUserId();
        String oprMngCode = dto.getCustCode() + "_RCP_" +  dto.getServiceGroup();
        var query = queryFactory.update(qTbCommonNode)
                                .set(qTbCommonNode.nodeName, dto.getNodeName())
                                .set(qTbCommonNode.updateDate, LocalDateTime.now())
                                .set(qTbCommonNode.updateId, userId)
                                .set(qTbCommonNode.oprMngCode, oprMngCode)
                                .where(qTbCommonNode.seq.eq(dto.getSeq()).and(qTbCommonNode.useYn.eq("Y")));
        query.execute();

    }

    private BooleanExpression scenarioNameEq(ConversationCmmNodeInfoReq dto) {
        if (dto.getNodeName() == null || dto.getNodeName().equals("")) {
            return null;
        } else {
            return qTbCommonNode.nodeName.contains(dto.getNodeName());
        }
    }

    private BooleanExpression oprMngCodeEq(ConversationCmmNodeInfoReq dto) {
        if (dto.getCustCode() == null || dto.getCustCode().equals("")) {
            return null;
        } else if (dto.getServiceGroup() == null || dto.getServiceGroup().equals("")) {
            return null;
        } else {
            List<String> oprMngCodes = new ArrayList<>();
            oprMngCodes.add(dto.getCustCode() + "_RCP_" + dto.getServiceGroup());

            if (dto.isContainUpper()) {
                oprMngCodes.add(dto.getCustCode() + "_RCP_" + dto.getServiceGroupUpper());
            }
            return qTbCommonNode.oprMngCode.in(oprMngCodes);
        }
    }

    @Override
    public List<ConversationCmmNodeInfoRes> selectCmmNode(Long seq) {
        var query = queryFactory.select(
                                        Projections.fields(
                                                ConversationCmmNodeInfoRes.class,
                                                qTbCommonNode.nodeName,
                                                qTbCommonNode.seq,
                                                qTbCommonNode.updateId,
                                                qTbCommonNode.updateDate
                                        )
                                ).from(qTbCommonNode)
                                .where(qTbCommonNode.seq.eq(seq).and(qTbCommonNode.useYn.eq("Y")))
                                .fetch();

        return query;
    }

    @Override
    public void deleteCmmNode(Long seq) {
        String userId = loginService.getUserVo().getUserId();
        var query = queryFactory.update(qTbCommonNode)
                                .set(qTbCommonNode.useYn, "N")
                                .set(qTbCommonNode.updateDate, LocalDateTime.now())
                                .set(qTbCommonNode.updateId, userId)
                                .where(qTbCommonNode.seq.eq(seq));
        query.execute();

    }
}
