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

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.utils.persistence.Page;
import com.apobates.forum.utils.persistence.Pageable;

public interface InboxService {
	/**
	 * 查看指定会员的收件箱,级联加载信件在收件箱中的状态(ForumLetterStatus)
	 * 
	 * @param memberId 会员ID/信件的收件人
	 * @param pageable 分页请求参数
	 * @return
	 */
	Page<ForumLetter> getInBox(long memberId, Pageable pageable);
	Page<ForumLetter> getInBoxGroupSender(long memberId, Pageable pageable);
	
	/**
	 * 查看指定会员的收件箱,级联加载信件在收件箱中的状态(ForumLetterStatus)
	 * 
	 * @param memberId 会员ID/信件的收件人
	 * @param label    信件类型
	 * @param pageable 分页请求参数
	 * @return
	 */
	Page<ForumLetter> getInBox(long memberId, ForumLetterTypeEnum label, Pageable pageable);
	
	/**
	 * 查看未读的信件(不包含删除的)
	 * 
	 * @param memberId 会员ID/信件的收件人
	 * @param size     显示的数量
	 * @return
	 */
	Stream<ForumLetter> getReadableMessages(long memberId, int size);
	
	/**
	 * 查看发件人发来的所有信件
	 * 只包含发件人发来的信件.会员回复的信件不包含在内
	 * 
	 * @param sender   信件的发件人
	 * @param memberId 会员ID/信件的收件人
	 * @return
	 */
	Stream<ForumLetter> get(long sender, long memberId);
	
	/**
	 * 查看发件人发来的所有信件,自参考日期往后的信件
	 * 只包含发件人发来的信件.会员回复的信件不包含在内
	 * 
	 * @param sender        信件的发件人
	 * @param memberId      会员ID/信件的收件人
	 * @param prevUnixStamp 参考日期
	 * @return
	 */
	Stream<ForumLetter> get(long sender, long memberId, int prevUnixStamp);
	
	/**
	 * 将发件人发送的信件全部标记为阅读
	 * 
	 * @param memberId 会员ID/信件的收件人
	 * @param sender   信件的发件人
	 * @return
	 */
	Optional<Boolean> readed(long memberId, long sender);
	
	/**
	 * 删除指定的信件
	 * 
	 * @param memberId 会员ID/信件的收件人
	 * @param idList   信件记录ID列表ForumLetter.id(!= Inbox.id)
	 * @return
	 */
	int remove(long memberId, List<Long> idList)throws IllegalStateException;
	
	/**
	 * 阅读指定的信件
	 * 
	 * @param memberId 会员ID/信件的收件人
	 * @param idList   信件记录ID列表ForumLetter.id(!= Inbox.id)
	 * @return
	 */
	int readed(long memberId, List<Long> idList)throws IllegalStateException;
	
	/**
	 * 将收件人的未读信件标记为阅读
	 * 
	 * @param memberId 会员ID/信件的收件人
	 * @return
	 */
	int readed(long memberId);

	/**
	 * 复合标记为已读,复合(int readed(long) || Optional<Boolean> readed(long, long))
	 *
	 * @param memberId 主向会员
	 * @param othMemberId
	 * @param direction 方向
	 * @return
	 */
	Optional<Boolean> compositeReaded(long memberId, long othMemberId, int direction);

	/**
	 * 查看未读的信件数量(不包含删除的)
	 * 
	 * @param memberId 会员ID/信件的收件人
	 * @return
	 */
	long countForMemberMessages(long memberId);
	
	/**
	 * 分组统计指定发件人未读的信件数量
	 * 
	 * @param memberId    会员ID/信件的收件人
	 * @param senderIdSet 信件的发件人ID集合
	 * @return Key=信件的发件人ID, Value=收件人未读的信件数量
	 */
	Map<Long,Long> groupForMemberMessages(long memberId, Set<Long> senderIdSet);
}
