<script setup lang="ts">
import { NavigateToNewTab, isDarkMode } from '@/Utils'
import { cookie, isLoadingAccount, useAccount } from '@/api/account'
import { ThemeType } from '@/api/api-models'
import { QueryGetAPI } from '@/api/query'
import RegisterAndLogin from '@/components/RegisterAndLogin.vue'
import { checkUpdateNote } from '@/data/UpdateNote';
import { ACCOUNT_API_URL } from '@/data/constants'
import { useAuthStore } from '@/store/useAuthStore'
import { useMusicRequestProvider } from '@/store/useMusicRequest'
import {
  BookCoins20Filled,
  CalendarClock24Filled,
  Chat24Filled,
  Info24Filled,
  Live24Filled,
  Lottery24Filled,
  PeopleQueue24Filled,
  Person48Filled,
  PersonFeedback24Filled,
  TabletSpeaker24Filled,
  VehicleShip24Filled,
  VideoAdd20Filled,
  Mail24Filled,
} from '@vicons/fluent'
import { AnalyticsSharp, BrowsersOutline, Chatbox, Moon, MusicalNote, Sunny, Eye } from '@vicons/ionicons5'
import { useElementSize, useStorage } from '@vueuse/core'
import {
  NAlert,
  NBackTop,
  NBadge,
  NButton,
  NCountdown,
  NDivider,
  NElement,
  NFlex,
  NIcon,
  NLayout,
  NLayoutContent,
  NLayoutFooter,
  NLayoutHeader,
  NLayoutSider,
  NMenu,
  NPageHeader,
  NPopconfirm,
  NScrollbar,
  NSpace,
  NSpin,
  NSwitch,
  NTag,
  NText,
  NTooltip,
  useMessage,
  NCard,
} from 'naive-ui'
import { computed, h, onMounted, ref, watch } from 'vue'
import { RouterLink, useRoute } from 'vue-router'
// @ts-ignore
import APlayer from 'vue3-aplayer'

// 全局状态和工具
const accountInfo = useAccount()
const message = useMessage()
const route = useRoute()
const windowWidth = window.innerWidth
const themeType = useStorage('Settings.Theme', ThemeType.Auto)

// 侧边栏和布局相关
const sider = ref()
const { width } = useElementSize(sider)

// 页面类型计算
const type = computed(() => route.meta.danmaku ? 'danmaku' : '')

// 音乐请求服务相关
const musicRquestStore = useMusicRequestProvider()
const aplayerHeight = computed(() =>
  musicRquestStore.originMusics.length === 0 ? '0' : '80'
)
const aplayer = ref()
watch(aplayer, () => {
  musicRquestStore.aplayerRef = aplayer.value
})

// 邮箱验证相关
const canResendEmail = ref(false)
const isBiliVerified = computed(() => accountInfo.value?.isBiliVerified)

// 图标渲染函数 - 用于菜单项
const renderIcon = (icon: any) => () => h(NIcon, null, { default: () => h(icon) })

