package com.eactive.eai.rms.onl.manage.control.history;

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

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

import org.springframework.beans.factory.annotation.Autowired;
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.adapter.QAdapterGroup;
import com.eactive.eai.data.entity.onl.message.QEAIMessageEntity;
import com.eactive.eai.data.entity.onl.restrict.QRestrictInfoHistory;
import com.eactive.eai.data.entity.onl.restrict.RestrictInfoHistory;
import com.eactive.eai.data.entity.onl.restrict.RestrictInfoHistoryId;
import com.eactive.eai.data.jpa.AbstractDataService;
import com.eactive.eai.data.jpa.BaseRepository;
import com.querydsl.core.Tuple;
import com.querydsl.jpa.impl.JPAQueryFactory;

@Service
public class ControlHistoryService extends
		AbstractDataService<RestrictInfoHistory, RestrictInfoHistoryId, BaseRepository<RestrictInfoHistory, RestrictInfoHistoryId>> {

	@PersistenceContext
	EntityManager entityManager;

	@Autowired
	ControlHistoryManMapper mapper;

	public Page<ControlHistoryServiceDto> findAll(Pageable pageable, ControlHistoryManUISearch uiSearch) {
		JPAQueryFactory jpaQueryFactory = new JPAQueryFactory(entityManager);
		QRestrictInfoHistory qHistory = QRestrictInfoHistory.restrictInfoHistory;
		QEAIMessageEntity qEaiMessageEntity = QEAIMessageEntity.eAIMessageEntity;

		List<Tuple> queryResult = jpaQueryFactory.select(qHistory, qEaiMessageEntity.eaisvcdesc).from(qHistory)
				.leftJoin(qEaiMessageEntity).on(qHistory.id.eaictrlname.eq(qEaiMessageEntity.eaisvcname))
				.where(qHistory.id.ctrlprcssyms.between(uiSearch.getSearchStartDate() + "000000000",
						uiSearch.getSearchEndDate() + "235959999"))
				.orderBy(qHistory.id.ctrlprcssyms.desc()).offset(pageable.getOffset()).limit(pageable.getPageSize())
				.fetch();

		List<String> osidinstinoList = queryResult.stream()
				.filter(tuple -> tuple.get(qHistory).getEaictrlnamedstcd().equals("2"))
				.map(tuple -> tuple.get(qHistory).getId().getEaictrlname()).distinct().collect(Collectors.toList());

		Map<String, String> adapterOsidInstiNoMap = findAdapterOsidInstiNoMap(jpaQueryFactory, osidinstinoList);

		List<ControlHistoryServiceDto> dtoList = toDto(qHistory, qEaiMessageEntity, queryResult, adapterOsidInstiNoMap);

		long count = jpaQueryFactory.select(qHistory.count()).from(qHistory).where(qHistory.id.ctrlprcssyms
				.between(uiSearch.getSearchStartDate() + "000000000", uiSearch.getSearchEndDate() + "235959999"))
				.fetchOne();

		return new PageImpl<>(dtoList, pageable, count);

	}

	public List<ControlHistoryServiceDto> findAll(ControlHistoryManUISearch uiSearch) {
		JPAQueryFactory jpaQueryFactory = new JPAQueryFactory(entityManager);
		QRestrictInfoHistory qHistory = QRestrictInfoHistory.restrictInfoHistory;
		QEAIMessageEntity qEaiMessageEntity = QEAIMessageEntity.eAIMessageEntity;

		List<Tuple> queryResult = jpaQueryFactory.select(qHistory, qEaiMessageEntity.eaisvcdesc).from(qHistory)
				.leftJoin(qEaiMessageEntity).on(qHistory.id.eaictrlname.eq(qEaiMessageEntity.eaisvcname))
				.where(qHistory.id.ctrlprcssyms.between(uiSearch.getSearchStartDate() + "000000000",
						uiSearch.getSearchEndDate() + "235959999"))
				.orderBy(qHistory.id.ctrlprcssyms.desc()).fetch();

		List<String> osidinstinoList = queryResult.stream()
				.filter(tuple -> tuple.get(qHistory).getEaictrlnamedstcd().equals("2"))
				.map(tuple -> tuple.get(qHistory).getId().getEaictrlname()).distinct().collect(Collectors.toList());

		Map<String, String> adapterOsidInstiNoMap = findAdapterOsidInstiNoMap(jpaQueryFactory, osidinstinoList);

		return toDto(qHistory, qEaiMessageEntity, queryResult, adapterOsidInstiNoMap);

	}

	private List<ControlHistoryServiceDto> toDto(QRestrictInfoHistory qHistory, QEAIMessageEntity qEaiMessageEntity,
			List<Tuple> queryResult, Map<String, String> adapterOsidInstiNoMap) {
		return queryResult.stream().map(tuple -> {
			RestrictInfoHistory restrictInfoHistory = tuple.get(qHistory);
			ControlHistoryServiceDto dto = mapper.toDto(restrictInfoHistory);
			String eaisvcdesc = tuple.get(qEaiMessageEntity.eaisvcdesc);
			if (eaisvcdesc != null)
				dto.setEaictrldesc(eaisvcdesc);

			String adptrbzwkgroupdesc = adapterOsidInstiNoMap.get(restrictInfoHistory.getId().getEaictrlname());
			if (adptrbzwkgroupdesc != null)
				dto.setEaictrldesc(adptrbzwkgroupdesc);

			return dto;
		}).collect(Collectors.toList());
	}
	
	private Map<String, String> findAdapterOsidInstiNoMap(JPAQueryFactory jpaQueryFactory,
			List<String> osidinstinoList) {
		QAdapterGroup qAdapterGroup = QAdapterGroup.adapterGroup;
		List<Tuple> adapterOsidInstiNoTuple = jpaQueryFactory
				.select(qAdapterGroup.osidinstino, qAdapterGroup.adptrbzwkgroupdesc).from(qAdapterGroup)
				.where(qAdapterGroup.osidinstino.in(osidinstinoList)).fetch();
		return adapterOsidInstiNoTuple.stream()
				.collect(Collectors.toMap(tuple -> tuple.get(qAdapterGroup.osidinstino).trim(),
						tuple -> tuple.get(qAdapterGroup.adptrbzwkgroupdesc), (p1, p2) -> p1));
	}
	
}
