<script setup lang="ts">
import { Close } from '@vicons/ionicons5'
import { nextTick, onMounted, onUnmounted, ref } from 'vue'
import { useRoute } from 'vue-router'

const observer = ref<IntersectionObserver | null>(null)
const message = useMessage()
const userStore = useUserStore()
const route = useRoute()
const { userId } = route.query
const loading = ref(false)
const finished = ref(false)
const total = ref(0) // 总条数
const loadingTrigger = ref(null)

const urlList = ref({
  0: '/personalCenter/selectByUserIdModel',
  1: '/personalCenter/selectByUserIdWorkFlow',
  2: '/personalCenter/selectByUserIdImage',
})
const currentType = ref('0')
const typeList = ref([
  { id: '0', title: '模型' },
  { id: '1', title: '工作流' },
  { id: '2', title: '图片' },
])
const orderOptions = ref([
  {
    dictLabel: '最新',
    dictValue: 'create_time',
  },
  {
    dictLabel: '最热',
    dictValue: 'like_num',
  },
])

const isShowFan = ref(false)

const activeTab = ref('like')
function closefanList() {
  isShowFan.value = false
}

const bannerStyle = {
  backgroundImage:
    'url(\'https://img.zcool.cn/community/special_cover/3a9a64d3628c000c2a1000657eec.jpg\')',
}

const publishParams = ref({
  pageNum: 1,
  pageSize: 20,
  orderByColumn: 'create_time',
  userId,
})

const currentUserInfo = ref({})
async function getCurrentUserInfo() {
  const res = await request.get(`/system/user/selectUserById?id=${userId}`)
  if (res.code === 200) {
    currentUserInfo.value = res.data
  }
}
getCurrentUserInfo()

// 获取粉丝的列表
const attentionList = ref([])
const attentionListParams = ref({
  pageNumber: 1,
  pageSize: 20,
  type: userId,
})
async function getAttentionList() {
  const res = await request.post(`/attention/selectToAttention`, {
    ...attentionListParams.value,
  })
  if (res.code === 200) {
    attentionList.value = res.data.list
  }
}
getAttentionList()

// 获取关注的列表
const likeList = ref([])
const likeListParams = ref({
  pageNumber: 1,
  pageSize: 20,
  type: userId,
})
async function getLikeList() {
  const res = await request.post(`/attention/selectAttentionList`, {
    ...likeListParams.value,
  })
  if (res.code === 200) {
    likeList.value = res.data.list
  }
}
getLikeList()

// 查询是否关注
const isAttention = ref(false)
async function getIsAttention() {
  const res = await request.get(`/attention/selectAttention?userId=${userId}`)
  if (res.code === 200) {
    isAttention.value = res.data
  }
}
getIsAttention()

// 去关注/取消关注当前用户
async function onAttention(item: any) {
  const myUserId = userStore.userInfo.userId
  if (myUserId === item.userId) {
    return message.warning('自己不能关注自己')
  }
  let paramsUserId
  if (item.userId) {
    paramsUserId = item.userId
  }
  else {
    paramsUserId = userId
  }
  try {
    const res = await request.get(`/attention/addAttention?userId=${paramsUserId}`)
    if (res.code === 200) {
      if (res.data) {
        message.success('关注成功')
      }
      else {
        message.success('取消关注成功')
      }
      if (item.userId) {
        item.attention = !item.attention
      }
      else {
        isAttention.value = !isAttention.value
      }
    }
  }
  catch (err) {
    console.log(err)
  }
}

// 获取用户点赞/粉丝/关注数量
interface SelectUserInfo {
  likeCount: number
  bean: number
  download: number
  attention: number
}
const selectUserInfo = ref<SelectUserInfo>({
  likeCount: 0,
  bean: 0,
  download: 0,
  attention: 0,
})
async function getAttention() {
  try {
    const res = await request.get(`/attention/selectUserInfo?userId=${userId}`)
    if (res.code === 200) {
      selectUserInfo.value = res.data
    }
  }
  catch (err) {
    console.log(err)
  }
}
getAttention()

// 切换模型/工作流/图片
function changeType(id: string) {
  currentType.value = id
  initPageNUm()
}