// 菜单配置
const menuOptions = computed(() => {
  return [
    {
      label: () => h(RouterLink, { to: { name: 'manage-history' } }, { default: () => '历史' }),
      key: 'manage-history',
      disabled: accountInfo.value?.isEmailVerified === false,
      icon: renderIcon(AnalyticsSharp),
    },
    {
      label: () => h(RouterLink, { to: { name: 'manage-live' } }, { default: () => '直播记录' }),
      key: 'manage-live',
      disabled: accountInfo.value?.isEmailVerified === false,
      icon: renderIcon(Live24Filled),
    },
    {
      label: () => h(RouterLink, { to: { name: 'manage-analyze' } }, { default: () => '直播数据' }),
      key: 'manage-analyze',
      disabled: accountInfo.value?.isEmailVerified === false,
      icon: renderIcon(Eye),
    },
    {
      label: () => h(RouterLink, { to: { name: 'manage-event' } }, { default: () => '舰长和SC' }),
      key: 'manage-event',
      disabled: accountInfo.value?.isEmailVerified === false,
      icon: renderIcon(VehicleShip24Filled),
    },
    {
      label: () => h(RouterLink, { to: { name: 'manage-point' } }, { default: () => '积分和礼物' }),
      key: 'manage-point',
      disabled: accountInfo.value?.isEmailVerified === false,
      icon: renderIcon(BookCoins20Filled),
    },
    {
      label: () => h(RouterLink, { to: { name: 'manage-schedule' } }, { default: () => '日程' }),
      key: 'manage-schedule',
      icon: renderIcon(CalendarClock24Filled),
      disabled: accountInfo.value?.isEmailVerified === false,
    },
    {
      label: () => h(RouterLink, { to: { name: 'manage-songList' } }, { default: () => '歌单' }),
      key: 'manage-songList',
      icon: renderIcon(MusicalNote),
      disabled: accountInfo.value?.isEmailVerified === false,
    },
    {
      label: () => h(RouterLink, { to: { name: 'manage-questionBox' } }, { default: () => '棉花糖 (提问箱' }),
      key: 'manage-questionBox',
      icon: renderIcon(Chatbox),
      disabled: accountInfo.value?.isEmailVerified === false,
    },
    {
      label: () => h(RouterLink, { to: { name: 'manage-videoCollect' } }, { default: () => '视频征集' }),
      key: 'manage-videoCollect',
      icon: renderIcon(VideoAdd20Filled),
      disabled: accountInfo.value?.isEmailVerified === false,
    },
    {
      label: () => h(RouterLink, { to: { name: 'manage-lottery' } }, { default: () => '动态抽奖' }),
      key: 'manage-lottery',
      icon: renderIcon(Lottery24Filled),
    },
    {
      label: () => h(
        NTooltip,
        {},
        {
          trigger: () => h(
            NText,
            () => [
              '弹幕相关',
              h(
                NTooltip,
                { style: 'padding: 0;' },
                {
                  trigger: () => h(NIcon, { component: Info24Filled }),
                  default: () => h(
                    NAlert,
                    {
                      type: 'warning',
                      size: 'small',
                      title: '可用性警告',
                      style: 'max-width: 600px;',
                    },
                    () => h('div', {}, [
                      '    当浏览器在后台运行时, 定时器和 Websocket 连接将受到严格限制, 这会导致弹幕接收功能无法正常工作 (详见',
                      h(
                        NButton,
                        {
                          text: true,
                          tag: 'a',
                          href: 'https://developer.chrome.com/blog/background_tabs/',
                          target: '_blank',
                          type: 'info',
                        },
                        () => '此文章',
                      ),
                      '), 虽然本站已经针对此问题做出了处理, 一般情况下即使掉线了也会重连, 不过还是有可能会遗漏事件',
                      h('br'),
                      '为避免这种情况, 建议注册本站账后使用',
                      h(
                        NButton,
                        {
                          type: 'primary',
                          text: true,
                          size: 'small',
                          tag: 'a',
                          href: 'https://www.wolai.com/fje5wLtcrDoZcb9rk2zrFs',
                          target: '_blank',
                        },
                        () => 'VtsuruEventFetcher',
                      ),
                      ', 否则请在使用功能时尽量保持网页在前台运行, 同时关闭浏览器的 页面休眠/内存节省 功能',
                      h('br'),
                      'Chrome: ',
                      h(
                        NButton,
                        {
                          type: 'info',
                          text: true,
                          size: 'small',
                          tag: 'a',
                          href: 'https://support.google.com/chrome/answer/12929150?hl=zh-Hans#zippy=%2C%E5%BC%80%E5%90%AF%E6%88%96%E5%85%B3%E9%97%AD%E7%9C%81%E5%86%85%E5%AD%98%E6%A8%A1%E5%BC%8F%2C%E8%AE%A9%E7%89%B9%E5%AE%9A%E7%BD%91%E7%AB%99%E4%BF%9D%E6%8C%81%E6%B4%BB%E5%8A%A8%E7%8A%B6%E6%80%81',
                          target: '_blank',
                        },
                        () => '让特定网站保持活动状态',
                      ),
                      ', Edge: ',
                      h(
                        NButton,
                        {
                          type: 'info',
                          text: true,
                          size: 'small',
                          tag: 'a',
                          href: 'https://support.microsoft.com/zh-cn/topic/%E4%BA%86%E8%A7%A3-microsoft-edge-%E4%B8%AD%E7%9A%84%E6%80%A7%E8%83%BD%E5%8A%9F%E8%83%BD-7b36f363-2119-448a-8de6-375cfd88ab25',
                          target: '_blank',
                        },
                        () => '永远不想进入睡眠状态的网站',
                      ),
                    ]),
                  ),
                },
              ),
            ]
          ),
          default: () => isBiliVerified.value
            ? '需要使用直播弹幕的功能'
            : '你尚未进行 Bilibili 认证, 请前往面板进行绑定',
        },
      ),
      key: 'manage-danmaku',
      icon: renderIcon(Chat24Filled),
      disabled: accountInfo.value?.isEmailVerified === false || !isBiliVerified.value,
      children: [
        {
          label: () => !isBiliVerified.value ? '弹幕机' : h(
            NBadge,
            { value: '新', offset: [15, 12], type: 'info' },
            () => h(
              NTooltip,
              {},
              {
                trigger: () => h(
                  RouterLink,
                  { to: { name: 'manage-danmuji' } },
                  { default: () => '弹幕机' },
                ),
                default: () => '兼容 blivechat 样式 (其实就是直接用的 blivechat 组件',
              }
            )
          ),
          key: 'manage-danmuji',
          disabled: !isBiliVerified.value,
          icon: renderIcon(Lottery24Filled),
        },
        {
          label: () => !isBiliVerified.value ? '抽奖' : h(
            RouterLink,
            { to: { name: 'manage-liveLottery' } },
            { default: () => '抽奖' },
          ),
          key: 'manage-liveLottery',
          icon: renderIcon(Lottery24Filled),
          disabled: !isBiliVerified.value,
        },
        {
          label: () => !isBiliVerified.value ? '点播' : h(
            NTooltip,
            {},
            {
              trigger: () => h(
                RouterLink,
                { to: { name: 'manage-liveRequest' } },
                { default: () => '点播' },
              ),
              default: () => '歌势之类用的, 可以用来点歌或者跳舞什么的',
            },
          ),
          key: 'manage-liveRequest',
          icon: renderIcon(MusicalNote),
          disabled: !isBiliVerified.value,
        },
        {
          label: () => !isBiliVerified.value ? '点歌' : h(
            NTooltip,
            {},
            {
              trigger: () => h(
                RouterLink,
                { to: { name: 'manage-musicRequest' } },
                { default: () => '点歌' },
              ),
              default: () => '就是传统的点歌机, 发弹幕后播放指定的歌曲',
            },
          ),
          key: 'manage-musicRequest',
          icon: renderIcon(MusicalNote),
          disabled: !isBiliVerified.value,
        },
        {
          label: () => !isBiliVerified.value ? '排队' : h(
            RouterLink,
            { to: { name: 'manage-liveQueue' } },
            { default: () => '排队' },
          ),
          key: 'manage-liveQueue',
          icon: renderIcon(PeopleQueue24Filled),
          disabled: !isBiliVerified.value,
        },
        {
          label: () => !isBiliVerified.value ? '读弹幕' : h(
            RouterLink,
            { to: { name: 'manage-speech' } },
            { default: () => '读弹幕' },
          ),
          key: 'manage-speech',
          icon: renderIcon(TabletSpeaker24Filled),
          disabled: !isBiliVerified.value,
        },
      ],
    },
  ]
})

