package com.eactive.eai.rms.onl.manage.control.log.servicegroup;

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

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.eactive.eai.data.entity.onl.message.QEAIMessageEntity;
import com.eactive.eai.data.entity.onl.restrict.QRestrictInfoLog;
import com.eactive.eai.rms.data.entity.onl.restrict.RestrictInfoLogService;
import com.eactive.eai.rms.onl.manage.control.log.ControlLogManUISearch;
import com.eactive.eai.rms.onl.manage.control.log.ControlLogService;
import com.eactive.eai.rms.onl.manage.control.log.ControlLogServiceDto;
import com.querydsl.core.Tuple;
import com.querydsl.jpa.impl.JPAQueryFactory;

@Service
public class ServiceGroupControlLogService extends RestrictInfoLogService implements ControlLogService {

	@PersistenceContext
	private EntityManager entityManager;

	public Page<ControlLogServiceDto> findALLGroupBy(Pageable pageable, ControlLogManUISearch uiSearch) {
		JPAQueryFactory jpaQueuryFactory = new JPAQueryFactory(entityManager);
		QRestrictInfoLog qLog = QRestrictInfoLog.restrictInfoLog;
		List<Tuple> groupByCount = jpaQueuryFactory
				.select(qLog.id.eaibzwkdstcd, qLog.eaisvcname, qLog.id.eaibzwkdstcd.count())
				.from(qLog)
				.where(qLog.id.msgdpstyms
						.between(uiSearch.getSearchStartDate() + BETWEEN_START_HHmmssSSS,
								uiSearch.getSearchEndDate() + BETWEEN_END_HHmmssSSS)
						.and(qLog.eaisvcname.isNotEmpty()))
				.groupBy(qLog.id.eaibzwkdstcd, qLog.eaisvcname)
				.orderBy(qLog.id.eaibzwkdstcd.asc(), qLog.eaisvcname.asc())
				.offset(pageable.getOffset())
				.limit(pageable.getPageSize())
				.fetch();

		List<ControlLogServiceDto> dtoList = tupleToDtoList(qLog, groupByCount);
		Map<String, String> eaiSvcDescMap = this.findEaiSvcDescOfLog(dtoList);
		for (ControlLogServiceDto dto : dtoList)
			dto.setEaisvcdesc(eaiSvcDescMap.get(dto.getEaisvcname()));

		long totalCount = jpaQueuryFactory
				.select(qLog.count())
				.from(qLog)
				.where(qLog.id.msgdpstyms
						.between(uiSearch.getSearchStartDate() + BETWEEN_START_HHmmssSSS,
								uiSearch.getSearchEndDate() + BETWEEN_END_HHmmssSSS)
						.and(qLog.eaisvcname.isNotEmpty()))
				.groupBy(qLog.id.eaibzwkdstcd, qLog.eaisvcname)
				.fetch()
				.size();

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

	public List<ControlLogServiceDto> findALLGroupBy(ControlLogManUISearch uiSearch) {
		JPAQueryFactory jpaQueuryFactory = new JPAQueryFactory(entityManager);
		QRestrictInfoLog qLog = QRestrictInfoLog.restrictInfoLog;
		List<Tuple> groupByCount = jpaQueuryFactory
				.select(qLog.id.eaibzwkdstcd, qLog.eaisvcname, qLog.id.eaibzwkdstcd.count())
				.from(qLog)
				.where(qLog.id.msgdpstyms
						.between(uiSearch.getSearchStartDate() + BETWEEN_START_HHmmssSSS,
								uiSearch.getSearchEndDate() + BETWEEN_END_HHmmssSSS)
						.and(qLog.eaisvcname.isNotEmpty()))
				.groupBy(qLog.id.eaibzwkdstcd, qLog.eaisvcname)
				.orderBy(qLog.id.eaibzwkdstcd.asc(), qLog.eaisvcname.asc())
				.fetch();
		List<ControlLogServiceDto> dtoList = tupleToDtoList(qLog, groupByCount);

		Map<String, String> eaiSvcDescMap = this.findEaiSvcDescOfLog(dtoList);
		for (ControlLogServiceDto dto : dtoList)
			dto.setEaisvcdesc(eaiSvcDescMap.get(dto.getEaisvcname()));

		return dtoList;
	}

	private List<ControlLogServiceDto> tupleToDtoList(QRestrictInfoLog qLog, List<Tuple> groupByCount) {
		return groupByCount.stream().map(tuple -> {
			ControlLogServiceDto dto = new ControlLogServiceDto();
			dto.setEaibzwkdstcd(tuple.get(qLog.id.eaibzwkdstcd));
			dto.setEaisvcname(tuple.get(qLog.eaisvcname));
			dto.setCnt(tuple.get(qLog.id.eaibzwkdstcd.count()).toString());
			return dto;
		}).collect(Collectors.toList());
	}

	private Map<String, String> findEaiSvcDescOfLog(List<ControlLogServiceDto> foundDtoList) {
		if (foundDtoList.isEmpty())
			return new HashMap<>();

		List<String> foundEaiSvcName = foundDtoList
				.stream()
				.map(dto -> dto.getEaisvcname())
				.distinct()
				.collect(Collectors.toList());
		QEAIMessageEntity qEAIMessageEntity = QEAIMessageEntity.eAIMessageEntity;
		JPAQueryFactory jpaQueuryFactory = new JPAQueryFactory(entityManager);
		List<Tuple> eaiMessageDescTupleList = jpaQueuryFactory
				.select(qEAIMessageEntity.eaisvcname, qEAIMessageEntity.eaisvcdesc)
				.from(qEAIMessageEntity)
				.where(qEAIMessageEntity.eaisvcname.in(foundEaiSvcName))
				.fetch();

		return eaiMessageDescTupleList
				.stream()
				.collect(Collectors
						.toMap(tuple -> tuple.get(qEAIMessageEntity.eaisvcname),
								tuple -> tuple.get(qEAIMessageEntity.eaisvcdesc)));
	}

}
