<template>
  <div
    class="fixed lg:right-5 right-5 top-70% -translate-y-50% flex flex-col items-center content-center gap-5 z-100"
  >
    <div class="flex flex-col bg-white rounded-8px shadow-md overflow-hidden">
      <div
        v-for="item in stats"
        :key="item.label"
        :content="item.label"
        placement="left"
        :show-after="300"
      >
        <div
          class="flex flex-col items-center justify-center w-56px h-56px transition-all duration-200 group"
          @click="handleClick(item as StatItem)"
        >
          <el-icon class="group-hover:text-blue-500! cursor-pointer" size="24">
            <component :is="item.icon" :active="item.active" />
          </el-icon>

          <span
            class="text-12px cursor-pointer group-hover:text-blue-500!"
            :style="{ color: item.active ? '#3b82f6' : '#606266' }"
          >
            {{ item.count }}
          </span>
        </div>
      </div>
    </div>
    <ScrollTopComp class="flex flex-col" />
  </div>
</template>
<script setup lang="tsx">
import type { ArticleItemDto } from '@/api'
import type { Component } from 'vue'
import { useScrollTop } from '@/hooks'
import { addOrCanceArticlelCollect, addOrCanceArticlelLike } from '@/api'
import { push } from 'notivue'
import { isWxShareCancel, wxShare } from '@/utils/wxUtil'

const modelValue = defineModel<ArticleItemDto>('modelValue', { required: true })

const emit = defineEmits<{
  (e: 'scrollToCommentBox'): void
}>()

const { ScrollTopComp } = useScrollTop(window)

interface StatItem {
  icon: Component
  count: number | string
  label: string
  active?: boolean
  actionFn?: () => Promise<void>
}

const stats = computed(() => {
  return [
    {
      icon: ({ active }: { active: boolean }) => (
        <SvgIcon name={active ? 'praise_fill' : 'praise'}></SvgIcon>
      ),
      count: modelValue.value?.praiseCount ?? 0,
      label: '点赞',
      active: modelValue.value?.hasPraised,
      api: addOrCanceArticlelLike,
      async actionFn() {
        await addOrCanceArticlelLike(modelValue.value.id)

        // 前端直接本地修改
        const isAdd = !modelValue.value.hasPraised
        modelValue.value.hasPraised = isAdd
        modelValue.value.praiseCount = isAdd
          ? modelValue.value.praiseCount + 1
          : modelValue.value.praiseCount - 1

        push.success(isAdd ? '点赞成功' : '取消点赞成功')
      },
    },
    {
      icon: ({ active }: { active: boolean }) => (
        <SvgIcon name={active ? 'collection_fill' : 'collection'}></SvgIcon>
      ),
      count: modelValue.value?.collectionCount ?? 0,
      label: '收藏',
      active: modelValue.value?.hasCollect,
      api: addOrCanceArticlelCollect,
      async actionFn() {
        await addOrCanceArticlelCollect(modelValue.value.id)
        // 前端直接本地修改
        const isAdd = !modelValue.value.hasCollect
        modelValue.value.hasCollect = isAdd
        modelValue.value.collectionCount = isAdd
          ? modelValue.value.collectionCount + 1
          : modelValue.value.collectionCount - 1
        push.success(isAdd ? '收藏成功' : '取消收藏成功')
      },
    },
    {
      icon: <SvgIcon name="comment"></SvgIcon>,
      count: modelValue.value?.replyCount ?? 0,
      label: '评论',
      // active: modelValue.value?.replyCount > 0,
      actionFn: () => {
        emit('scrollToCommentBox')
      },
    },
    {
      icon: <SvgIcon name="share" size="20"></SvgIcon>,
      count: '分享',
      label: '分享',
      async actionFn() {
        try {
          await wxShare({
            title: modelValue.value.title,
            desc: [modelValue.value.createUserName, modelValue.value.region].filter(Boolean).join('——'),
            imgUrl: modelValue.value.faceUrl || modelValue.value.imgUrl?.split(',').find(Boolean),
          })
          push.success('分享成功')
        } catch (error) {
          if (isWxShareCancel(error)) {
            console.warn(error)
            push.warning('取消分享')
            return
          }
          console.error(error)
          push.error('分享失败，请刷新页面重新分享')
        }
      },
    },
  ]
})

const handleClick = (item: StatItem) => {
  if (item.actionFn) {
    item.actionFn()
  }
}
</script>
