<template>
  <div
    ref="commentRef"
    class="bg-white rounded-lg shadow-sm border border-white/50 overflow-hidden"
  >
    <!-- 评论筛选 -->
    <div class="p-4 border-b border-gray-100">
      <div class="flex items-center gap-4 justify-between">
        <span class="text-lg font-semibold text-gray-800">评论 ({{ total }})</span>
        <div class="flex items-center gap-2">
          <button
            class="cursor-pointer px-3 py-1.5 text-sm transition-all relative"
            @click="((searchParams.sortType = 2), refresh())"
            :class="{
              'text-indigo-600 font-medium': searchParams.sortType === 2,
              'text-gray-600 hover:text-gray-900': searchParams.sortType !== 2,
            }"
          >
            最新
            <span
              v-if="searchParams.sortType === 2"
              class="absolute bottom-0 left-0 right-0 h-0.5 bg-indigo-600"
            ></span>
          </button>
          <button
            class="cursor-pointer px-3 py-1.5 text-sm transition-all relative"
            @click="((searchParams.sortType = 4), refresh())"
            :class="{
              'text-indigo-600 font-medium': searchParams.sortType === 4,
              'text-gray-600 hover:text-gray-900': searchParams.sortType !== 4,
            }"
          >
            最多点赞
            <span
              v-if="searchParams.sortType === 4"
              class="absolute bottom-0 left-0 right-0 h-0.5 bg-indigo-600"
            ></span>
          </button>
          <button
            class="cursor-pointer px-3 py-1.5 text-sm transition-all relative"
            @click="((searchParams.sortType = 1), refresh())"
            :class="{
              'text-indigo-600 font-medium': searchParams.sortType === 1,
              'text-gray-600 hover:text-gray-900': searchParams.sortType !== 1,
            }"
          >
            最多评论
            <span
              v-if="searchParams.sortType === 1"
              class="absolute bottom-0 left-0 right-0 h-0.5 bg-indigo-600"
            ></span>
          </button>

          <!-- <Tabs v-model="searchParams.sortType" :tabs="tabs" /> -->
        </div>
      </div>
    </div>

    <div>
      <!-- 发表评论 -->
      <div class="p-4 border-b border-gray-100">
        <div class="flex gap-3">
          <img
            :src="userAvatar"
            alt=""
            class="w-10 h-10 rounded-full object-cover cursor-pointer"
            @click="jumpToUserHomePage({ userId: userInfo.userId, type })"
          />
          <CommentBox
            v-model:inputText="myComment"
            v-model:inputImg="myCommentImgStr"
            class="flex-1"
          >
            <template #submit>
              <button
                type="button"
                class="comment-publish-btn cursor-pointer disabled:opacity-50 px-6 py-2 text-white rounded-full text-sm hover:shadow-lg transition-all"
                :disabled="!myComment?.trim() || loading"
                @click="handleMyComment"
              >
                <div v-show="myCommentLoading" class="flex items-center gap-2">
                  <el-icon><IEpLoading /></el-icon>
                  <span>发表中...</span>
                </div>
                <div v-show="!myCommentLoading">发表</div>
              </button>
            </template>
          </CommentBox>
        </div>
      </div>
      <!-- 分割线 -->

      <!-- 评论列表 -->
      <div v-loading="loading" class="divide-y divide-gray-100">
        <div v-show="list.length">
          <div
            v-for="(item, index) in list"
            :key="item.id"
            :ref="(el) => (commentItemRefList[index] = el as HTMLElement)"
          >
            <div class="p-4 transition-colors">
              <div class="flex gap-3">
                <img
                  @click="jumpToUserHomePage({ userId: item.userId, type })"
                  :src="isReal ? item.avatar : item.hiddenAvatar"
                  alt=""
                  class="w-10 h-10 rounded-full object-cover cursor-pointer"
                />
                <div class="flex-1">
                  <div class="flex items-center gap-2 mb-2">
                    <span class="font-semibold text-gray-800">{{
                      isReal ? item.replyUser : item.hiddenName
                    }}</span>
                    <!-- <span
                    class="px-2 py-0.5 text-xs bg-gradient-to-r from-purple-100 to-blue-100 text-purple-600 rounded-full"
                  >
                    技术专家
                  </span> -->
                    <!-- <span class="px-2 py-0.5 text-xs bg-red-100 text-red-600 rounded-full">置顶</span> -->
                  </div>
                  <!-- 换行 -->
                  <p
                    class="text-gray-800 my-2 break-all whitespace-pre-wrap"
                    v-html="parseEmoji(item.content)"
                  ></p>
                  <!-- 评论图片列表 -->
                  <div class="flex flex-wrap gap-2">
                    <div
                      v-for="(img, imgIndex) in item.imgUrl.split(',').filter(Boolean)"
                      :key="imgIndex"
                      class="w-20 h-20 rounded-lg overflow-hidden mb-2 cursor-pointer"
                    >
                      <el-image
                        :src="img"
                        :preview-teleported="true"
                        class="w-full h-full object-cover"
                        :preview-src-list="item.imgUrl.split(',').filter(Boolean)"
                        :initial-index="imgIndex"
                        fit="cover"
                      />
                    </div>
                  </div>
                  <div class="flex items-center justify-between">
                    <div class="flex items-center gap-6 text-gray-500">
                      <span class="flex items-center gap-2 text-[14px]">
                        <span
                          >{{ dayjs(item.createTime * 1000).format('YYYY-MM-DD HH:mm:ss') }}
                        </span>
                        <span>·</span>
                        <span class="text-gray-500">{{ item.region }}</span>
                      </span>
                      <div class="flex gap-2 items-center hover:text-blue-500">
                        <div
                          class="flex items-center gap-1 cursor-pointer"
                          @click="handleLickComment(item)"
                        >
                          <el-icon :size="16">
                            <svg-icon :name="item.hasPraise ? 'praise_fill' : 'praise'"></svg-icon>
                          </el-icon>
                          <span>{{ item.postPriseCount }}</span>
                        </div>
                      </div>
                      <button
                        class="cursor-pointer hover:text-blue-500 transition-colors text-[14px]"
                        @click="handleReply(item, index)"
                      >
                        回复
                      </button>
                    </div>
                  </div>
                  <!-- 回复列表 -->
                  <!-- 问吧 和 其他 做区分 -->
                  <template v-if="!isQuestion">
                    <div v-if="item.children?.length" class="mt-3 ml-4 space-y-3">
                      <!-- 回复评论的内容 里面可能是 展示全部的 也有可能是展示5条之内容 -->
                      <div
                        v-for="child in getCurrentChildrenList(item)"
                        v-loading="item.loadingChildren"
                        :key="child.id"
                        class="flex gap-2 p-3 rounded-lg"
                      >
                        <img
                          @click="jumpToUserHomePage({ userId: child.userId, type })"
                          :src="child.avatar"
                          alt=""
                          class="w-8 h-8 rounded-full object-cover cursor-pointer"
                        />
                        <div class="flex-1">
                          <div class="flex items-center gap-1">
                            <span class="font-semibold text-gray-600 text-base">{{
                              child.replyUser
                            }}</span>
                            <!-- v-if="item.replyName && item.replyName !== parentComment?.replyUser" -->
                            <span class="text-gray-500 text-sm flex items-center gap-1">
                              <el-icon class="mx-1"><IEpCaretRight /></el-icon>
                              {{ child.replyName }}
                            </span>
                          </div>
                          <p
                            class="text-gray-800 my-2 break-all whitespace-pre-wrap text-[16px]"
                            v-html="parseEmoji(child.content)"
                          ></p>
                          <!-- 评论图片列表 -->
                          <div class="flex flex-wrap gap-2">
                            <div
                              v-for="(img, imgIndex) in child.imgUrl.split(',').filter(Boolean)"
                              :key="imgIndex"
                              class="w-20 h-20 rounded-lg overflow-hidden mb-2"
                            >
                              <el-image
                                :src="img"
                                :preview-teleported="true"
                                class="w-full h-full object-cover"
                                :preview-src-list="child.imgUrl.split(',').filter(Boolean)"
                                :initial-index="imgIndex"
                                fit="cover"
                              />
                            </div>
                          </div>
                          <div class="flex items-center justify-between">
                            <div class="flex items-center gap-6 text-gray-500 text-[14px]">
                              <span class="flex items-center gap-2">
                                <span
                                  >{{
                                    dayjs(child.createTime * 1000).format('YYYY-MM-DD HH:mm:ss')
                                  }}
                                </span>
                                <span>·</span>
                                <span class="text-gray-500">{{ child.region }}</span>
                              </span>
                              <div class="flex gap-2 items-center hover:text-blue-500">
                                <div
                                  class="flex items-center gap-1 cursor-pointer"
                                  @click="handleLickComment(child)"
                                >
                                  <el-icon :size="16">
                                    <svg-icon
                                      :name="child.hasPraise ? 'praise_fill' : 'praise'"
                                    ></svg-icon>
                                  </el-icon>
                                  <span>{{ child.postPriseCount }}</span>
                                </div>
                              </div>
                              <button
                                @click="handleReply(child, index)"
                                class="cursor-pointer hover:text-blue-500 transition-colors"
                              >
                                回复
                              </button>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </template>
                  <!-- 问吧  如果有 子评论 直接变成 查看更多 -->
                  <template v-else>
                    <div v-if="item.childNum">
                      <button
                        class="cursor-pointer text-sm text-gray-500 mt-2"
                        @click="handleOpenCommentDialog(item)"
                      >
                        查看全部{{ item.childNum }} 条回复>
                      </button>
                    </div>
                  </template>
                  <!-- 只有大于5 才会显示这个 -->
                  <div class="ml-4" v-show="item.childrenNum > 5 && !isQuestion">
                    <!-- 展示 展开回复 -->
                    <button
                      v-show="!item.showChildrenPage"
                      class="cursor-pointer text-sm text-gray-500"
                      @click="handleExpandReply(item)"
                    >
                      还有{{ item.childrenNum - 5 }}条回复,<span
                        class="hover:text-blue-500 transition-colors"
                        >点击查看</span
                      >
                    </button>
                    <!-- 展示 收起回复 以及分页 -->
                    <div class="flex items-center gap-2" v-show="item.showChildrenPage">
                      <span class="text-sm text-gray-500"
                        >共{{ Math.ceil(item.childrenNum / 10) }}页</span
                      >
                      <el-pagination
                        :pager-count="5"
                        layout="pager"
                        v-show="item.showChildrenPage"
                        :current-page="item.childrenPageCurrent"
                        :total="item.childrenNum"
                        @current-change="handleChildrenCurrentChange($event, item, index)"
                      />
                      <button
                        class="cursor-pointer hover:text-blue-500 transition-colors text-sm text-gray-500"
                        @click="handleCollapseReply(item, index)"
                      >
                        收起回复
                      </button>
                    </div>
                  </div>
                  <!-- 展示 回复评论的输入框 -->
                  <transition name="fadeToComment">
                    <div v-show="showCommentBox(item)" class="flex gap-3 mt-4">
                      <img
                        :src="userAvatar"
                        alt=""
                        class="w-10 h-10 rounded-full object-cover cursor-pointer"
                        @click="jumpToUserHomePage({ userId: userInfo.userId, type })"
                      />
                      <CommentBox
                        v-model:inputText="commentToOther"
                        v-model:inputImg="commentToOtherImgStr"
                        class="flex-1"
                        :ref="(el) => (replyToOtherBoxRefList[index] = el as HTMLElement)"
                      >
                        <template #submit>
                          <button
                            type="button"
                            class="comment-publish-btn cursor-pointer disabled:opacity-50 px-6 py-2 text-white rounded-full text-sm hover:shadow-lg transition-all"
                            :disabled="!commentToOther.trim() || commentToOtherLoading"
                            @click="handleComment(index)"
                          >
                            发表
                          </button>
                        </template>
                      </CommentBox>
                    </div>
                  </transition>
                </div>
              </div>
            </div>
            <div class="px-4">
              <el-divider class="my-2!" />
            </div>
          </div>
          <!-- 底部分页 -->
          <!-- 靠右侧 -->
          <div class="flex justify-end">
            <div class="w-fit p-4">
              <el-pagination
                v-model:current-page="searchParams.current"
                v-model:page-size="searchParams.size"
                :total="firstComentTotal"
                @current-change="handleCurrentChange"
                @size-change="changePageSize"
                layout="prev, pager, next, slot"
              >
                <div>共 {{ total }} 条</div>
              </el-pagination>
            </div>
          </div>
        </div>
        <div v-show="!list.length">
          <div class="flex items-center justify-center">
            <el-empty :image-size="100" description="暂无评论" />
          </div>
        </div>
      </div>
    </div>
    <CommentListDialog ref="commentListDialogRef" :articleId="id" :pid="currentDialogCommentPid" />
  </div>
