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.ConversationApiNodeEditReq;
import com.icomsys.main_vm.biz.rcp.conversation.vo.ConversationApiNodeInfoReq;
import com.icomsys.main_vm.biz.rcp.conversation.vo.ConversationApiNodeInfoRes;
import com.icomsys.main_vm.db.jpa.entity.scenario.QTbApiNode;
import com.icomsys.main_vm.db.jpa.entity.system.QTbIcsOprMngInfo;
import com.icomsys.main_vm.db.jpa.entity.system.QTbServiceGrouop;
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 : TbApiNodeRepoDslImpl 
 * date : 2023-02-09 
 * author :  Mong
 * description :
 * ===========================================================
 * DATE                 AUTHOR                NOTE
 * -----------------------------------------------------------
 * 2023-02-09                Mong             최초 생성
 */
@Aspect
@Slf4j
@RequiredArgsConstructor
public class TbApiNodeRepoDslImpl implements TbApiNodeRepoDsl {

    private final JPAQueryFactory queryFactory;

    private QTbApiNode qTbApiNode = QTbApiNode.tbApiNode;
    private QTbIcsOprMngInfo qTbIcsOprMngInfo = QTbIcsOprMngInfo.tbIcsOprMngInfo;
    private QTbServiceGrouop qTbServiceGroup = QTbServiceGrouop.tbServiceGrouop;


    private final LoginService loginService;

    @Override
    public QueryResults<ConversationApiNodeInfoRes> searchApiNodeList(ConversationApiNodeInfoReq dto) {

        QueryResults<ConversationApiNodeInfoRes> result =
                queryFactory.select(
                        Projections.fields(
                            ConversationApiNodeInfoRes.class,
                            qTbApiNode.seq,
                            qTbApiNode.nodeName,
                            qTbApiNode.updateDate,
                            qTbApiNode.updateId,
                            qTbApiNode.oprMngCode,
                            qTbServiceGroup.serviceGroupName
                        )
                ).from(qTbApiNode).innerJoin(qTbIcsOprMngInfo).on(qTbApiNode.oprMngCode.eq(qTbIcsOprMngInfo.oprMngCode))
                        .innerJoin(qTbServiceGroup).on(qTbIcsOprMngInfo.serviceGroup.eq(qTbServiceGroup.serviceGroup))
                .where(scenarioNameEq(dto)
                       ,oprMngCodeEq(dto)
                       ,(qTbApiNode.useYn.eq("Y"))
                       )
                .fetchResults();
        return result;
    }

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

    private BooleanExpression oprMngCodeEq(ConversationApiNodeInfoReq 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 qTbApiNode.oprMngCode.in(oprMngCodes);
        }
    }

    @Override
    public void updateApiNode(ConversationApiNodeEditReq dto) {

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

    @Override
    public List<ConversationApiNodeInfoRes> selectApiNode(Long seq) {

        var query = queryFactory.select(
                Projections.fields(
                        ConversationApiNodeInfoRes.class,
                        qTbApiNode.nodeName,
                        qTbApiNode.seq,
                        qTbApiNode.updateId,
                        qTbApiNode.updateDate,
                        qTbApiNode.oprMngCode
                )
        ).from(qTbApiNode)
        .where(qTbApiNode.seq.eq(seq).and(qTbApiNode.useYn.eq("Y")))
        .fetch();

        return query;

    }

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


    }
}
