<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { Bell, ChatDotRound, Refresh, Tickets } from '@element-plus/icons-vue'
import { fetchChats, type ChatConversation } from '@/features/chats/api/chats'
import { useChatSSE, type ChatEvent } from '@/features/chats/composables/useChatSSE'
import { useDesktopNotification } from '@/features/chats/composables/useDesktopNotification'
import NotificationSettings from '@/features/chats/components/NotificationSettings.vue'
import {
  fetchNotifications,
  markAllNotificationsRead,
  markNotificationRead,
  type NotificationItem,
} from '@/features/auth/api/notifications'
import {
  notificationUnreadChangedEvent,
  useNotificationUnreadCount,
} from '@/features/auth/composables/useNotificationUnreadCount'
import { formatDateMinute, formatDateTime } from '@/shared/utils/time'

const router = useRouter()
const route = useRoute()
const currentUserId = Number(localStorage.getItem('user_id') || 0)

// ── 聊天状态 ──
const loading = ref(false)
const conversations = ref<ChatConversation[]>([])
const page = ref(1)
const pageSize = 20
const total = ref(0)

const hasMore = computed(() => conversations.value.length < total.value)
const unreadTotal = computed(() =>
  conversations.value.reduce((sum, item) => sum + item.unread_count, 0)
)

// ── 通知状态 ──
const notiLoading = ref(false)
const notiSubmitting = ref(false)
const notifications = ref<NotificationItem[]>([])
const notiPage = ref(1)
const notiPageSize = 20
const notiTotal = ref(0)
const { unreadCount: notificationUnreadCount } = useNotificationUnreadCount(route)

// ── 合并未读 ──
const combinedUnread = computed(() => unreadTotal.value + notificationUnreadCount.value)

// ── Tab ──
const activeTab = ref('chats')

const desktopNotification = useDesktopNotification('user')
const { onEvent } = useChatSSE('user', '/api/chats/events')
onEvent(handleSSEEvent)

onMounted(() => {
  desktopNotification.requestPermissionSilently()
  loadChats(true)
})

// ── 聊天方法 ──
async function loadChats(isRefresh = false, showLoading = true) {
  if (isRefresh) page.value = 1
  if (loading.value) return
  if (showLoading) loading.value = true
  try {
    const res = await fetchChats(page.value, pageSize)
    conversations.value = isRefresh ? res.items : [...conversations.value, ...res.items]
    total.value = res.total
    if (conversations.value.length < res.total && res.items.length > 0) {
      page.value += 1
    }
  } catch {
    ElMessage.error('获取会话失败')
  } finally {
    loading.value = false
  }
}

function handleSSEEvent(event: ChatEvent) {
  if (event.type === 'new_message' || event.type === 'conversation_updated') {
    loadChats(true, false)
    window.dispatchEvent(new Event('chat-unread-changed'))
  }
  if (event.type === 'new_message' && event.message) {
    const isSelf = event.message.sender_type === 'user' && event.message.sender_id === currentUserId
    if (!isSelf) {
      desktopNotification.notify(event, null)
    }
  }
}

function openConversation(item: ChatConversation) {
  router.push(`/messages/${item.id}`)
}

function roleLabel(role: string) {
  const map: Record<string, string> = {
    renter: '租客',
    owner: '号主',
    support: '客服',
    customer: '咨询',
  }
  return map[role] || '成员'
}

function conversationTypeMeta(item: ChatConversation) {
  if (item.type === 'listing_group') return { icon: '📢', label: '账号群' }
  if (item.type === 'order_group' || item.order_id) return { icon: '📦', label: '订单' }
  return { icon: '🎧', label: '平台客服' }
}

function previewText(item: ChatConversation) {
  return (
    item.last_message_preview ||
    (item.type === 'general_support' ? '客服会话已创建' : '订单群聊已创建')
  )
}

// ── 通知方法 ──
async function loadNotifications(reset = false) {
  if (notiLoading.value) return
  if (reset) notiPage.value = 1
  notiLoading.value = true
  try {
    const result = await fetchNotifications(notiPage.value, notiPageSize)
    notifications.value = reset ? result.items : [...notifications.value, ...result.items]
    notiTotal.value = result.total
    if (notifications.value.length < result.total && result.items.length > 0) {
      notiPage.value += 1
    }
  } catch {
    ElMessage.error('站内信加载失败')
  } finally {
    notiLoading.value = false
  }
}

async function markNotiRead(item: NotificationItem) {
  if (item.read_at) return
  try {
    await markNotificationRead(item.id)
    item.read_at = new Date().toISOString()
    window.dispatchEvent(new Event(notificationUnreadChangedEvent))
    ElMessage.success('已标记为已读')
  } catch {
    ElMessage.error('操作失败')
  }
}