</template>
<script setup lang="ts">
import {
  getCommentList,
  addOrCancelCommentLike,
  addComment,
  getCommentChildren,
  getSecondCommentList,
} from '@/api'
import { usePageSearch, useScrollTop } from '@/hooks'
import { ArticleTypeEnum, BooleanFlag } from '@/constants'
import type { CommentItemDto } from '@/api'
import { useUserStore } from '@/stores'
import { storeToRefs } from 'pinia'
import CommentListDialog from '../CommentListDialog/index.vue'
import { useNavigation } from '@/hooks'
import { parseEmoji } from '@/utils/emoji'
import CommentBox from '../CommentBox/index.vue'
import dayjs from 'dayjs'
import { push } from 'notivue'

const { jumpToUserHomePage } = useNavigation()
const {
  id,
  defaultSize = 10,
  immediate = true,
  isQuestion = false,
  commentId = 0,
  type,
} = defineProps<{
  id: number // 文章ID
  defaultSize?: number
  isQuestion?: boolean // 如果是问题的话 展示有点不一样
  immediate?: boolean
  commentId?: number // 如果是问题的话 需要传入评论id
  type: ArticleTypeEnum
}>()

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

const total = defineModel<number>('total', { required: true, default: 0 })

const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const isReal = computed(
  () =>
    type === ArticleTypeEnum.PRACTICE ||
    type === ArticleTypeEnum.INTERVIEW ||
    type === ArticleTypeEnum.QUESTION,
)
const userAvatar = computed(() => {
  return isReal.value ? userInfo.value.avatar : userInfo.value.hiddenAvatar
})

