<template>
  <div class="page-comment">
    <main v-loading="loading">
      <div class="container-comment">
        <div class="title">
          <avatar-component :author="comment.user || {}">
            {{ timerDiff(comment.updatedAt) + $t("topic.before") }}..
          </avatar-component>
          <div v-show="comment.canHide" class="delete-comment">
            <div
              class="wrapper"
              @click="deleteComment({ id: comment._jv.id, type: 'comment' })"
            >
              <svg-icon type="trash" style="font-size: 16px" />
              <span>{{ $t("topic.delete") }}</span>
            </div>
          </div>
        </div>
        <topic-content
          :article="comment || {}"
          :paid-information="{ paid: true, price: 0 }"
          :thread-type="3"
          :category="{}"
          :video="{}"
        />
        <div class="thread-card">
          <avatar-component
            :size="40"
            round
            :author="(thread && thread.user) || {}"
          >
            {{ timerDiff(thread.createdAt) + $t("topic.before") }} ..
          </avatar-component>
          <div
            v-show="thread && thread.firstPost"
            class="content-html"
            v-html="
              (thread && thread.firstPost && $xss(thread.firstPost.summary)) ||
                ''
            "
          />
          <nuxt-link
            :to="`/thread/${thread._jv ? thread._jv.id : ''}`"
            class="view-more"
          >{{ $t("topic.viewDetail") }}</nuxt-link>
          <svg-icon
            v-if="thread && thread.isEssence"
            style="font-size: 50px;"
            type="essence-comment"
            class="essence"
          />
        </div>
        <div id="reply" class="container-reply">
          <comment-header
            v-if="replyCount"
            :comment-count="replyCount"
            :is-positive-sort="isPositiveSort"
            @changeSort="changeSort"
          />
          <div v-else class="without-comment">{{ $t("topic.noComment") }}</div>
          <editor
            v-if="afterPushReply"
            style="margin-top: 20px; margin-bottom: 20px"
            editor-style="comment"
            class="reply-editor"
            selector="reply-editor"
            :type-information="replyType"
            :post.sync="replyPost"
            :on-publish="onReplyPublish"
            @publish="replyPublish(comment._jv.id)"
          />
          <div v-loading="replyLoading">
            <reply-list
              :reply-list="replyList || []"
              @delete="deleteComment"
              @onLike="onLike"
            />
          </div>
          <list-load-more
            :loading="scrollLoading"
            :length="replyList.length"
            :has-more="replyCount > replyList.length"
            :page-num="pageNumber"
            @loadMore="getReplyList('scroll')"
          />
        </div>
      </div>
    </main>
    <topic-aside :author="(thread && thread.user) || {}" />
  </div>
</template>

<script>
const threadInclude = 'posts.replyUser,user.groups,user,posts,posts.user,posts.likedUsers'
  + ',posts.images,firstPost,firstPost.likedUsers,firstPost.images,firstPost.attachments'
  + ',rewardedUsers,category,threadVideo,paidUsers';
const commentInclude = 'user,likedUsers,commentPosts,commentPosts.user,commentPosts.user.groups'
  + ',commentPosts.replyUser,commentPosts.replyUser.groups,commentPosts.mentionUsers'
  + ',commentPosts.images,images,attachments';
const replyInclude = 'replyUser,user.groups,user,images';
import publishResource from '@/mixin/publishResource';
import postLegalityCheck from '@/mixin/postLegalityCheck';
import head from '@/mixin/head';
import handleError from '@/mixin/handleError';
import timerDiff from '@/mixin/timerDiff';
import isLogin from '@/mixin/isLogin';
import env from '@/utils/env';

