package com.apobates.forum.core.impl.service;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.apobates.forum.core.api.dao.BoardTopicCategoryIndexDao;
import com.apobates.forum.core.api.dao.TopicCategoryDao;
import com.apobates.forum.core.api.service.BoardTopicCategoryIndexService;
import com.apobates.forum.core.entity.BoardTopicCategoryIndex;
import com.apobates.forum.core.entity.TopicCategory;

@Service
public class BoardTopicCategoryIndexServiceImpl implements BoardTopicCategoryIndexService{
	@Autowired
	private BoardTopicCategoryIndexDao boardTopicCategoryIndexDao;
	@Autowired
	private TopicCategoryDao topicCategoryDao;
	private final static Logger logger = LoggerFactory.getLogger(BoardTopicCategoryIndexServiceImpl.class);
	
	@Override
	public Stream<TopicCategory> getAllByBoardTopicCategories(final int boardGroupId, final long boardId) {
		CompletableFuture<Set<TopicCategory>> relatived = getAllByBoardAsync(boardGroupId, boardId).thenApply(tcs -> tcs.collect(Collectors.toSet()));
		CompletableFuture<Set<TopicCategory>> allCategories = CompletableFuture.supplyAsync(() -> topicCategoryDao.findUsed()).thenApply(tcs -> tcs.collect(Collectors.toSet()));
		return relatived.thenCombine(allCategories, (r, ar) -> {
			//未绑定使用全部
			Set<TopicCategory> result = (null == r || r.isEmpty()) ? ar : r;
			result.add(TopicCategory.empty());
			return result;
		}).join().stream();
	}
	
	@Override
	public int deleteForTopic(long boardId, List<Integer> categoryIds) {
		if(null == categoryIds || categoryIds.isEmpty()){
			return 0;
		}
		return boardTopicCategoryIndexDao.delete(boardId, categoryIds);
	}

	@Override
	public int create(int boardGroundId, long boardId, List<Integer> categoryIds) {
		if (null == categoryIds || categoryIds.isEmpty()) {
			return 0;
		}
		List<BoardTopicCategoryIndex> entities = categoryIds.stream().map(cateId -> new BoardTopicCategoryIndex(boardGroundId, boardId, cateId)).collect(Collectors.toList());
		try {
			return boardTopicCategoryIndexDao.batchSave(entities);
		} catch (Exception e) {
			if (logger.isDebugEnabled()) {
				logger.debug("批量关联版块类型失败", e);
			}
		}
		return -1;
	}

	@Override
	public Stream<TopicCategory> getAllByBoard(int boardGroundId, long boardId) {
		return boardTopicCategoryIndexDao.findAll(boardId, boardGroundId);
	}

	@Override
	public Optional<BoardTopicCategoryIndex> getReportRelativeRecord() {
		List<BoardTopicCategoryIndex> rs = boardTopicCategoryIndexDao.findAllByCategory(TopicCategory.report().getId()).collect(Collectors.toList());
		if(rs == null || rs.isEmpty()){
			return Optional.empty();
		}
		if(rs.size() > 1){
			return Optional.empty();
		}
		return Optional.ofNullable(rs.get(0));
	}

	@Override
	public Optional<BoardTopicCategoryIndex> getFeedbackRelativeRecord() {
		List<BoardTopicCategoryIndex> rs = boardTopicCategoryIndexDao.findAllByCategory(TopicCategory.feedback().getId()).collect(Collectors.toList());
		if(rs == null || rs.isEmpty()){
			return Optional.empty();
		}
		if(rs.size() > 1){
			return Optional.empty();
		}
		return Optional.ofNullable(rs.get(0));
	}

	@Override
	public Set<Integer> getAllRelativeRecords() {
		return boardTopicCategoryIndexDao.findAllByCategory(Arrays.asList(TopicCategory.report().getId(), TopicCategory.feedback().getId())).map(BoardTopicCategoryIndex::getCategoryId).collect(Collectors.toSet());
	}

	private CompletableFuture<Stream<TopicCategory>> getAllByBoardAsync(final int boardGroupId, final long boardId) {
		return CompletableFuture.supplyAsync(() -> boardTopicCategoryIndexDao.findAll(boardId, boardGroupId));
	}
}
