<template>
  <view class="page">
    <view class="header-fixed">
      <view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
      <view class="nav-bar" :style="{ paddingRight: capsuleRight + 'px' }">
        <view class="nav-back" @tap="goBack">
          <Icon name="arrowLeft" :size="40" color="#2D1B1B" />
        </view>
        <text class="nav-title">通知中心</text>
        <view class="nav-action" @tap="handleMarkAllRead">
          <text class="nav-action-text">全部已读</text>
        </view>
      </view>
    </view>

    <!-- Tab 切换 -->
    <view class="tabs-wrap">
      <view class="tabs">
        <view v-for="tab in tabs" :key="tab.key" class="tab" :class="{ active: currentTab === tab.key }" @tap="switchTab(tab.key)">
          <text class="tab-text">{{ tab.label }}</text>
        </view>
      </view>
    </view>

    <!-- 通知列表 -->
    <view v-if="loading && list.length === 0" class="loading-box">
      <text class="loading-text">加载中...</text>
    </view>

    <view v-else-if="list.length === 0" class="empty-box">
      <Icon name="bell" :size="48" color="#BFB3B3" />
      <text class="empty-text">暂无通知</text>
    </view>

    <view v-else class="notification-list">
      <view v-for="item in list" :key="item.id" class="notification-item" :class="{ unread: !item.is_read, pinned: item.is_pinned }" @tap="handleTap(item)">
        <view class="notif-icon" :style="{ background: getNotifBg(item.type) }">
          <Icon :name="getIconName(item.type)" :size="28" :color="getIconColor(item.type)" />
        </view>
        <view class="notif-content">
          <view class="notif-title-row">
            <text v-if="item.is_pinned" class="pin-badge">📌</text>
            <text class="notif-title">{{ item.title }}</text>
          </view>
          <text class="notif-body" v-if="item.content">{{ item.content }}</text>
          <image v-if="item.image_url" class="notif-image" :src="item.image_url" mode="widthFix" />
          <view class="notif-meta">
            <text class="notif-time">{{ formatTime(item.created_at) }}</text>
            <text v-if="item.link_url" class="notif-link" @tap.stop="openLink(item.link_url)">查看详情</text>
          </view>
          <!-- 管理员操作 -->
          <view v-if="isAdmin && item.type === 'system'" class="admin-actions">
            <view class="admin-btn" @tap.stop="handleTogglePin(item)">
              <text class="admin-btn-text">{{ item.is_pinned ? '取消置顶' : '置顶' }}</text>
            </view>
            <view class="admin-btn danger" @tap.stop="handleDeleteNotif(item)">
              <text class="admin-btn-text danger-text">删除</text>
            </view>
          </view>
        </view>
        <view v-if="!item.is_read" class="unread-dot"></view>
      </view>

      <view v-if="noMore && list.length > 0" class="no-more">
        <text class="no-more-text">没有更多了</text>
      </view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { onShow, onReachBottom } from '@dcloudio/uni-app'
import { useNotificationStore } from '@/stores/notification'
import { useUserStore } from '@/stores/user'
import { getNotifications, markRead, markAllRead, deleteNotification, updateNotification } from '@/api/notification'
import { waitForReady } from '@/utils/app-ready'
import { statusBarHeight, capsuleRight } from '@/utils/system'
import Icon from '@/components/Icon/Icon.vue'
import type { Notification } from '@/api/notification'

const notifStore = useNotificationStore()
const userStore = useUserStore()
const isAdmin = computed(() => userStore.userInfo?.role === 'admin')

const tabs = [
  { key: 'all', label: '全部' },
  { key: 'system', label: '公告' },
  { key: 'group', label: '群组' },
  { key: 'personal', label: '个人' },
]

const currentTab = ref('all')
const list = ref<Notification[]>([])
const page = ref(1)
const total = ref(0)
const loading = ref(false)
let loadSeq = 0

const noMore = computed(() => list.value.length >= total.value && total.value > 0)

