<script lang="ts" setup>
import { getCurrentInstance } from 'vue'
import useRequest from '@/hooks/useRequest'
import { queryLinkGroups, queryLinks } from '@/api/halo-plugin/link'
import { cover } from '@/utils/imageHelper'
import { copy } from '@/utils/base/clipboard'
import { getRect } from '@/utils/base/getRect'
import { useListData } from '@/hooks/useListData'
import type { IPaginationParams } from '@/hooks/useListData'
import { debounce } from '@/utils/base/debounce'

defineOptions({
  name: 'Links',
})

definePage({
  style: {
    navigationBarTitleText: '友情链接',
    navigationBarBackgroundColor: '#ffffff',
    enablePullDownRefresh: true,
  },
})

const { loading: loadingGroups, error: errorGroups, data: dataGroups, run: runGroups } = useRequest<any>(queryLinkGroups, { loadingToast: false, loadingToastContent: '加载中...', loadingToastMask: true })
const { loading, error, data, run } = useRequest<any, IPaginationParams>(queryLinks, { loadingToast: false, loadingToastContent: '加载中...', loadingToastMask: true })

const { list: links, refresh } = useListData<any>({
  params: {
    page: 1,
    size: 0,
  },
  loading: toRef(loading),
  onPullDownRefresh: async (params, updateData) => {
    await run({ ...params })
    updateData({
      error: error.value,
      hasNext: data.value?.hasNext,
      items: data.value?.items ?? [],
    })
  },
  onReachBottom: async (params, updateData) => {
    await run({ ...params })
    updateData({
      error: error.value,
      hasNext: data.value?.hasNext,
      items: data.value?.items ?? [],
    })
  },
})

// 分组列表,处理排序,分组显示
interface ILinkGroupData {
  name: string
  index: string
  priority: number
  links: any[]
}
const linkGroups = computed(() => {
  const groupedLinks = links.value.reduce((acc, link) => {
    const groupName = link.spec.groupName

    const group = dataGroups.value?.find(item => item.metadata.name === groupName)
    let _groupName = '未分组'
    if (group) {
      _groupName = group.spec.displayName
    }
    if (!acc[_groupName]) {
      acc[_groupName] = {
        name: _groupName,
        index: _groupName,
        priority: group?.spec.priority ?? (dataGroups.value ? dataGroups.value.length + 1 : 99),
        links: [],
      }
    }
    acc[_groupName].links.push(toRaw(link))
    return acc
  }, {} as Record<string, any[]>)
  // // 分组还需要根据 分组中的 spec.priority 字段进行排序
  return Object.values(groupedLinks)
    .map((item) => {
      return item
    })
    .sort((a: ILinkGroupData, b: ILinkGroupData) => a.priority - b.priority)
    .map((item: ILinkGroupData) => {
      item.links.sort((a, b) => a.spec.priority - b.spec.priority)
      return item
    })
})

const useBottomGroupNav = ref(false)
const allGroupRects = ref([])
const instance = getCurrentInstance()

async function getAllGroupPosition() {
  await nextTick()
  allGroupRects.value = []
  linkGroups.value.forEach(async (item, index) => {
    const groupRects = await getRect({ selector: `.group-start-${index},.group-end-${index}`, instance, all: true })
    allGroupRects.value.push({
      name: item.name,
      index,
      active: false,
      startRect: groupRects[0],
      endRect: groupRects[1],
    })
  })
}

function scrollToGroup(item: any) {
  const startRect = item.startRect
  if (startRect) {
    uni.pageScrollTo({
      scrollTop: startRect.top - 12,
      duration: 300,
    })
    uni.showToast({
      title: item.name,
      icon: 'none',
      duration: 600,
    })
  }
}

const handleActiveNavGroup = debounce((scrollTop: number) => {
  allGroupRects.value.forEach((item) => {
    if (scrollTop >= item.startRect.top - 24 && scrollTop <= item.endRect.top + 60) {
      item.active = true
    }
    else {
      item.active = false
    }
  })
}, 30)

watch(() => linkGroups.value, async (newVal) => {
  if (newVal.length !== 0) {
    await getAllGroupPosition()
  }
})

onPageScroll(({ scrollTop }) => {
  handleActiveNavGroup(scrollTop)
})

onLoad(async () => {
  await runGroups()
  await refresh()
})
</script>