const commentRef = useTemplateRef<HTMLElement | null>('commentRef')
const commentListDialogRef = useTemplateRef<typeof CommentListDialog>('commentListDialogRef')
const replyToOtherBoxRefList = ref<HTMLElement[]>([])
const commentItemRefList = ref<HTMLElement[]>([])
// 回滚到评论框
const { handleBackTop } = useScrollTop(commentRef)
// 回滚到子评论框
const { handleBackTop: handleBackTopChildren } = useScrollTop(commentItemRefList)

const {
  list,
  searchParams,
  goToPage,
  loading,
  changePageSize,
  refresh,
  search,
  total: firstComentTotal,
} = usePageSearch(isQuestion ? getSecondCommentList : getCommentList, {
  defaultParams: {
    ...(commentId
      ? { pid: commentId, sortType: 2 }
      : {
          articleId: id,
          sortType: 2,
        }),
  },
  defaultSize,
  formatList(list: CommentItemDto[]) {
    return list.map((item) => {
      // 初始化的时候 添加新的字段 是否展示分页子评论 默认是false 当前子评论分页current 以及子评论分页列表 loading效果

      const obj: CommentItemDto = { ...item }
      // if (obj.showChildrenPage == undefined) {
      obj.showChildrenPage = false
      // }
      // if (obj.childrenPageCurrent == undefined) {
      obj.childrenPageCurrent = 1
      // }
      // if (obj.childrenPageList == undefined) {
      obj.childrenPageList = []
      // }
      // if (obj.loadingChildren == undefined) {
      obj.loadingChildren = false
      // }

      return obj
    })
  },
  immediate,
})
const handleCurrentChange = async (e: number) => {
  await goToPage(e)
  handleBackTop()
}

