<template>
  <a-popover
    v-model:open="popoverVisible"
    trigger="click"
    placement="bottomRight"
    :overlay-class-name="`notification-popover ${theme}`"
    :arrow="true"
    @openChange="onPopoverChange"
  >
    <template #content>
      <div class="bell-dropdown">
        <!-- 头部：标题 + 全部已读 -->
        <div class="dropdown-header">
          <span class="dropdown-title">消息通知</span>
          <a-button
            v-if="unreadTotal > 0"
            type="link"
            size="small"
            class="mark-all-btn"
            :loading="markAllLoading"
            @click="handleMarkAll"
          >
            全部已读
          </a-button>
        </div>

        <!-- Tab 过滤 -->
        <div class="dropdown-tabs">
          <a-radio-group v-model:value="activeType" size="small" button-style="solid" @change="handleTypeChange">
            <a-radio-button value="">全部</a-radio-button>
            <a-radio-button value="ticket">工单</a-radio-button>
            <a-radio-button value="system">系统</a-radio-button>
            <a-radio-button value="review">审核</a-radio-button>
          </a-radio-group>
        </div>

        <!-- 通知列表 -->
        <div class="dropdown-list" @scroll="onListScroll">
          <a-spin :spinning="loading">
            <template v-if="filteredRecentList.length">
              <div
                v-for="item in filteredRecentList"
                :key="item.id"
                class="notification-item"
                :class="{ unread: !item.isRead }"
                @click="handleItemClick(item)"
              >
                <div class="item-icon">
                  {{ notificationTypeMap[item.type!]?.icon || '📢' }}
                </div>
                <div class="item-body">
                  <div class="item-title">{{ item.title }}</div>
                  <div class="item-content">{{ item.content }}</div>
                  <div class="item-meta">
                    <span class="item-time">{{ formatTime(item.createTime) }}</span>
                    <span v-if="item.senderName" class="item-sender">{{ item.senderName }}</span>
                  </div>
                </div>
                <div v-if="!item.isRead" class="item-dot" />
              </div>
            </template>
            <a-empty v-else description="暂无消息" :image-style="{ height: '60px' }" />
          </a-spin>
        </div>

        <!-- 底部：查看全部 -->
        <div class="dropdown-footer">
          <a-button type="link" block @click="goToAll">
            查看全部通知
            <RightOutlined />
          </a-button>
        </div>
      </div>
    </template>

    <!-- 铃铛触发器 -->
    <div class="bell-trigger" :class="[theme]" @click.stop>
      <a-badge :count="unreadTotal" :overflow-count="99" :dot="false" size="small">
        <BellOutlined class="bell-icon" />
      </a-badge>
    </div>
  </a-popover>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { BellOutlined, RightOutlined } from '@ant-design/icons-vue'
import { useNotificationCenter, notificationTypeMap } from '@/composables/useNotificationCenter'
import type { Notification, NotificationType } from '@/api/app/notification/model'

const props = withDefaults(defineProps<{
  /** 主题：light 用于 console 白色头部，dark 用于 SiteHeader 暗色头部 */
  theme?: 'light' | 'dark'
}>(), {
  theme: 'light',
})

const {
  unreadTotal,
  recentList,
  loading,
  fetchUnreadCount,
  fetchRecentNotifications,
  markNotificationRead,
  markAllAsRead,
  startPolling,
  stopPolling,
  formatTime,
  getNotificationLink,
} = useNotificationCenter()

const popoverVisible = ref(false)
const activeType = ref('')
const markAllLoading = ref(false)

// 过滤后的最近通知
const filteredRecentList = computed(() => {
  if (!activeType.value) return recentList.value
  return recentList.value.filter((n) => n.type === activeType.value)
})

function onPopoverChange(visible: boolean) {
  if (visible) {
    fetchRecentNotifications()
  }
}

function handleTypeChange() {
  // 切换类型时重新加载
  fetchRecentNotifications()
}