// 重发验证邮件
async function resendEmail() {
  try {
    const data = await QueryGetAPI(ACCOUNT_API_URL + 'send-verify-email')
    if (data.code === 200) {
      canResendEmail.value = false
      message.success('发送成功, 请检查你的邮箱. 如果没有收到, 请检查垃圾邮件')
      if (accountInfo.value && accountInfo.value.nextSendEmailTime) {
        accountInfo.value.nextSendEmailTime += 1000 * 60
      }
    } else {
      message.error('发送失败: ' + data.message)
    }
  } catch (err) {
    message.error('发送失败')
  }
}

// 登出操作
function logout() {
  cookie.value = undefined
  window.location.reload()
}

// 播放下一首音乐
function onNextMusic() {
  musicRquestStore.nextMusic()
}

// 跳转到认证页面
function gotoAuthPage() {
  if (!accountInfo.value?.biliUserAuthInfo) {
    message.error('你尚未进行 Bilibili 认证, 请前往面板进行认证和绑定')
    return
  }
  useAuthStore()
    .setCurrentAuth(accountInfo.value?.biliUserAuthInfo.token)
    .then(() => {
      NavigateToNewTab('/bili-user')
    })
}

onMounted(() => {
  // 检查邮箱验证状态
  if (accountInfo.value?.isEmailVerified === false) {
    if ((accountInfo.value?.nextSendEmailTime ?? -1) <= 0) {
      canResendEmail.value = true
    }
  }
})
</script>