// 自己发出的评论
const myComment = ref('')
const myCommentLoading = ref(false)
// 回复别人的
const commentToOther = ref('')
const commentToOtherLoading = ref(false)
// 回复别人placeholder
const replyPlaceholder = ref('回复@')
// 自己发出的评论图片
const myCommentImgStr = ref('')
// 回复别人的图片
const commentToOtherImgStr = ref('')
const currentCommentId = ref(-1)

const handleLickComment = async (item: CommentItemDto) => {
  await addOrCancelCommentLike(item.id)
  if (item.hasPraise === BooleanFlag.YES) {
    push.success('取消点赞成功')
    item.postPriseCount--
    item.hasPraise = BooleanFlag.NO
  } else {
    push.success('点赞成功')
    item.postPriseCount++
    item.hasPraise = BooleanFlag.YES
  }
}

const handleReply = (item: CommentItemDto, index: number) => {
  replyPlaceholder.value = `回复@${item.replyUser}：`
  commentToOther.value = ''
  currentCommentId.value = item.id
  replyToOtherBoxRefList.value[index]?.focus()
}

// 是否展示子评论回复框
const showCommentBox = (item: CommentItemDto) => {
  return (
    currentCommentId.value === item.id ||
    getCurrentChildrenList(item)?.some((i) => i.id === currentCommentId.value)
  )
}

