package com.apobates.forum.thrones.event;

import com.github.davidmarquis.redisq.Message;
import com.github.davidmarquis.redisq.consumer.MessageListener;
import com.github.davidmarquis.redisq.consumer.retry.RetryableMessageException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.apobates.forum.core.entity.Posts;
import com.apobates.forum.core.entity.Topic;
import com.apobates.forum.core.entity.proxy.PostsReplica;
import com.apobates.forum.core.entity.proxy.TopicReplica;
import com.apobates.forum.core.impl.event.PostsPublishEvent;
import com.apobates.forum.core.service.PostsService;
import com.apobates.forum.letterbox.entity.ForumLetter;
import com.apobates.forum.letterbox.entity.ForumLetterReceiver;
import com.apobates.forum.letterbox.service.ForumLetterService;
import org.springframework.stereotype.Component;
import java.util.List;

/**
 * 回复的引用通知
 *
 * @author xiaofanku
 * @since 20200301
 */
@Component("postsQuoteNotice")
public class PostsQuoteNoticeListener implements MessageListener<PostsPublishEvent> {
    @Autowired
    private PostsService postsService;
    @Autowired
    private ForumLetterService forumLetterService;
    private final static Logger logger = LoggerFactory.getLogger(PostsQuoteNoticeListener.class);
    
    @Override
    public void onMessage(Message<PostsPublishEvent> event) throws RetryableMessageException {
        logger.info("[Posts][PublishEvent][3]回复动作引用处理开始");
        Posts posts = event.getPayload().getPosts();
        //回复中是否能提取引用的cite
        long quotePostsId = parseBlockquoteTag(posts.getContent());
        if (quotePostsId <= 0) {
            logger.info("[Posts][PublishEvent][3]回复中无引用记录");
            return;
        }
        logger.info("[Posts][PublishEvent][3]引用的回复ID: " + quotePostsId);
        //被引用的回复
        PostsReplica quotePosts = postsService.get(quotePostsId, posts.getTopicId()).orElse(null);
        if (null != quotePosts) {
            try {
                forumLetterService.create(
                        getQuoteNotice(quotePosts.getTopic(), posts, quotePosts.getFloorNumber()),
                        List.of(new ForumLetterReceiver(quotePosts.getMemberId(), quotePosts.getMemberNickname())));
            } catch (Exception e) {}
        }
        logger.info("[Posts][PublishEvent][3]回复动作引用处理结束");
    }
    //生成引用通知
    private ForumLetter getQuoteNotice(Topic topic, Posts posts, long authorReplyFloor) {
        String floorLink = String.format("/topic/%s.xhtml#posts-%d", TopicReplica.generateConnectString(topic.getId(), topic.getBoardId(), topic.getVolumesId()), posts.getId());
        return ForumLetter.noticeLetter(
                posts.getMemberNickname() + "引用了您的回复",
                String.format(
                        "<p><a href=\"/member/%d.xhtml\">%s</a>引用了您在<a href=\"%s\">#%s#</a>%d楼发布的回复内容</p>",
                        posts.getMemberId(),
                        posts.getMemberNickname(),
                        floorLink,
                        topic.getTitle(),
                        authorReplyFloor));
    }
    //提取blockquote属性的cite
    private long parseBlockquoteTag(String postsContent) {
        Document doc = Jsoup.parse(postsContent);
        Element quoteTag = doc.selectFirst("blockquote");
        if (null == quoteTag) {
            return -1L;
        }
        Element quoteAnchor = quoteTag.selectFirst("a");
        if (null == quoteAnchor) {
            return 0L;
        }
        try {
            String quoteAnchorHref = quoteAnchor.attr("href");
            return Long.valueOf(quoteAnchorHref.substring(quoteAnchorHref.lastIndexOf("#posts-") + 7));
        } catch (Exception e) {
            return -2L;
        }
    }
}