package com.eactive.eai.rms.data.entity.onl.transform;

import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.eactive.eai.data.entity.onl.message.QServiceMessageEntity;
import com.eactive.eai.data.entity.onl.transformer.transform.QTransformEntity;
import com.eactive.eai.data.entity.onl.transformer.transform.TransformEntity;
import com.eactive.eai.data.jpa.AbstractDataService;
import com.eactive.eai.rms.common.login.LoginVo;
import com.eactive.eai.rms.common.login.SessionManager;
import com.eactive.eai.rms.data.entity.onl.bzwkdstcd.QUserBusiness;
import com.eactive.eai.rms.onl.common.exception.BizException;
import com.querydsl.core.Tuple;
import com.querydsl.jpa.impl.JPAQuery;

@Service
@Transactional
public class TransformService extends AbstractDataService<TransformEntity, String, TransformEMSRepository> {

	public Page<TransformEaiMessage> findAll(Pageable pageable, String searchCnvsnName, String searchCnvsnDesc,
			String searchBizCode, String searchIfSvcCd) {

		QTransformEntity qTransformEntity = QTransformEntity.transformEntity;
		QUserBusiness qUserBusiness = QUserBusiness.userBusiness;
		QServiceMessageEntity reqQServiceMessageEntity = new QServiceMessageEntity("reqQServiceMessageEntity");
		QServiceMessageEntity resQServiceMessageEntity = new QServiceMessageEntity("resQServiceMessageEntity");
		QServiceMessageEntity errQServiceMessageEntity = new QServiceMessageEntity("errQServiceMessageEntity");

		LoginVo loginVo = SessionManager.getLoginVo();

		if (loginVo == null) {
			throw new BizException("세션 정보가 없습니다.");
		}

		JPAQuery<String> userBusinessSubQuery = new JPAQuery<>()
				.select(qUserBusiness.id.eaiBzwkDstcd)
				.from(qUserBusiness)
				.where(qUserBusiness.id.userId.eq(loginVo.getUserId()));

		JPAQuery<?> mainQuery = getJPAQueryFactory()
				.from(qTransformEntity)
				.leftJoin(reqQServiceMessageEntity)
				.on(qTransformEntity.cnvsnname
						.eq(reqQServiceMessageEntity.chngmsgidname)
						.and(reqQServiceMessageEntity.id.svcprcssno.eq(1)))
				.leftJoin(resQServiceMessageEntity)
				.on(qTransformEntity.cnvsnname
						.eq(resQServiceMessageEntity.bascrspnschngmsgidname)
						.and(resQServiceMessageEntity.id.svcprcssno.eq(1)))
				.leftJoin(errQServiceMessageEntity)
				.on(qTransformEntity.cnvsnname
						.eq(errQServiceMessageEntity.errrspnschngmsgidname)
						.and(errQServiceMessageEntity.id.svcprcssno.eq(1)))
				.leftJoin(reqQServiceMessageEntity.eaimessage)
				.on(reqQServiceMessageEntity.id.eaisvcname.eq(reqQServiceMessageEntity.eaimessage.eaisvcname))
				.leftJoin(resQServiceMessageEntity.eaimessage)
				.on(resQServiceMessageEntity.id.eaisvcname.eq(resQServiceMessageEntity.eaimessage.eaisvcname))
				.leftJoin(errQServiceMessageEntity.eaimessage)
				.on(errQServiceMessageEntity.id.eaisvcname.eq(errQServiceMessageEntity.eaimessage.eaisvcname))
				.where(qTransformEntity.cnvsnname.substring(10, 13).in(userBusinessSubQuery));

		if (StringUtils.isNotBlank(searchCnvsnName)) {
			mainQuery.where(qTransformEntity.cnvsnname.containsIgnoreCase(searchCnvsnName));
		}

		if (StringUtils.isNotBlank(searchCnvsnDesc)) {
			mainQuery.where(qTransformEntity.cnvsndesc.containsIgnoreCase(searchCnvsnDesc));
		}

		if (StringUtils.isNotBlank(searchBizCode)) {
			mainQuery
					.where(reqQServiceMessageEntity.eaimessage.eaibzwkdstcd
							.containsIgnoreCase(searchBizCode)
							.or(resQServiceMessageEntity.eaimessage.eaibzwkdstcd.containsIgnoreCase(searchBizCode))
							.or(errQServiceMessageEntity.eaimessage.eaibzwkdstcd.containsIgnoreCase(searchBizCode)));
		}

		if (StringUtils.isNotBlank(searchIfSvcCd)) {
			mainQuery
					.where(reqQServiceMessageEntity.eaimessage.eaisvcname
							.containsIgnoreCase(searchIfSvcCd)
							.or(resQServiceMessageEntity.eaimessage.eaisvcname.containsIgnoreCase(searchIfSvcCd))
							.or(errQServiceMessageEntity.eaimessage.eaisvcname.containsIgnoreCase(searchIfSvcCd)));
		}

		long totalCount = mainQuery.select(qTransformEntity.count()).fetchOne();

		if (pageable.isPaged()) {
			mainQuery.limit(pageable.getPageSize()).offset(pageable.getOffset());
		}

		List<Tuple> tuples = mainQuery
				.select(qTransformEntity, reqQServiceMessageEntity.eaimessage.eaisvcname,
						reqQServiceMessageEntity.eaimessage.eaibzwkdstcd,
						reqQServiceMessageEntity.eaimessage.eaisvcdesc,

						resQServiceMessageEntity.eaimessage.eaisvcname,
						resQServiceMessageEntity.eaimessage.eaibzwkdstcd,
						resQServiceMessageEntity.eaimessage.eaisvcdesc,

						errQServiceMessageEntity.eaimessage.eaisvcname,
						errQServiceMessageEntity.eaimessage.eaibzwkdstcd,
						errQServiceMessageEntity.eaimessage.eaisvcdesc)
				.orderBy(qTransformEntity.cnvsnname.asc())
				.fetch();

		List<TransformEaiMessage> transformEntities = tuples.stream().map(tuple -> {
			TransformEntity transformEntity = tuple.get(qTransformEntity);

			String eaisvcname = null;
			String eaibzwkdstcd = null;
			String eaisvcdesc = null;

			if (StringUtils.isNotBlank(tuple.get(reqQServiceMessageEntity.eaimessage.eaisvcname))) {
				eaisvcname = tuple.get(reqQServiceMessageEntity.eaimessage.eaisvcname);
				eaibzwkdstcd = tuple.get(reqQServiceMessageEntity.eaimessage.eaibzwkdstcd);
				eaisvcdesc = tuple.get(reqQServiceMessageEntity.eaimessage.eaisvcdesc);
			} else if (StringUtils.isNotBlank(tuple.get(resQServiceMessageEntity.eaimessage.eaisvcname))) {
				eaisvcname = tuple.get(resQServiceMessageEntity.eaimessage.eaisvcname);
				eaibzwkdstcd = tuple.get(resQServiceMessageEntity.eaimessage.eaibzwkdstcd);
				eaisvcdesc = tuple.get(resQServiceMessageEntity.eaimessage.eaisvcdesc);
			} else if (StringUtils.isNotBlank(tuple.get(errQServiceMessageEntity.eaimessage.eaisvcname))) {
				eaisvcname = tuple.get(errQServiceMessageEntity.eaimessage.eaisvcname);
				eaibzwkdstcd = tuple.get(errQServiceMessageEntity.eaimessage.eaibzwkdstcd);
				eaisvcdesc = tuple.get(errQServiceMessageEntity.eaimessage.eaisvcdesc);
			}

			return new TransformEaiMessage(transformEntity, eaisvcname, eaibzwkdstcd, eaisvcdesc);
		}).collect(Collectors.toList());

		return new PageImpl<>(transformEntities, pageable, totalCount);
	}

}