async function handleItemClick(item: Notification) {
  // 标记已读
  if (!item.isRead && item.id) {
    await markNotificationRead(item.id)
  }
  // 关闭弹窗
  popoverVisible.value = false
  // 跳转
  const link = getNotificationLink(item)
  navigateTo(link)
}

async function handleMarkAll() {
  markAllLoading.value = true
  try {
    const type = activeType.value || undefined
    await markAllAsRead(type)
  } finally {
    markAllLoading.value = false
  }
}

function goToAll() {
  popoverVisible.value = false
  navigateTo('/console/notifications')
}

function onListScroll() {
  // 暂不实现无限滚动，铃铛下拉只展示最近 10 条
}

onMounted(() => {
  startPolling()
})

onUnmounted(() => {
  stopPolling()
})
</script>

<style scoped>
/* ===== 铃铛触发器 ===== */
.bell-trigger {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 9999px;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
  position: relative;
}

.bell-trigger.light {
  color: #374151;
}
.bell-trigger.light:hover {
  background: rgba(0, 0, 0, 0.04);
}

.bell-trigger.dark {
  color: rgba(255, 255, 255, 0.85);
}
.bell-trigger.dark:hover {
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
}

.bell-icon {
  font-size: 18px;
}

/* ===== 下拉面板 ===== */
.bell-dropdown {
  width: 380px;
  max-height: 520px;
  display: flex;
  flex-direction: column;
}

.dropdown-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px 8px;
  border-bottom: 1px solid #f0f0f0;
}

.dropdown-title {
  font-size: 15px;
  font-weight: 600;
  color: rgba(0, 0, 0, 0.88);
}

.mark-all-btn {
  font-size: 12px;
  padding: 0;
  height: auto;
}

.dropdown-tabs {
  padding: 8px 16px 4px;
}

.dropdown-tabs :deep(.ant-radio-group) {
  width: 100%;
}

.dropdown-tabs :deep(.ant-radio-button-wrapper) {
  flex: 1;
  text-align: center;
  font-size: 12px;
  padding: 0 4px;
  height: 28px;
  line-height: 26px;
}

/* ===== 通知列表 ===== */
.dropdown-list {
  flex: 1;
  overflow-y: auto;
  max-height: 360px;
  padding: 4px 0;
}

.dropdown-list::-webkit-scrollbar {
  width: 4px;
}

.dropdown-list::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.12);
  border-radius: 4px;
}

.notification-item {
  display: flex;
  gap: 10px;
  padding: 10px 16px;
  cursor: pointer;
  transition: background 0.15s;
  position: relative;
}

.notification-item:hover {
  background: rgba(0, 0, 0, 0.02);
}

.notification-item.unread {
  background: rgba(24, 144, 255, 0.03);
}

.notification-item.unread::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 24px;
  background: #1890ff;
  border-radius: 0 3px 3px 0;
}

.item-icon {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f5f7fa;
  border-radius: 10px;
  font-size: 16px;
}

.item-body {
  flex: 1;
  min-width: 0;
}

.item-title {
  font-size: 13px;
  font-weight: 500;
  color: rgba(0, 0, 0, 0.88);
  line-height: 1.4;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.notification-item.unread .item-title {
  font-weight: 600;
}

.item-content {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.45);
  line-height: 1.5;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-top: 2px;
}

.item-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
  font-size: 11px;
  color: rgba(0, 0, 0, 0.35);
}

.item-dot {
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #1890ff;
  margin-top: 14px;
}

/* ===== 底部 ===== */
.dropdown-footer {
  padding: 6px 16px;
  border-top: 1px solid #f0f0f0;
}

.dropdown-footer :deep(.ant-btn-link) {
  font-size: 13px;
  color: rgba(0, 0, 0, 0.65);
  padding: 4px 0;
}

.dropdown-footer :deep(.ant-btn-link:hover) {
  color: #1890ff;
}
</style>

<style>
/* 暗色主题下的 popover 适配 */
.notification-popover.dark .ant-popover-inner {
  background: #1f2937;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);
}

.notification-popover.dark .ant-popover-arrow::before {
  background: #1f2937;
}
</style>