onMounted(async () => {
  await waitForReady()
  await loadNotifications(true)
})

onShow(() => {
  notifStore.fetchUnreadCount()
})

function switchTab(key: string) {
  currentTab.value = key
  loadNotifications(true)
}

async function loadNotifications(reset = false) {
  if (reset) {
    page.value = 1
    list.value = []
  }
  const seq = ++loadSeq
  loading.value = true
  try {
    const params: any = { page: page.value, pageSize: 20 }
    if (currentTab.value !== 'all') params.type = currentTab.value
    const data = await getNotifications(params)
    if (seq !== loadSeq) return
    if (reset) {
      list.value = data.list
    } else {
      list.value = [...list.value, ...data.list]
    }
    total.value = data.total
  } catch (e) {
    console.error('Load notifications error:', e)
  } finally {
    if (seq === loadSeq) loading.value = false
  }
}

function getIconName(type: string) {
  if (type === 'system') return 'bell'
  if (type === 'group') return 'user'
  return 'alert-circle'
}

function getIconColor(type: string) {
  if (type === 'system') return '#FF8C69'
  if (type === 'group') return '#8B7E7E'
  return '#BFB3B3'
}

function getNotifBg(type: string) {
  if (type === 'system') return '#FFE8E0'
  if (type === 'group') return '#F0E0D6'
  return '#FFF0E6'
}

function formatTime(dateStr: string) {
  const d = new Date(dateStr)
  const now = new Date()
  const diff = now.getTime() - d.getTime()
  const minutes = Math.floor(diff / 60000)
  if (minutes < 1) return '刚刚'
  if (minutes < 60) return `${minutes}分钟前`
  const hours = Math.floor(minutes / 60)
  if (hours < 24) return `${hours}小时前`
  const days = Math.floor(hours / 24)
  if (days < 7) return `${days}天前`
  return `${d.getMonth() + 1}月${d.getDate()}日`
}

async function handleTap(item: Notification) {
  if (!item.is_read) {
    try {
      await markRead(item.id)
      item.is_read = 1
      notifStore.fetchUnreadCount()
    } catch {
      uni.showToast({ title: '操作失败', icon: 'none' })
    }
  }
}

async function handleMarkAllRead() {
  try {
    await markAllRead()
    list.value.forEach(item => { item.is_read = 1 })
    notifStore.fetchUnreadCount()
    uni.showToast({ title: '已全部标记已读', icon: 'success' })
  } catch {
    uni.showToast({ title: '操作失败，请重试', icon: 'none' })
  }
}

function openLink(url: string) {
  // #ifdef H5
  window.open(url, '_blank')
  // #endif
  // #ifdef MP-WEIXIN
  uni.setClipboardData({
    data: url,
    success: () => uni.showToast({ title: '链接已复制', icon: 'success' })
  })
  // #endif
}

/** 管理员：切换置顶状态 */
async function handleTogglePin(item: Notification) {
  try {
    await updateNotification(item.id, { is_pinned: !item.is_pinned })
    item.is_pinned = item.is_pinned ? 0 : 1
    uni.showToast({ title: item.is_pinned ? '已置顶' : '已取消置顶', icon: 'success' })
  } catch {
    uni.showToast({ title: '操作失败', icon: 'none' })
  }
}

/** 管理员：删除公告 */
function handleDeleteNotif(item: Notification) {
  uni.showModal({
    title: '删除公告',
    content: `确定删除「${item.title}」？`,
    success: async (res) => {
      if (res.confirm) {
        try {
          await deleteNotification(item.id)
          list.value = list.value.filter(n => n.id !== item.id)
          uni.showToast({ title: '已删除', icon: 'success' })
        } catch {
          uni.showToast({ title: '删除失败', icon: 'none' })
        }
      }
    }
  })
}

function goBack() {
  uni.navigateBack()
}

onReachBottom(() => {
  if (noMore.value || loading.value) return
  page.value++
  loadNotifications(false)
})
</script>