async function markAllNotiRead() {
  if (notiSubmitting.value) return
  notiSubmitting.value = true
  try {
    const result = await markAllNotificationsRead()
    window.dispatchEvent(new Event(notificationUnreadChangedEvent))
    ElMessage.success(result.read_count > 0 ? `已标记 ${result.read_count} 条通知` : '暂无未读通知')
    await loadNotifications(true)
  } catch {
    ElMessage.error('操作失败')
  } finally {
    notiSubmitting.value = false
  }
}

function notiHasMore() {
  return notifications.value.length < notiTotal.value
}

// ── Tab 切换 ──
function handleTabChange(tab: string) {
  if (tab === 'notifications' && notifications.value.length === 0) {
    loadNotifications(true)
  }
}
</script>

<template>
  <section class="page messages-page">
    <div class="page-header-row">
      <div class="page-header">
        <p class="eyebrow">Messages</p>
        <h1>消息</h1>
        <p>
          {{
            combinedUnread > 0
              ? `${combinedUnread} 条未读`
              : '查看订单群聊、平台客服消息和系统通知。'
          }}
        </p>
      </div>
      <div class="header-actions">
        <NotificationSettings scope="user" />
        <el-button :icon="Refresh" :loading="loading" @click="loadChats(true)">刷新</el-button>
        <el-button type="primary" :icon="Tickets" @click="router.push('/orders')"
          >我的订单</el-button
        >
      </div>
    </div>

    <el-tabs v-model="activeTab" class="messages-tabs" @tab-change="handleTabChange">
      <!-- 聊天 Tab -->
      <el-tab-pane name="chats">
        <template #label>
          <span class="tab-label">
            <el-icon><ChatDotRound /></el-icon>
            聊天
            <em v-if="unreadTotal > 0" class="tab-badge">{{ unreadTotal > 99 ? '99+' : unreadTotal }}</em>
          </span>
        </template>

        <div v-if="loading && conversations.length === 0" class="message-loading" v-loading="loading" />

        <div v-else-if="!loading && conversations.length === 0" class="empty-panel">
          <el-empty description="暂无会话">
            <el-button type="primary" :icon="Tickets" @click="router.push('/orders')"
              >查看订单</el-button
            >
          </el-empty>
        </div>

        <div v-else v-loading="loading" class="conversation-list">
          <button
            v-for="item in conversations"
            :key="item.id"
            class="conversation-item"
            type="button"
            @click="openConversation(item)"
          >
            <div class="avatar-stack">
              <span class="avatar main">{{ roleLabel(item.role).slice(0, 1) }}</span>
              <span class="avatar support">客</span>
            </div>
            <div class="conversation-body">
              <div class="conversation-head">
                <h2>
                  <span class="conv-type-icon">{{ conversationTypeMeta(item).icon }}</span>
                  {{ item.title }}
                </h2>
                <span class="conversation-time">{{
                  formatDateMinute(item.last_message_at || item.created_at)
                }}</span>
              </div>
              <div class="conversation-meta">
                <span class="role-chip">{{ roleLabel(item.role) }}</span>
                <span class="order-id">{{ conversationTypeMeta(item).label }}</span>
              </div>
              <p class="conversation-preview">{{ previewText(item) }}</p>
            </div>
            <span v-if="item.unread_count > 0" class="unread-badge">
              {{ item.unread_count > 99 ? '99+' : item.unread_count }}
            </span>
          </button>
        </div>

        <div v-if="hasMore && conversations.length > 0" class="pagination-wrap">
          <el-button :loading="loading" @click="loadChats(false)">加载更多</el-button>
        </div>
      </el-tab-pane>

      <!-- 通知 Tab -->
      <el-tab-pane name="notifications">
        <template #label>
          <span class="tab-label">
            <el-icon><Bell /></el-icon>
            通知
            <em v-if="notificationUnreadCount > 0" class="tab-badge">{{ notificationUnreadCount > 99 ? '99+' : notificationUnreadCount }}</em>
          </span>
        </template>

        <div class="noti-toolbar">
          <span v-if="notificationUnreadCount > 0" class="noti-toolbar-text">
            {{ notificationUnreadCount }} 条未读
          </span>
          <span v-else class="noti-toolbar-text">暂无未读通知</span>
          <el-button
            size="small"
            type="primary"
            :loading="notiSubmitting"
            :disabled="notificationUnreadCount === 0"
            @click="markAllNotiRead"
          >全部已读</el-button>
        </div>

        <div v-if="notiLoading && notifications.length === 0" class="message-loading" v-loading="notiLoading" />

        <div v-else-if="!notiLoading && notifications.length === 0" class="empty-panel">
          <el-empty description="暂无站内信" />
        </div>

        <div v-else v-loading="notiLoading" class="notification-list">
          <div
            v-for="item in notifications"
            :key="item.id"
            class="notification-item"
            :class="{ unread: !item.read_at }"
          >
            <div class="notification-body">
              <span class="noti-type-chip">{{ item.type }}</span>
              <h2>{{ item.title }}</h2>
              <p>{{ item.content }}</p>
              <small>{{ formatDateTime(item.created_at) }}</small>
            </div>
            <div class="notification-actions">
              <el-button
                v-if="item.biz_type === 'order' && item.biz_id"
                size="small"
                @click="router.push(`/orders/${item.biz_id}`)"
              >查看订单</el-button>
              <el-button
                v-if="!item.read_at"
                size="small"
                type="primary"
                @click="markNotiRead(item)"
              >已读</el-button>
            </div>
          </div>

          <div v-if="notiHasMore()" class="pagination-wrap">
            <el-button :loading="notiLoading" @click="loadNotifications(false)">加载更多</el-button>
          </div>
        </div>
      </el-tab-pane>
    </el-tabs>
  </section>