<template>
  <NLayout
    v-if="accountInfo.id"
    style="height: 100vh"
  >
    <!-- 顶部导航栏 -->
    <NLayoutHeader
      bordered
      style="height: var(--vtsuru-header-height); padding: 10px 15px 5px 15px"
    >
      <NPageHeader>
        <template #title>
          <NText
            strong
            style="font-size: 1.4rem; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1)"
          >
            VTSURU CENTER
          </NText>
        </template>
        <template #extra>
          <NSpace
            align="center"
            justify="center"
          >
            <!-- 主题切换开关 -->
            <NSwitch
              :default-value="!isDarkMode"
              @update:value="(value) => (themeType = value ? ThemeType.Light : ThemeType.Dark)"
            >
              <template #checked>
                <NIcon :component="Sunny" />
              </template>
              <template #unchecked>
                <NIcon :component="Moon" />
              </template>
            </NSwitch>
            <NButton
              size="small"
              type="primary"
              @click="$router.push({ name: 'user-index', params: { id: accountInfo?.name } })"
            >
              回到展示页
            </NButton>
          </NSpace>
        </template>
      </NPageHeader>
    </NLayoutHeader>

    <!-- 主布局部分 -->
    <NLayout
      has-sider
      style="height: calc(100vh - 50px)"
    >
      <!-- 侧边导航栏 -->
      <NLayoutSider
        v-if="accountInfo?.isEmailVerified"
        ref="sider"
        bordered
        show-trigger
        collapse-mode="width"
        :default-collapsed="windowWidth < 750"
        :collapsed-width="64"
        :width="180"
        :native-scrollbar="false"
        :scrollbar-props="{ trigger: 'none', style: {} }"
      >
        <!-- 顶部功能按钮区 -->
        <NSpace
          vertical
          style="margin-top: 16px"
          align="center"
        >
          <NSpace justify="center">
            <NButton
              type="info"
              style="width: 100%"
              @click="$router.push({ name: 'manage-index' })"
            >
              <template #icon>
                <NIcon :component="BrowsersOutline" />
              </template>
              <template v-if="width >= 180">
                面板
              </template>
            </NButton>
            <NTooltip v-if="width >= 180">
              <template #trigger>
                <NButton @click="$router.push({ name: 'manage-feedback' })">
                  <template #icon>
                    <NIcon :component="PersonFeedback24Filled" />
                  </template>
                </NButton>
              </template>
              反馈
            </NTooltip>
          </NSpace>
          <!-- B站认证用户入口 -->
          <NButton
            v-if="accountInfo.biliUserAuthInfo"
            type="info"
            secondary
            @click="gotoAuthPage()"
          >
            <template #icon>
              <NIcon :component="Person48Filled" />
            </template>
            <template v-if="width >= 180">
              认证用户主页
            </template>
          </NButton>
        </NSpace>

        <!-- 主导航菜单 -->
        <NMenu
          style="margin-top: 12px"
          :disabled="accountInfo?.isEmailVerified !== true"
          :default-value="($route.meta.parent as string) ?? $route.name?.toString()"
          :collapsed-width="64"
          :collapsed-icon-size="22"
          :options="menuOptions"
        />

        <!-- 底部信息区 -->
        <NSpace
          v-if="width > 150"
          justify="center"
          align="center"
          vertical
        >
          <NText depth="3">
            有更多功能建议请
            <NButton
              text
              type="info"
              @click="$router.push({ name: 'manage-feedback' })"
            >
              反馈
            </NButton>
          </NText>
          <NText depth="3">
            <NButton
              text
              type="info"
              @click="$router.push({ name: 'about' })"
            >
              关于本站
            </NButton>
          </NText>
        </NSpace>
        <NDivider style="margin-bottom: 8px;" />
        <NFlex
          justify="center"
          align="center"
        >
          <NText
            :style="`font-size: 12px; text-align: center;color: ${isDarkMode ? '#555' : '#c0c0c0'};visibility: ${width < 180 ? 'hidden' : 'visible'}`"
          >
            By Megghy
          </NText>
        </NFlex>
      </NLayoutSider>

      <!-- 内容区域 -->
      <NLayout>
        <!-- 主内容区域 -->
        <NScrollbar :style="`height: calc(100vh - var(--vtsuru-header-height) - ${aplayerHeight}px)`">
          <NLayoutContent content-style="margin: var(--vtsuru-content-padding); margin-right: calc(var(--vtsuru-content-padding) + 4px)">
            <NElement>
              <!-- 已验证邮箱的用户显示内容 -->
              <RouterView
                v-if="accountInfo?.isEmailVerified"
                v-slot="{ Component }"
              >
                <KeepAlive>
                  <Suspense>
                    <component :is="Component" />
                    <template #fallback>
                      <NSpin show />
                    </template>
                  </Suspense>
                </KeepAlive>
              </RouterView>
              <!-- 未验证邮箱的提示 -->
              <template v-else>
                <NCard>
                  <NSpace
                    vertical
                    size="large"
                    align="center"
                  >
                    <NFlex
                      justify="center"
                      align="center"
                      vertical
                    >
                      <NIcon
                        size="48"
                        color="#2080f0"
                      >
                        <Mail24Filled />
                      </NIcon>
                      <NText style="font-size: 20px; margin-top: 16px; font-weight: 500;">
                        请验证您的邮箱
                      </NText>
                      <NText
                        depth="3"
                        style="text-align: center; margin-top: 8px;"
                      >
                        我们已向您的邮箱发送了验证链接，请查收并点击链接完成验证
                      </NText>
                    </NFlex>

                    <NAlert
                      type="warning"
                      style="max-width: 450px;"
                    >
                      <template #icon>
                        <NIcon>
                          <Info24Filled />
                        </NIcon>
                      </template>
                      如果长时间未收到邮件，请检查垃圾邮件文件夹，或点击下方按钮重新发送
                    </NAlert>

                    <NSpace>
                      <NButton
                        type="primary"
                        :disabled="!canResendEmail"
                        style="min-width: 140px;"
                        @click="resendEmail"
                      >
                        <template #icon>
                          <NIcon>
                            <Mail24Filled />
                          </NIcon>
                        </template>
                        重新发送验证邮件
                      </NButton>
                      <NTag
                        v-if="!canResendEmail"
                        type="warning"
                        round
                      >
                        <NCountdown
                          :duration="(accountInfo?.nextSendEmailTime ?? 0) - Date.now()"
                          @finish="canResendEmail = true"
                        />
                        后可重新发送
                      </NTag>
                    </NSpace>

                    <NDivider style="width: 80%; min-width: 250px;" />

                    <NPopconfirm @positive-click="logout">
                      <template #trigger>
                        <NButton secondary>
                          <template #icon>
                            <NIcon>
                              <PersonFeedback24Filled />
                            </NIcon>
                          </template>
                          切换账号
                        </NButton>
                      </template>
                      确定要登出当前账号吗？
                    </NPopconfirm>
                  </NSpace>
                </NCard>
              </template>
              <NBackTop />
            </NElement>
          </NLayoutContent>
        </NScrollbar>

        <!-- 音乐播放器区域 -->
        <NLayoutFooter :style="`height: ${aplayerHeight}px;overflow: auto`">
          <div style="display: flex; align-items: center; margin: 0 10px">
            <APlayer
              v-if="musicRquestStore.aplayerMusics.length > 0"
              ref="aplayer"
              v-model:music="musicRquestStore.currentMusic"
              v-model:volume="musicRquestStore.settings.volume"
              v-model:shuffle="musicRquestStore.settings.shuffle"
              v-model:repeat="musicRquestStore.settings.repeat"
              :list="musicRquestStore.aplayerMusics"
              :list-max-height="'200'"
              mutex
              list-folded
              style="flex: 1; min-width: 400px"
              @ended="musicRquestStore.onMusicEnd"
              @play="musicRquestStore.onMusicPlay"
            />
            <NSpace vertical>
              <NTag
                :bordered="false"
                type="info"
                size="small"
              >
                队列: {{ musicRquestStore.waitingMusics.length }}
              </NTag>
              <NButton
                size="small"
                type="info"
                @click="onNextMusic"
              >
                下一首
              </NButton>
            </NSpace>
          </div>
        </NLayoutFooter>
      </NLayout>
    </NLayout>
  </NLayout>

  <!-- 未登录时显示的登录/注册界面 -->
  <template v-else>
    <NLayoutContent
      style="
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        width: 100vw;
        background: linear-gradient(135deg, rgba(250,250,250,0.8) 0%, rgba(240,240,245,0.9) 100%);
        padding: 0;
        margin: 0;
        box-sizing: border-box;
        position: fixed;
        top: 0;
        left: 0;
        overflow: auto;
      "
      :class="isDarkMode ? 'login-dark-bg' : ''"
    >
      <template v-if="!isLoadingAccount">
        <NCard
          class="login-card"
          :bordered="false"
        >
          <template #header>
            <NFlex
              justify="center"
              align="center"
              style="padding: 12px 0;"
            >
              <NText
                strong
                style="font-size: 1.8rem; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); background-image: linear-gradient(to right, #36d1dc, #5b86e5); -webkit-background-clip: text; -webkit-text-fill-color: transparent;"
              >
                VTSURU CENTER
              </NText>
            </NFlex>
          </template>

          <NSpace
            vertical
            size="large"
            style="padding: 8px 0;"
          >
            <NFlex
              justify="center"
              align="center"
            >
              <NText style="font-size: 16px; text-align: center;">
                请登录或注册后使用
              </NText>
            </NFlex>

            <NAlert
              type="info"
              style="border-radius: 8px;"
            >
              <NFlex
                vertical
                align="center"
                size="small"
              >
                <div style="text-align: center;">
                  如果你不是主播且不发送棉花糖(提问)的话则不需要注册登录, 直接访问认证完成后给出的链接即可
                </div>
                <NFlex
                  justify="center"
                  style="width: 100%; margin-top: 8px;"
                >
                  <NButton
                    type="primary"
                    size="small"
                    @click="$router.push({ name: 'bili-user' })"
                  >
                    <template #icon>
                      <NIcon :component="BrowsersOutline" />
                    </template>
                    前往 Bilibili 认证用户主页
                  </NButton>
                </NFlex>
              </NFlex>
            </NAlert>

            <NDivider style="margin: 8px 0;" />

            <RegisterAndLogin />

            <NFlex justify="center">
              <NButton
                secondary
                tag="a"
                href="/"
                style="min-width: 100px;"
              >
                回到主页
              </NButton>
            </NFlex>
          </NSpace>
        </NCard>
      </template>
      <template v-else>
        <NCard
          class="loading-card"
          :bordered="false"
        >
          <NFlex
            vertical
            justify="center"
            align="center"
            style="padding: 20px 10px;"
          >
            <NSpin
              :loading="isLoadingAccount"
              size="large"
            >
              <NText>正在请求账户数据...</NText>
            </NSpin>
          </NFlex>
        </NCard>
      </template>
    </NLayoutContent>
  </template>
</template>

<style scoped>
.login-dark-bg {
  background: linear-gradient(135deg, rgba(30, 30, 35, 0.9) 0%, rgba(20, 20, 25, 0.95) 100%) !important;
}

.login-card {
  max-width: 520px;
  width: 90%;
  min-width: 300px;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.08);
  margin: 16px;
}

.loading-card {
  min-width: 280px;
  width: 90%;
  max-width: 400px;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.08);
  margin: 16px;
}

@media (max-width: 480px) {
  .login-card, .loading-card {
    width: 95%;
    margin: 8px;
  }
}
</style>