<style lang="scss" scoped>
.page {
  min-height: 100vh;
  background: #FFF8F0;
  padding: 0 0 180rpx;
}

.header-fixed {
  position: sticky;
  top: 0;
  z-index: 100;
  background: #FFF8F0;
}

.status-bar { background: #FFF8F0; }

.nav-bar {
  display: flex;
  align-items: center;
  padding: 16rpx 40rpx 24rpx;
}

.nav-back {
  width: 88rpx;
  height: 88rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  &:active { opacity: 0.6; }
}

.nav-title {
  flex: 1;
  text-align: center;
  font-size: 36rpx;
  font-weight: 600;
  color: #2D1B1B;
}

.nav-action {
  padding: 8rpx 16rpx;
  &:active { opacity: 0.6; }
}

.nav-action-text {
  font-size: 26rpx;
  color: #FF8C69;
}

.tabs-wrap { display: flex; justify-content: center; margin: 0 0 24rpx; }

.tabs {
  display: inline-flex;
  background: #FFF0E6;
  border-radius: 24rpx;
  padding: 8rpx;
}

.tab {
  padding: 12rpx 32rpx;
  border-radius: 20rpx;
  font-size: 26rpx;
  color: #8B7E7E;
  transition: all 0.2s;

  &.active {
    background: #FFFFFF;
    color: #FF8C69;
    font-weight: 600;
    box-shadow: 2rpx 2rpx 8rpx rgba(45, 27, 27, 0.06);
  }
}

.loading-box, .empty-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16rpx;
  padding: 120rpx 0;
}

.loading-text, .empty-text {
  font-size: 28rpx;
  color: #BFB3B3;
}

.notification-list { padding: 0 40rpx; }

.notification-item {
  display: flex;
  align-items: flex-start;
  gap: 20rpx;
  padding: 28rpx 32rpx;
  margin-bottom: 16rpx;
  background: #FFFFFF;
  border-radius: 28rpx;
  border: 2rpx solid #F0E0D6;
  box-shadow: 4rpx 4rpx 12rpx rgba(45, 27, 27, 0.08);
  position: relative;
  overflow: hidden;

  &.unread { border-left: 6rpx solid #FF8C69; }
}

.notif-icon {
  width: 64rpx;
  height: 64rpx;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.notif-content { flex: 1; min-width: 0; }

.notif-title-row {
  display: flex;
  align-items: center;
  gap: 8rpx;
}

.pin-badge {
  font-size: 24rpx;
}

.notif-title {
  font-size: 28rpx;
  font-weight: 600;
  color: #2D1B1B;
  display: block;
}

.notif-body {
  font-size: 24rpx;
  color: #8B7E7E;
  display: block;
  margin-top: 8rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.notif-image {
  width: 100%;
  border-radius: 12rpx;
  margin-top: 12rpx;
}

.notif-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 8rpx;
}

.notif-time {
  font-size: 22rpx;
  color: #BFB3B3;
}

.unread-dot {
  width: 16rpx;
  height: 16rpx;
  border-radius: 50%;
  background: #FF8C69;
  flex-shrink: 0;
  margin-top: 8rpx;
}

.notif-link {
  font-size: 22rpx;
  color: #FF8C69;
  text-decoration: underline;
}

.pinned {
  border-color: #FF8C69;
  background: #FFFAF7;
}

.no-more {
  text-align: center;
  padding: 32rpx 0;
}

.no-more-text {
  font-size: 24rpx;
  color: #BFB3B3;
}

.admin-actions {
  display: flex;
  gap: 12rpx;
  margin-top: 12rpx;
}

.admin-btn {
  padding: 8rpx 16rpx;
  background: #FFF0E6;
  border-radius: 12rpx;

  &.danger { background: #FFE8E8; }
  &:active { opacity: 0.7; }
}

.admin-btn-text {
  font-size: 22rpx;
  color: #FF8C69;
  &.danger-text { color: #FF6B6B; }
}
</style>
