<script lang="ts" setup>
import { computed, onMounted, ref } from 'vue'

interface errObj {
  blog?: object
  git?: object
}

const { $mitt } = useNuxtApp(),
  recentPosts = ref<IPost[] | null>(null),
  recentActivities = ref<IActivity[] | null>(null),
  isLoading = ref({
    blog: true,
    git: true,
  }),
  isError = ref({
    blog: false,
    git: false,
  }),
  errMsg = ref<errObj>({
    blog: undefined,
    git: undefined,
  }),

  getBlogRecentPost = get<IBlogResponse<IPostsData>, unknown>('/blog/index.php/api/posts', {
    params: {
      showDigest: 'excerpt',
      limit: 100,
    },
  }),
  getActivity = get<IActivity[], unknown>('/git/api/v1/users/cantyonion/activities/feeds', {
    params: {
      'limit': 10,
      'only-performed-by': true,
    },
  }),

  hasPosts = computed(() => (recentPosts.value ?? []).length > 0),
  hasActivities = computed(() => (recentActivities.value ?? []).length > 0),
  postsData = computed(() => {
    if (!recentPosts.value) {
      return []
    }
    if (recentPosts.value.length > 4) {
      return recentPosts.value.slice(0, 4)
    }
    return recentPosts.value
  }),
  activitiesData = computed((): IStrictActivity[] => {
    if (!Array.isArray(recentActivities.value)) {
      return []
    }
    return recentActivities.value.map((item) => {
      return {
        ...item,
        content: typeof item.content === 'string' && item.content ? JSON.parse(item.content) : null,
      }
    })
  }),

  reloadPosts = async () => {
    try {
      isLoading.value.blog = true
      isError.value.blog = false
      const postData = await getBlogRecentPost()
      if (postData !== null) {
        recentPosts.value = postData.data.dataSet
      }
    }
    catch (e) {
      isError.value.blog = true
      errMsg.value.blog = e as object
    }
    finally {
      isLoading.value.blog = false
    }
  },

  reloadActivities = async () => {
    try {
      isLoading.value.git = true
      isError.value.git = false
      recentActivities.value = await getActivity()
    }
    catch (e) {
      isError.value.git = true
      errMsg.value.git = e as object
    }
    finally {
      isLoading.value.git = false
    }
  }

await Promise.allSettled([reloadPosts(), reloadActivities()])

onMounted(() => {
  $mitt.emit('startLoading', false)
})
</script>

<template>
  <div class="main">
    <!--  个人介绍  -->
    <card-full-screen-intro-card />

    <div class="container mx-auto xl:max-w-screen-xl">
      <!-- 博客部分 -->
      <section class="w-full px-4 sm:px-0">
        <!-- 标题部分 -->
        <card-title
          :icon="['fas', 'blog']"
          title="最近文章"
        />

        <card-section-card
          :empty="!hasPosts"
          :error="isError.blog"
          :loading="isLoading.blog"
          :err-msg="errMsg.blog"
          @reload="reloadPosts"
        >
          <template #default>
            <div class="grid w-full grid-cols-1 gap-8 sm:grid-cols-2 lg:grid-cols-3">
              <card-article-card
                v-for="item in postsData"
                :key="item.cid"
                :post="item"
              />
            </div>
          </template>
        </card-section-card>
      </section>

      <!-- Git部分 -->
      <section class="my-4 w-full px-4 sm:px-0">
        <card-title
          :icon="['fas', 'code']"
          title="最近活动"
        />

        <card-section-card
          :empty="!hasActivities"
          :error="isError.git"
          :loading="isLoading.git"
          :err-msg="errMsg.git"
          @reload="reloadActivities"
        >
          <template #default>
            <div class="w-full rounded-xl bg-white divide-y divide-dashed">
              <card-git-card
                v-for="item in activitiesData"
                :key="item.id"
                :commit="item"
              />
            </div>
          </template>
        </card-section-card>
      </section>
    </div>
  </div>
</template>

<style scoped>

</style>