// 切换点赞的最热/最新
function changeLikeOrder(value: string) {
  publishParams.value.orderByColumn = value
  initPageNUm()
}

function initPageNUm() {
  publishParams.value.pageNum = 1
  finished.value = false // 重置加载完成状态
  getList()
}

// 查询发布模型接口
const dataList = ref([])
async function getList() {
  if (loading.value || finished.value)
    return

  loading.value = true
  const url = urlList.value[currentType.value]
  try {
    const res = await request.post(url, publishParams.value)
    if (res.code === 200) {
      // 如果是第一页，直接赋值，否则追加数据
      if (publishParams.value.pageNum === 1) {
        dataList.value = res.rows
      }
      else {
        dataList.value = [...dataList.value, ...res.rows]
      }

      total.value = res.total // 假设接口返回了总条数

      // 判断是否加载完所有数据
      if (dataList.value.length >= total.value) {
        finished.value = true
      }
      publishParams.value.pageNum++
    }
  }
  catch (err) {
    dataList.value = []
    finished.value = true
    console.log(err)
  }
  finally {
    loading.value = false
  }
}
getList()

async function topedRefresh() {
  if (import.meta.client) {
    await nextTick()
    window.scrollTo({
      top: 0,
      behavior: 'smooth',
    })
  }
  initPageNUm()
}

onMounted(() => {
  window.addEventListener('scroll', topedRefresh)
  observer.value = new IntersectionObserver(
    ([entry]) => {
      if (entry.isIntersecting && !loading.value && !finished.value) {
        getList()
      }
    },
    {
      threshold: 0.1,
    },
  )

  if (loadingTrigger.value) {
    observer.value.observe(loadingTrigger.value)
  }
})

onUnmounted(() => {
  window.removeEventListener('scroll', topedRefresh)
  if (observer.value) {
    observer.value.disconnect()
  }
})
</script>

