package com.eactive.eai.rms.onl.manage.adapter.messagekey;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.eactive.eai.data.entity.onl.messagekey.MessageKey;
import com.eactive.eai.data.entity.onl.messagekey.MessageKeyId;
import com.eactive.eai.rms.common.base.BaseService;
import com.eactive.eai.rms.data.entity.onl.messagekey.MessageKeyService;

import lombok.NonNull;

@Service
@Transactional
public class MessageKeyManService extends BaseService {

	private MessageKeyService messageKeyService;

	private MessageKeyUIMapper messageKeyUIMapper;

	private MessageKeyUIFieldMapper messageKeyUIFieldMapper;

	@Autowired
	@NonNull
	public MessageKeyManService(MessageKeyService messageKeyService, MessageKeyUIMapper messageKeyUIMapper, MessageKeyUIFieldMapper messageKeyUIFieldMapper) {
		this.messageKeyService = messageKeyService;
		this.messageKeyUIMapper = messageKeyUIMapper;
		this.messageKeyUIFieldMapper = messageKeyUIFieldMapper;
	}

	public Page<MessageKeyUI> selectList(Pageable pageable, String searchAdptrBzwkGroupName, String searchIoDstcd) {
		return messageKeyService
				.findAll(pageable, searchAdptrBzwkGroupName, searchIoDstcd)
				.map(messageKeyUIMapper::toVo);
	}

	public List<Map<String, Object>> selectListToExcel(String searchAdptrBzwkGroupName, String searchIoDstcd) {

		Pageable pageable = Pageable.unpaged();
		pageable.getSort().and(Sort.by("id"));

		return selectList(pageable, searchAdptrBzwkGroupName, searchIoDstcd).stream().map(messageKeyUI -> {
			Map<String, Object> map = new HashMap<>();
			map.put("ADPTRBZWKGROUPNAME", messageKeyUI.getAdptrBzwkGroupName());
			map.put("MSGDSTCD", messageKeyUI.getMsgDstcd());
			map.put("IODSTCDTEXT", messageKeyUI.getIodstcdtext());
			map.put("GROUPINORNO", messageKeyUI.getGroupInorNo());
			map.put("BZWKFLDNAMETEXT", messageKeyUI.getBzwkfldnameText());
			map.put("NOMALPRCSSCTNT", messageKeyUI.getNomalprcssctnt());
			return map;
		}).collect(Collectors.toList());
	}

	public List<MessageKeyUI> selectDetail(String adptrBzwkGroupName, String msgDstcd, String ioDstcd,
			Integer groupInorNo) {
		List<MessageKey> list = messageKeyService.findAll(adptrBzwkGroupName, msgDstcd, ioDstcd, groupInorNo);

		return list.stream().map(messageKeyUIMapper::toVo).collect(Collectors.toList());

	}

	public void update(MessageKeyUI messageKeyUI) {

		Map<MessageKeyId, MessageKey> newMessageKeys = messageKeyUIFieldMapper
				.toMessageKeyMap(messageKeyUI.getAdptrBzwkGroupName(), messageKeyUI.getMsgDstcd(),
						messageKeyUI.getIoDstcd(), messageKeyUI.getGroupInorNo(), messageKeyUI.getGridData());

		Map<MessageKeyId, MessageKey> oldMessageKeys = messageKeyService
				.findAll(messageKeyUI.getAdptrBzwkGroupName(), messageKeyUI.getMsgDstcd(), messageKeyUI.getIoDstcd(),
						messageKeyUI.getGroupInorNo())
				.stream()
				.collect(Collectors.toMap(MessageKey::getId, old -> old));

		// newMessageKey에 포함 되지 않은 oldMessageKey는 삭제
		oldMessageKeys
				.values()
				.stream()
				.filter(old -> !newMessageKeys.containsKey(old.getId()))
				.forEach(messageKeyService::delete);

		// update
		oldMessageKeys.values().stream().filter(old -> newMessageKeys.containsKey(old.getId())).forEach(old -> {
			messageKeyUIMapper.updateMessageKey(newMessageKeys.get(old.getId()), old);
			newMessageKeys.put(old.getId(), old);
		});

		// save
		messageKeyService.saveAll(newMessageKeys.values());

	}

	public void insert(MessageKeyUI messageKeyUI) {

		int groupInorNo = messageKeyService
				.getLastGroupKey(messageKeyUI.getAdptrBzwkGroupName(), messageKeyUI.getMsgDstcd(),
						messageKeyUI.getIoDstcd());

		Collection<MessageKey> newMessageKeys = messageKeyUIFieldMapper
				.toMessageKeyMap(messageKeyUI.getAdptrBzwkGroupName(), messageKeyUI.getMsgDstcd(),
						messageKeyUI.getIoDstcd(), messageKeyUI.getGroupInorNo(), messageKeyUI.getGridData())
				.values();

		newMessageKeys.forEach(newMessageKey -> newMessageKey.getId().setGroupinorno(groupInorNo));

		messageKeyService.saveAll(newMessageKeys);
	}

	public long delete(MessageKeyUI messageKeyUI) {
		Map<MessageKeyId, MessageKey> oldMessageKeys = messageKeyService
				.findAll(messageKeyUI.getAdptrBzwkGroupName(), messageKeyUI.getMsgDstcd(), messageKeyUI.getIoDstcd(),
						messageKeyUI.getGroupInorNo())
				.stream()
				.collect(Collectors.toMap(MessageKey::getId, old -> old));

		messageKeyService.deleteAll(oldMessageKeys.values());

		return messageKeyService
				.countByAdptrBzwkGroupNameAndIoDstcd(messageKeyUI.getAdptrBzwkGroupName(), messageKeyUI.getIoDstcd());
	}

}
