<template>
    <div>
        <main-nav title="泡泡详情" :back="true" />

        <n-list class="main-content-wrap" bordered>
            <n-list-item>
                <n-spin :show="loading">
                    <div class="detail-wrap" v-if="post.id > 1">
                        <post-detail :post="post" @reload="loadPost" />
                    </div>
                    <div class="empty-wrap" v-else>
                        <n-empty size="large" description="暂无数据" />
                    </div>
                </n-spin>
            </n-list-item>
            <div class="comment-opts-wrap" v-if="post.id > 0">
                <n-tabs type="bar" justify-content="end" size="small" animated @update:value="commentTab">
                    <template #prefix>
                        <span class="comment-title-item">评论</span>
                    </template>
                    <n-tab-pane name="default" tab="默认" />
                    <n-tab-pane name="newest" tab="最新" />
                </n-tabs>
            </div>
            <n-list-item v-if="post.id > 0">
                <compose-comment :lock="post.is_lock" :post-id="post.id" @post-success="reloadComments" />
            </n-list-item>

            <div v-if="post.id > 0">
                <div v-if="commentLoading" class="skeleton-wrap">
                    <post-skeleton :num="5" />
                </div>
                <div v-else>
                    <div class="empty-wrap" v-if="comments.length === 0">
                        <n-empty size="large" description="暂无评论，快来抢沙发" />
                    </div>

                    <n-list-item v-for="comment in comments" :key="comment.id">
                        <comment-item :comment="comment" @reload="reloadComments" />
                    </n-list-item>
                </div>
            </div>
            <n-space justify="center">
                <InfiniteLoading class="load-more" v-if="comments.length > 0" :slots="{complete: '没有更多数据了', error: '加载出错'}" @infinite="loadComments">
                    <template #spinner>
                        <span v-if="defaultCommentsSort && defaultNoMore" class="load-more-spinner" ><!-- 注意一定要保留这里 --></span>
                        <span v-if="!defaultCommentsSort && newestNoMore" class="load-more-spinner" ><!-- 注意一定要保留这里 --></span>
                        <span v-if="defaultCommentsSort && !defaultNoMore" class="load-more-spinner" >加载评论</span>
                        <span v-if="!defaultCommentsSort && !newestNoMore" class="load-more-spinner" >加载评论</span>
                    </template>
                </InfiniteLoading>
            </n-space>
        </n-list>
    </div>
</template>

<script setup lang="ts">
import { ref, watch, onMounted, computed } from 'vue';
import { useRoute } from 'vue-router';
import { getPost, getPostComments } from '@/api/post';
import InfiniteLoading from "v3-infinite-loading";
import "v3-infinite-loading/lib/style.css";

const route = useRoute();
const post = ref<Item.PostProps>({} as Item.PostProps);
const loading = ref(false);
const commentLoading = ref(false);
const comments = ref<Item.CommentProps[]>([]);
const postId = computed(() => +(route.query.id as string));
const sortStrategy = ref<"default" | "newest">('default');
const defaultCommentsSort = ref<boolean>(true)
const pageSize = 20

let stateHandler = ({
  loading() {
    //nothing
  },
  loaded() {
    // nothing
  },
  complete() {
    // nothing
  },
  error() {
    // nothing
  },
});

const commentTab = (tab: "default" | "newest") => {
    sortStrategy.value = tab;
    if (tab === "default") {
        defaultCommentsSort.value = true
    }
    loadComments(stateHandler);
};

const loadPost = () => {
    post.value = {
        id: 0,
    } as Item.PostProps;
    loading.value = true;
    getPost({
        id: postId.value,
    })
        .then((res) => {
            loading.value = false;
            post.value = res;

            // 加载评论
            loadComments(stateHandler);
        })
        .catch((err) => {
            loading.value = false;
        });
};

let defaultCommmentsPage = 1;
const defaultNoMore = ref<boolean>(false)
const defaultComments = ref<Item.CommentProps[]>([]);
const loadDefaultComments = ($state: any) => {
    if (defaultNoMore.value) {
        return
    }

    getPostComments({
        id: post.value.id as number,
        sort_strategy: 'default',
        page: defaultCommmentsPage,
        page_size: pageSize,
    })
    .then((res) => {
        if ($state !== null) {
            stateHandler = $state
        }
        if (res.list.length < pageSize) {
            defaultNoMore.value = true
        } else {
            defaultCommmentsPage++
        }
        if (res.list.length > 0)  {
            if (defaultCommmentsPage === 1) {
                defaultComments.value = res.list;
            } else {
                defaultComments.value.push(...res.list);
            }
            comments.value = defaultComments.value
        }
        stateHandler.loaded();
        commentLoading.value = false;
    })
    .catch((err) => {
        commentLoading.value = false;
        stateHandler.error();
    });
};

let newestCommmentsPage = 1;
let newestNoMore = ref<boolean>(false)
const newestComments=ref<Item.CommentProps[]>([]);
const loadNewestComments = ($state: any) => {
    if (newestNoMore.value) {
        return
    }

    getPostComments({
        id: post.value.id as number,
        sort_strategy: 'newest',
        page: newestCommmentsPage,
        page_size: pageSize,
    })
    .then((res) => {
        if ($state !== null) {
            stateHandler = $state
        }
        if (res.list.length < pageSize) {
            newestNoMore.value = true
        } else {
            newestCommmentsPage++
        }
        if (res.list.length > 0) {
            if (newestCommmentsPage === 1) {
                newestComments.value = res.list;
            } else {
                newestComments.value.push(...res.list);
            }
            comments.value = newestComments.value
        }
        stateHandler.loaded();
        commentLoading.value = false;
    })
    .catch((err) => {
        commentLoading.value = false;
        stateHandler.error();
    });
};

const loadComments = ($state: any) => {
    if (postId.value < 1) {
        return
    }
    if (comments.value.length === 0) {
        commentLoading.value = true;
    }
    if (sortStrategy.value === 'default') {
        comments.value = defaultComments.value
        loadDefaultComments($state)
    } else {
        comments.value = newestComments.value
        loadNewestComments($state)
    }
    commentLoading.value = false;
};

const reloadComments = () => {
    // 这里需要做特殊处理,目前暴力处理，一切都重新加载
    // TODO：后续持续优化， 这里有大bug！！！
    defaultCommmentsPage = 1;
    defaultNoMore.value = false
    defaultComments.value = []

    newestCommmentsPage = 1;
    newestNoMore.value = false
    newestComments.value = []

    loadComments(stateHandler)
}

onMounted(() => {
    loadPost();
});

watch(postId, () => {
    if (postId.value > 0 && route.name === 'post') {
        loadPost();
    }
});
</script>

<style lang="less" scoped>
.detail-wrap {
    min-height: 100px;
}

.comment-opts-wrap {
    padding-top: 6px;
    padding-left: 16px;
    padding-right: 16px;
    opacity: 0.75;

    .comment-title-item {
        padding-top: 4px;
        font-size: 16px;
        text-align: center;
    }
}

.main-content-wrap {
    .load-more {
        margin-bottom: 8px;
        .load-more-spinner {
            font-size: 14px;
            opacity: 0.65;
        }
    }
}


.dark {
    .main-content-wrap,
    .skeleton-wrap {
        background-color: rgba(16, 16, 20, 0.75);
    }
}
</style>