const handleMyComment = async () => {
  try {
    myCommentLoading.value = true
    await addComment({
      articleId: id,
      content: myComment.value,
      ...(commentId ? { pid: commentId } : {}),
      imgUrl: myCommentImgStr.value,
    })
    push.success('发表评论成功')
    refresh()
    myComment.value = ''
    myCommentImgStr.value = ''
    total.value++
    emit('commentSuccess')
  } catch (error) {
    console.error(error)
  } finally {
    myCommentLoading.value = false
  }
}

const handleComment = async (index: number) => {
  try {
    commentToOtherLoading.value = true
    await addComment({
      articleId: id,
      content: commentToOther.value,
      ...(currentCommentId.value ? { pid: currentCommentId.value } : {}),
      imgUrl: commentToOtherImgStr.value,
    })
    push.success('发表评论成功')
    commentToOther.value = ''
    commentToOtherImgStr.value = ''
    total.value++
    handleBackTopChildren(index)
    // 只需要刷新当前的评论
    search()
    emit('commentSuccess')
  } catch (error) {
    console.error(error)
  } finally {
    commentToOtherLoading.value = false
  }
}

// 展开回复 获取子评论列表
const handleExpandReply = async (item: CommentItemDto) => {
  item.loadingChildren = true
  try {
    // 获取子评论
    await getCommentChildrenList(item)
  } catch (error) {
    console.error(error)
  } finally {
    item.loadingChildren = false
  }

  item.showChildrenPage = true
}
// 收起回复
const handleCollapseReply = (item: CommentItemDto, index: number) => {
  item.showChildrenPage = false

  handleBackTopChildren(index)
}

// 改变子评论的当前页数
const handleChildrenCurrentChange = (e: number, item: CommentItemDto, index: number) => {
  item.childrenPageCurrent = e
  getCommentChildrenList(item)
  handleBackTopChildren(index)
}

// 根据页数获取子评论列表
const getCommentChildrenList = async (item: CommentItemDto) => {
  const { data } = await getCommentChildren({
    pid: item.id,
    articleId: id,
    current: item.childrenPageCurrent,
    size: 10,
  })
  item.childrenPageList = data.list
}

// 获取当前要渲染的子列表
const getCurrentChildrenList = (item: CommentItemDto) => {
  if (item.showChildrenPage) {
    return item.childrenPageList
  } else {
    return item.children
  }
}

const currentDialogCommentPid = ref(0)
const handleOpenCommentDialog = (item: CommentItemDto) => {
  currentDialogCommentPid.value = item.id
  commentListDialogRef.value?.open()
}

defineExpose({
  scrollToCommentBox: () => handleBackTop(),
  search: () => search(),
})
</script>
<style scoped lang="scss">
/**
 * 发表按钮：不用纯 Uno 渐变工具类。
 * 旧版内核 / 部分企业微信 WebView 对「依赖 CSS 变量的 linear-gradient」解析失败时，
 * 背景会变成透明或无效，原生 button 呈白底，易出现「只剩阴影、几乎看不见按钮」。
 * 这里用实色 background-color 作兜底，并写死 hex + -webkit- 前缀渐变。
 */
.comment-publish-btn {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
  border: 1px solid rgba(255, 255, 255, 0.35);
  /* 与 Tailwind blue-500 / purple-500 接近的实色兜底 */
  background-color: #6366f1;
  background-image: -webkit-linear-gradient(left, #3b82f6, #a855f7);
  background-image: linear-gradient(to right, #3b82f6, #a855f7);
  color: #ffffff;
}

.comment-publish-btn:disabled {
  cursor: not-allowed;
}

/* 进入 & 离开公共属性 */
.fadeToComment-enter-active,
.fadeToComment-leave-active {
  transition:
    opacity 0.25s ease,
    transform 0.25s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: opacity, transform;
}

/* 进入前 & 离开后 */
.fadeToComment-enter-from,
.fadeToComment-leave-to {
  opacity: 0;
  transform: translateY(8px);
}

/* 进入后 & 离开前 */
.fadeToComment-enter-to,
.fadeToComment-leave-from {
  opacity: 1;
  transform: translateY(0);
}
</style>