<template>
  <view class="min-h-screen w-full flex flex-col bg-page2">
    <!-- <view>
      <view>分组数据</view>
      <view>{{ dataGroups }}</view>
    </view> -->

    <!-- 分组列表 -->
    <view v-if="linkGroups.length !== 0" class="box-border w-full flex flex-col gap-y-4 overflow-hidden p-4 pb-0">
      <template v-for="(item, index) in linkGroups" :key="item.name">
        <view
          v-if="linkGroups.length !== 1" class="flex items-center justify-between text-sm"
          :class="[`group-start-${index}`]"
        >
          <text class="font-bold">{{ item.name }}</text>
          <text class="text-xs text-gray-600"> {{ item.links.length }} 条记录 </text>
        </view>

        <!-- 分组卡片 -->
        <view
          v-for="(link, linkIndex) in item.links" :key="link.metadata.name"
          class="uh-shadow-card box-border w-full flex flex-col items-center justify-center gap-y-2 overflow-hidden border-2 border-white rounded-xl border-solid bg-white p-4"
          :class="[
            linkIndex === item.links.length - 1 ? `group-end-${index}` : '',
          ]"
        >
          <!-- 顶部信息 -->
          <view class="box-border w-full flex items-center justify-between gap-x-4">
            <view
              class="uh-shadow-md box-border h-11 w-11 shrink-0 overflow-hidden border-2 border-white rounded-xl border-solid bg-white"
            >
              <image :src="cover(link.spec.logo)" mode="aspectFill" class="h-full w-full" />
            </view>
            <view class="flex flex-1 flex-col gap-y-1">
              <view class="line-clamp-1 text-sm text-gray-900 font-bold">
                {{ link.spec.displayName }}
              </view>
              <view class="line-clamp-1 text-xs text-gray-400">
                {{ link.spec.url }}
              </view>
            </view>
            <view class="shrink-0">
              <view
                class="uh-shadow-md rounded-3xl bg-[#1A1A1A] px-4 py-2 text-xs text-white"
                @click="copy(link.spec.url, true)"
              >
                复制
              </view>
            </view>
          </view>
          <!-- 底部信息 -->
          <view class="line-clamp-2 w-full text-xs text-gray-500 leading-relaxed">
            {{ link.spec.description }}
            <!-- {{ '你好,我是 UNI HALO v3.0 新版本,开源免费 Halo 博客小程序，支持多端编译。' }} -->
          </view>
        </view>
      </template>
    </view>
    <view v-else class="w-full flex flex-1 items-center justify-center">
      <wd-empty icon="no-content" tip="暂无友链">
        <template #image>
          <wd-icon name="empty" color="#1A1A1A" :size="52" />
        </template>
      </wd-empty>
    </view>

    <!-- 导航 -->
    <view
      v-if="!useBottomGroupNav && allGroupRects.length !== 0" class="fixed right-2 top-1/2 z-50" :style="{
        transform: 'translateY(-50%)',
      }"
    >
      <view class="uh-shadow-md h-full flex flex-col items-center justify-center gap-y-1 rounded-full bg-white p-1">
        <view
          v-for="(item) in allGroupRects" :key="item.index"
          class="flex flex-col items-center justify-center rounded-full px-1 py-1.5 text-gray-600"
          :class="{ 'bg-gray-900 text-white py-1.5!': item.active }" @click="scrollToGroup(item)"
        >
          <text v-if="item.active" class="text-xs">
            #
          </text>
          <text class="text-[10px] -mt-1">
            {{ item.name.slice(0, 1) }}
          </text>
        </view>
      </view>
    </view>

    <view
      v-if="useBottomGroupNav && allGroupRects.length !== 0"
      class="fixed bottom-0 left-4 right-4 z-50 box-border pb-4"
    >
      <view class="uh-shadow-md box-border w-full flex-1 overflow-hidden rounded-full bg-white p-2">
        <scroll-view :scroll-x="true" class="uh-shadow-md w-full whitespace-nowrap rounded-full">
          <view
            v-for="(item) in allGroupRects" :key="item.index"
            class="mr-2 inline-block border border-gray-900 rounded-2xl border-solid bg-gray-900 px-3 py-1.5 text-[11px] text-white"
            @click="scrollToGroup(item.name)"
          >
            {{ item.name }}
          </view>
        </scroll-view>
      </view>
      <!-- 底部导航占位 -->
      <uh-tabbar-page-placeholder />
    </view>

    <!-- 底部导航占位 -->
    <view
      class="w-full shrink-0" :class="{
        'pb-10': useBottomGroupNav,
      }"
    >
      <uh-tabbar-page-placeholder />
    </view>
  </view>
</template>

<style scoped>
.uh-shadow-xs {
  box-shadow: 0 0 24rpx rgba(0, 0, 0, 0.035);
}

.uh-shadow-md {
  box-shadow: 0 0 24rpx rgba(0, 0, 0, 0.075);
}

.uh-shadow-card {
  box-shadow: 0 16rpx 60rpx rgba(0, 0, 0, 0.04);
}
</style>