<template>
  <div class="mx-auto container">
    <div
      class="banner-content h-32 bg-blue bg-cover bg-center rounded-sm"
      :style="bannerStyle"
    />
    <div class="info-content mt-[-50px] p-5">
      <div class="edit-info-content flex items-center">
        <div
          class="mc-head mr-5 h-20 w-20 rounded-full bg-white shadow-lg flex items-center justify-center"
        >
          <div class="mc-head-inner h-18 w-18 m-1 rounded-full bg-blue-200">
            <client-only>
              <img
                class="head-img m-1 h-16 w-16 rounded-full bg-white"
                :src="currentUserInfo.avatar"
                alt="User Avatar"
              >
            </client-only>
            <!-- {{ userStore.userInfo.avatar }} -->
          </div>
        </div>
        <div
          v-if="isAttention !== null"
          class="mr-2 cursor-pointer rounded-full bg-gradient-to-r from-[#1f66df] to-[#3faeff] px-4 py-1 text-white"
          @click="onAttention"
        >
          {{ isAttention ? '已关注' : '关注' }}
        </div>
      </div>

      <div class="user-info mt-4">
        <div v-if="currentUserInfo" class="nickname text-xl font-bold">
          {{ currentUserInfo.nickName }}
          <!-- {{ userInfo.nickName }} -->
        </div>
        <div v-if="currentUserInfo" class="info-desc mt-1 text-sm text-gray-700">
          {{ currentUserInfo.brief }}
        </div>
        <div class="production-state mt-4 flex text-sm text-gray-700">
          <div
            class="production-state-item mr-5 cursor-pointer"
            @click="isShowFan = true"
          >
            <span class="production-state-number font-bold">{{
              selectUserInfo.bean ? selectUserInfo.bean : 0
            }}</span>
            粉丝
          </div>
          <div
            class="production-state-item mr-5 cursor-pointer"
            @click="isShowFan = true"
          >
            <span class="production-state-number font-bold">{{
              selectUserInfo.attention ? selectUserInfo.attention : 0
            }}</span>
            关注
          </div>
          <div class="production-state-item mr-5">
            <span class="production-state-number font-bold">{{
              selectUserInfo.download ? selectUserInfo.download : 0
            }}</span>
            作品被使用次数
          </div>
          <div class="production-state-item">
            <span class="production-state-number font-bold">{{
              selectUserInfo.likeCount ? selectUserInfo.likeCount : 0
            }}</span>
            作品被点赞次数
          </div>
        </div>
      </div>

      <div class="select-content mt-4 flex items-center justify-between">
        <div class="flex items-center rounded-full bg-gray-100">
          <div
            v-for="(item, index) in typeList"
            :key="index"
            class="m-1 mr-2 cursor-pointer rounded-full px-4 py-1 text-sm"
            :class="{
              'bg-white': item.id === currentType,
            }"
            @click="changeType(item.id)"
          >
            {{ item.title }}
          </div>
        </div>

        <div class="flex items-center">
          <NSelect
            v-model:value="publishParams.orderByColumn"
            :options="orderOptions"
            label-field="dictLabel"
            value-field="dictValue"
            placeholder="请选择"
            class="w-32"
            @update:value="changeLikeOrder"
          />
        </div>
      </div>
    </div>

    <div class="login-content my-4 grid grid-cols-4 gap-4 px-5">
      <PersonalCenterPublishCard
        v-for="(item, index) in dataList"
        :key="index"
        :item="item"
        :current-type="currentType"
        @toped-refresh="topedRefresh"
      />
    </div>
    <div ref="loadingTrigger" class="h-10">
      <div v-if="loading" class="text-center text-gray-500">
        加载中...
      </div>
      <div v-if="finished" class="text-center text-gray-500">
        没有更多数据了
      </div>
    </div>
    <div v-if="isShowFan" class="fan-centent">
      <div
        class="w-[550px] h-[calc(100vh-100px)] max-h-[700px] m-auto py-0 px-8 pb-[43px] bg-[#fff] rounded-lg relative"
      >
        <n-icon size="20" class="mr-2 cursor-pointer absolute top-4 right-2" @click="closefanList">
          <Close />
        </n-icon>
        <n-tabs
          v-model:value="activeTab"
          default-value="like"
          justify-content="space-evenly"
          type="line"
        >
          <n-tab-pane name="like" :tab="`粉丝${selectUserInfo.bean || 0}`">
            <n-infinite-scroll style="height: calc(100vh - 200px)" :distance="10" @load="getAttentionList">
              <div class="overflow-y-auto h-[calc(100vh-200px)] px-2">
                <div
                  v-for="(item, index) in attentionList"
                  :key="index"
                  class="flex justify-between items-center py-2"
                >
                  <div class="flex items-center">
                    <img :src="item.avatar || ''" alt="" class="w-14 h-14 rounded-full mr-2">
                    {{ item.nickName }}
                  </div>
                  <div class="bg-[#f4f5f9] px-4 py-2 rounded-full cursor-pointer" @click="onAttention(item, 'attention')">
                    {{ item.attention ? '已关注' : '未关注' }}
                  </div>
                </div>
                <div v-if="attentionList.length === 0" class="w-full text-center text-gray-500 font-bold mt-2">
                  暂无数据
                </div>
              </div>
            </n-infinite-scroll>
          </n-tab-pane>
          <n-tab-pane name="attention" :tab="`关注${selectUserInfo.attention || 0}`">
            <div class="overflow-y-auto h-[calc(100vh-200px)] px-2">
              <div
                v-for="(item, index) in likeList"
                :key="index"
                class="flex justify-between items-center py-2"
              >
                <div class="flex items-center">
                  <img :src="item.avatar || ''" alt="" class="w-14 h-14 rounded-full mr-2">
                  {{ item.nickName }}
                </div>
                <div class="bg-[#f4f5f9] px-4 py-2 rounded-full cursor-pointer" @click="onAttention(item, 'like')">
                  {{ item.attention ? '已关注' : '未关注' }}
                </div>
              </div>
              <div v-if="attentionList.length === 0" class="w-full text-center text-gray-500 font-bold mt-2">
                暂无数据
              </div>
            </div>
          </n-tab-pane>
        </n-tabs>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.fan-centent {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  background: rgba(0, 0, 0, 0.4);
}

.n-tabs.n-tabs--flex .n-tabs-nav .n-tabs-wrapper .n-tabs-tab {
  margin-right: 0;
  font-size: 20px;
}
</style>