</template>

<style scoped>
.messages-page {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.page-header-row {
  align-items: flex-end;
}

.header-actions {
  display: flex;
  gap: 10px;
}

/* ── Tabs ── */
.messages-tabs {
  margin-top: 4px;
}

.tab-label {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-weight: 600;
}

.tab-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: #ef4444;
  color: #fff;
  font-size: 10px;
  font-style: normal;
  font-weight: 800;
  line-height: 1;
}

/* ── 通用 ── */
.message-loading,
.empty-panel {
  min-height: 360px;
  border: 1px solid #e8edf3;
  border-radius: 8px;
  background: #fff;
}

.empty-panel {
  display: grid;
  place-items: center;
}

.pagination-wrap {
  display: flex;
  justify-content: center;
  margin-top: 16px;
}

/* ── 通知工具栏 ── */
.noti-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.noti-toolbar-text {
  color: #6b7280;
  font-size: 13px;
}

/* ── 聊天列表 ── */
.conversation-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 180px;
}

.conversation-item {
  position: relative;
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr);
  gap: 12px;
  width: 100%;
  padding: 14px 16px;
  border: 1px solid #e8edf3;
  border-radius: 10px;
  background: #fff;
  text-align: left;
  cursor: pointer;
  transition:
    border-color 0.15s,
    box-shadow 0.15s;
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.04);
}

.conversation-item:hover {
  border-color: #1477ff;
  box-shadow: 0 4px 16px rgba(20, 119, 255, 0.1);
}

.avatar-stack {
  position: relative;
  width: 48px;
  height: 48px;
  flex-shrink: 0;
}

.avatar {
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: #fff;
  font-weight: 800;
}

.avatar.main {
  width: 44px;
  height: 44px;
  background: #1477ff;
  font-size: 16px;
}

.avatar.support {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 22px;
  height: 22px;
  border: 2px solid #fff;
  background: #10b981;
  font-size: 11px;
}

.conversation-body {
  min-width: 0;
}

.conversation-head {
  display: flex;
  align-items: center;
  gap: 8px;
}

.conversation-head h2 {
  flex: 1;
  min-width: 0;
  margin: 0;
  overflow: hidden;
  color: #17233d;
  font-size: 15px;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.conv-type-icon {
  margin-right: 4px;
}

.conversation-time {
  flex: none;
  color: #9ca3af;
  font-size: 12px;
}

.conversation-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  color: #6b7785;
  font-size: 12px;
}

.role-chip {
  padding: 1px 8px;
  border-radius: 999px;
  background: #eef6ff;
  color: #1477ff;
  font-size: 11px;
  font-weight: 700;
}

.order-id {
  color: #8a94a6;
}

.conversation-preview {
  margin: 6px 0 0;
  overflow: hidden;
  color: #4b5563;
  font-size: 13px;
  line-height: 1.4;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.unread-badge {
  position: absolute;
  right: 14px;
  bottom: 14px;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 10px;
  background: #ef4444;
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  line-height: 20px;
  text-align: center;
}

/* ── 通知列表 ── */
.notification-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 180px;
}

.notification-item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 16px;
  border: 1px solid #e8edf3;
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 2px 8px rgba(15, 23, 42, 0.04);
  transition:
    border-color 0.15s,
    box-shadow 0.15s;
}

.notification-item:hover {
  border-color: #1477ff;
  box-shadow: 0 4px 16px rgba(20, 119, 255, 0.1);
}

.notification-item.unread {
  border-color: rgba(255, 106, 0, 0.35);
  background: #fffaf5;
}

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

.noti-type-chip {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  background: #eef6ff;
  color: #1477ff;
  font-size: 11px;
  font-weight: 700;
}

.notification-body h2 {
  margin: 8px 0 4px;
  color: #17233d;
  font-size: 14px;
  font-weight: 700;
}

.notification-body p {
  margin: 0;
  color: #4b5563;
  font-size: 13px;
  line-height: 20px;
}

.notification-body small {
  color: #9ca3af;
  font-size: 12px;
}

.notification-actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex-shrink: 0;
}
</style>