export default {
  name: 'Comment',
  layout: 'custom_layout',
  mixins: [
    head,
    timerDiff,
    handleError,
    isLogin,
    publishResource,
    postLegalityCheck
  ],
  async asyncData({ store, query }) {
    if (!env.isSpider) {
      return {};
    }
    const threadId = query.threadId;
    const commentId = query.commentId;
    try {
      const thread = await store.dispatch('jv/get', [
        `threads/${threadId}`,
        { params: { include: threadInclude }}
      ]);
      const comment = await store.dispatch('jv/get', [
        `posts/${commentId}`,
        { params: { include: commentInclude }}
      ]);
      // TODO 暂时不用 SSR 避免出问题
      // const replyList = await store.dispatch('jv/get', [`posts`, {
      //   params: {
      //     'filter[thread]': threadId,
      //     'filter[reply]': commentId,
      //     'filter[isDeleted]': 'no',
      //     sort: '-createdAt',
      //     'filter[isComment]': 'yes',
      //     include: replyInclude
      //   }
      // }])
      // const { data: { included: commentIncluded }}
      // = await service.get(`posts/${commentId}`, { include: commentInclude })
      // if (comment && commentIncluded) comment.user
      // = commentIncluded.filter(item => item.type === 'users')[0].attributes
      return { thread, comment };
    } catch (e) {
      return { loading: true };
    }
  },
  data() {
    return {
      thread: {},
      comment: {},
      afterPushReply: true,
      pageLimit: 5,
      pageNumber: 1,
      replyCount: 0,
      isPositiveSort: true,
      replyList: [],
      replyLoading: false,
      scrollLoading: false,
      loading: false,
      onReplyPublish: false,
      replyPost: { text: '', imageList: [], attachedList: [] },
      replyType: {
        type: 10,
        textLimit: 5000,
        showPayment: false,
        showTitle: false,
        showImage: true,
        showVideo: false,
        showAttached: false,
        showEmoji: true,
        showTopic: false,
        showCaller: true,
        placeholder: '写下我的回复 ...'
      }
    };
  },
  computed: {
    threadId() {
      return this.$route.query.threadId;
    },
    commentId() {
      return this.$route.query.commentId;
    }
  },
  mounted() {
    if (Object.keys(this.comment).length === 0) {
      this.getComment().then(() => {
        this.loading = false;
      });
    }
    if (Object.keys(this.thread).length === 0) this.getThread();
    this.getReplyList('scroll');
  },
  methods: {
    getThread() {
      return this.$store
        .dispatch('jv/get', [
          `threads/${this.threadId}`,
          { params: { include: threadInclude }}
        ])
        .then(
          response => {
            if (response.isDeleted) return this.$router.push('/404');
            this.thread = response;
          },
          e => this.handleError(e)
        );
    },
    getComment() {
      return this.$store
        .dispatch('jv/get', [
          `posts/${this.commentId}`,
          { params: { include: commentInclude }}
        ])
        .then(
          response => {
            if (response.isDeleted) return this.$router.push('/404');
            // TODO replyCount 不包括审核中的评论
            this.replyCount = response.replyCount;
            this.comment = response;
          },
          e => this.handleError(e)
        );
    },
    getReplyList(type) {
      if (this.replyLoading) return;
      type === 'commit'
        ? (this.replyLoading = true)
        : (this.scrollLoading = true);
      return this.$store
        .dispatch('jv/get', [
          `posts`,
          {
            params: {
              'filter[thread]': this.threadId,
              'filter[reply]': this.commentId,
              'page[number]': this.pageNumber,
              'page[limit]': this.pageLimit,
              'filter[isDeleted]': 'no',
              'filter[isComment]': 'yes',
              sort: this.isPositiveSort ? 'createdAt' : '-createdAt',
              include: replyInclude
            }
          }
        ])
        .then(
          data => {
            this.replyList.push(...data);
            this.pageNumber += 1;
          },
          e => this.handleError(e)
        )
        .finally(() => {
          // eslint-disable-next-line no-multi-assign
          this.replyLoading = this.scrollLoading = false;
        });
    },
    changeSort(value) {
      this.scrollLoading = true;
      this.pageNumber = 1;
      this.replyList = [];
      this.isPositiveSort = value;
      this.getReplyList('commit');
    },
    deleteComment({ id, type }) {
      const params = {
        _jv: { type: `posts`, id },
        isDeleted: true
      };
      this.$confirm(
        this.$t('topic.confirmDelete'),
        this.$t('discuzq.msgBox.title'),
        {
          confirmButtonText: this.$t('discuzq.msgBox.confirm'),
          cancelButtonText: this.$t('discuzq.msgBox.cancel'),
          type: 'warning'
        }
      ).then(
        () => {
          return this.$store.dispatch('jv/patch', params).then(
            () => {
              if (type === 'comment') {
                this.$router.push(`/thread/${this.thread._jv.id}`);
              } else if (type === 'reply') {
                const deleteReply = this.replyList.filter(
                  item => item._jv.id === id
                )[0];
                this.replyList.splice(this.replyList.indexOf(deleteReply), 1);
                this.replyCount -= 1;
              }
              this.$message.success(this.$t('topic.deleteSuccess'));
            },
            e => this.handleError(e)
          );
        },
        () => console.log('取消删除')
      );
    },
    onLike({ reply, index }) {
      const params = {
        _jv: { type: `posts`, id: reply._jv.id },
        isLiked: !reply.isLiked,
        include: replyInclude
      };
      return this.$store.dispatch('jv/patch', params).then(
        data => {
          this.$set(this.replyList, index, data);
        },
        e => this.handleError(e)
      );
    },
    replyPublish(id) {
      if (!this.isLogin()) return;
      if (!this.replyPost.text) {
        return this.$message.warning(this.$t('post.theContentCanNotBeBlank'));
      }
      if (this.replyPost.text.length > this.replyType.textLimit) {
        return this.$message.warning(this.$t('post.messageLengthCannotOver'));
      }
      this.onReplyPublish = true;
      const replyParams = {
        _jv: {
          type: `posts`,
          relationships: {
            thread: { data: { type: 'threads', id: this.thread?._jv?.id }}
          }
        },
        isComment: true,
        replyId: id,
        content: this.replyPost.text
      };
      this.publishPostResource(replyParams, this.replyPost);
      return this.$store
        .dispatch('jv/post', replyParams)
        .then(
          response => {
            this.afterPushReply = false; // 重置编辑器
            this.$nextTick(() => {
              this.afterPushReply = true;
            });
            this.replyPost.text = '';
            this.replyPost.imageList = [];
            this.replyCount += 1;
            // false 倒序 true 正序， 倒叙是从最新到最旧
            if (this.isPositiveSort) {
              this.replyList.length === this.replyCount
                ? this.replyList.push(response)
                : '';
            } else {
              this.replyList.unshift(response);
            }
            this.postLegalityCheck(
              response,
              this.$t('topic.replyPublishSuccess')
            );
          },
          e => this.handleError(e)
        )
        .finally(() => {
          this.onReplyPublish = false;
        });
    }
  },
  head() {
    return {
      title: this.comment ? this.comment.summaryText : '评论详情页'
    };
  }
};
</script>

<style lang="scss" scoped>
@import "@/assets/css/variable/color.scss";

.page-comment {
  background: #f4f5f6;
  width: 100%;
  display: flex;
  justify-content: space-between;

  main {
    background: transparent;
    flex: 1;

    > .container-comment {
      border-radius: 3px;
      padding: 20px;
      width: 100%;
      background: #ffffff;

      > .title {
        height: 50px;
        display: flex;
        justify-content: space-between;

        > .delete-comment {
          > .wrapper {
            cursor: pointer;

            span {
              color: $font-color-grey;
            }
          }
        }
      }

      > .thread-card {
        position: relative;
        margin-top: 30px;
        width: 100%;
        padding: 15px;
        background: $background-color-grey;
        > .content-html {
          margin-top: 10px;
          margin-bottom: 20px;
          word-break: break-all;
        }
        > .view-more {
          position: absolute;
          right: 15px;
          bottom: 15px;
          color: $color-blue-base;
        }
        > .essence {
          position: absolute;
          top: -12px;
          right: 15px;
        }
      }

      > .container-reply {
        margin-top: 40px;
        > .without-comment {
          color: $font-color-grey;
          text-align: center;
        }
      }
    }
  }
}
</style>
