package com.apobates.forum.letterbox.api.dao;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
import com.apobates.forum.letterbox.entity.ForumLetter;
import com.apobates.forum.letterbox.entity.ForumLetterTypeEnum;
import com.apobates.forum.letterbox.entity.Inbox;
import com.apobates.forum.utils.persistence.Page;
import com.apobates.forum.utils.persistence.Pageable;
import com.apobates.forum.utils.persistence.PagingAndSortingRepository;

public interface InboxDao extends PagingAndSortingRepository<ForumLetter,Long>{
	/**
	 * 查看指定会员收到的信件,已删除的不显示
	 * 
	 * @param memberId 收件人/会员ID
	 * @param pageable 分页请求参数
	 * @return
	 */
	Page<ForumLetter> findAllByReceiver(long memberId, Pageable pageable);
	
	/**
	 * 查看指定会员收到的信件,已删除的不显示.分组发件人,每个发件只出现最近的一条信件
	 * 
	 * @param memberId 收件人/会员ID
	 * @param pageable 分页请求参数
	 * @return
	 */
	Page<ForumLetter> findAllByReceiverGroupSender(long memberId, Pageable pageable);
	
	/**
	 * 查看指定会员收到的信件,已删除的不显示
	 * 
	 * @param memberId 收件人/会员ID
	 * @param typed    信件类型
	 * @param pageable 分页请求参数
	 * @return
	 */
	Page<ForumLetter> findAllByReceiverAndType(long memberId, ForumLetterTypeEnum typed, Pageable pageable);
	
	/**
	 * 查看指定会员寄来的所有信件
	 * 
	 * @param sender   发件人/会员ID
	 * @param memberId 收件箱的主人/会员ID
	 * @return
	 */
	Stream<ForumLetter> findAll(long sender, long memberId);
	Stream<ForumLetter> findAll(long sender, long memberId, LocalDateTime startDateTime);
	
	/**
	 * 查看指定会员未读的信件
	 * 
	 * @param memberId 收件人/会员ID
	 * @param size     显示的数量
	 * @return
	 */
	Stream<ForumLetter> findAllForUnReadable(long memberId, int size);
	
	/**
	 * 查看指定信件的到达记录
	 * 
	 * @param letterIdSet 信件记录ID列表ForumLetter.id(!= Inbox.id)
	 * @return
	 */
	Stream<Inbox> findAllByLetter(Collection<Long> letterIdSet);
	
	/**
	 * 将发件人发送的信件全部标记为阅读
	 * 
	 * @param memberId 收件人
	 * @param sender   发件人
	 * @return
	 */
	Optional<Boolean> editReadabled(long memberId, long sender);
	
	/**
	 * 将指定的未读信件标记为已读
	 * 
	 * @param memberId     收件人
	 * @param letterIdList 信件记录ID列表ForumLetter.id(!= Inbox.id)
	 * @return
	 */
	int editReadabled(long memberId, List<Long> letterIdList);
	
	/**
	 * 将收件人的未读信件标记为阅读
	 * 
	 * @param memberId 收件人
	 * @return
	 */
	int editReadabled(long memberId);
	
	/**
	 * 将指定的未读信件标记为删除
	 * 
	 * @param memberId     收件人
	 * @param letterIdList 信件记录ID列表ForumLetter.id(!= Inbox.id)
	 * @return
	 */
	int editDeleted(long memberId, List<Long> letterIdList);
	
	/**
	 * 批量保存多条收件箱信件到达记录
	 * 
	 * @param letterEntryRecords 信件到达记录
	 * @return
	 */
	int batchSave(Set<Inbox> letterEntryRecords);
	
	/**
	 * 查看指定会员未读的信件数量
	 * 
	 * @param memberId 收件人/会员ID
	 * @return
	 */
	long countForUnReadable(long memberId);
	
	/**
	 * 统计指定发件人的未读信件数量
	 * 
	 * @param memberId    收件人
	 * @param senderIdSet 发件人ID集合
	 * @return Key = 发件人ID, Value = 收件人未读信件的数量
	 */
	Map<Long,Long> groupForUnReadable(long memberId, Set<Long> senderIdSet);
}
