<template>
  <div class="support-page">
    <a-page-header title="客服管理" sub-title="聚焦前台全渠道会话，追踪实时处理效率">
      <template #tags>
        <a-tag color="volcano">待接入 {{ metrics.waitingCount }}</a-tag>
        <a-tag color="blue">进行中 {{ metrics.activeCount }}</a-tag>
        <a-tag color="purple">待跟进 {{ metrics.pendingCount }}</a-tag>
        <a-tag color="green">今日结单 {{ metrics.resolvedToday }}</a-tag>
      </template>
      <template #extra>
        <a-space>
          <span class="metric-extra">满意度 {{ metrics.satisfaction }}/5</span>
          <span class="metric-extra">首响 {{ metrics.avgFirstResponse }} 分钟</span>
        </a-space>
      </template>
    </a-page-header>

    <a-row :gutter="16" class="metric-row">
      <a-col v-for="card in overviewCards" :key="card.key" :span="6">
        <a-card class="metric-card">
          <div class="metric-header">
            <component :is="card.icon" :style="{ color: card.color }" class="metric-icon" />
            <span class="metric-title">{{ card.title }}</span>
          </div>
          <div class="metric-value">{{ card.value }}</div>
          <div class="metric-desc">{{ card.desc }}</div>
        </a-card>
      </a-col>
    </a-row>

    <a-card class="filter-card" :bordered="false">
      <a-form layout="inline" :model="searchForm">
        <a-form-item label="关键词">
          <a-input v-model:value="searchForm.keyword" placeholder="搜索会话编码/客户/客服" allow-clear style="width: 220px" />
        </a-form-item>
        <a-form-item label="状态">
          <a-select v-model:value="searchForm.status" placeholder="全部状态" style="width: 140px">
            <a-select-option v-for="option in statusOptions" :key="option.value" :value="option.value">
              {{ option.label }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="渠道">
          <a-select v-model:value="searchForm.channel" placeholder="全部渠道" style="width: 140px">
            <a-select-option v-for="option in channelOptions" :key="option.value" :value="option.value">
              {{ option.label }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="优先级">
          <a-select v-model:value="searchForm.priority" placeholder="全部优先级" style="width: 140px">
            <a-select-option v-for="option in priorityOptions" :key="option.value" :value="option.value">
              {{ option.label }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="日期范围">
          <a-range-picker v-model:value="searchForm.dateRange" value-format="YYYY-MM-DD" format="YYYY-MM-DD"
            style="width: 280px" allow-clear />
        </a-form-item>
        <a-form-item>
          <a-switch v-model:checked="searchForm.vipOnly" /> 仅看 VIP
        </a-form-item>
        <a-form-item>
          <a-space>
            <a-button type="primary" @click="handleSearch">
              <SearchOutlined /> 搜索
            </a-button>
            <a-button @click="handleReset">
              <ReloadOutlined /> 重置
            </a-button>
          </a-space>
        </a-form-item>
      </a-form>
    </a-card>

    <a-card class="table-card" :bordered="false">
      <template #title>会话列表</template>
      <template #extra>
        <a-space>
          <a-button type="primary" :disabled="!selectedRowKeys.length" :loading="batchResolving"
            @click="handleBatchResolve">
            <CheckCircleOutlined /> 批量结单
          </a-button>
        </a-space>
      </template>

      <a-table row-key="id" size="middle" :columns="columns" :data-source="conversationList" :loading="loading"
        :pagination="pagination" :row-selection="rowSelection" :scroll="{ y: 'calc(100vh - 420px)' }"
        @change="handleTableChange">
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'session'">
            <div class="session-cell">
              <div class="session-top">
                <span class="session-code">{{ record.sessionCode }}</span>
                <a-tag :color="getChannelInfo(record.channel).color">{{ getChannelInfo(record.channel).label }}</a-tag>
                <a-tag :color="getPriorityInfo(record.priority).color">
                  {{ getPriorityInfo(record.priority).label }}
                </a-tag>
                <a-tag v-if="record.customer.vip" color="gold">VIP</a-tag>
              </div>
              <div class="session-customer">
                <a-avatar :src="record.customer.avatar" :size="36" />
                <div class="customer-info">
                  <div class="customer-name">
                    {{ record.customer.nickname }}
                    <span class="customer-level">{{ record.customer.level }}</span>
                  </div>
                  <div class="customer-meta">
                    <EnvironmentOutlined /> {{ record.customer.city }}
                    <span class="customer-intent">{{ record.autoDetectedIntent }}</span>
                  </div>
                </div>
              </div>
              <div class="session-tags">
                <a-tag v-for="tag in record.tags" :key="tag.id" :color="tag.color">{{ tag.name }}</a-tag>
              </div>
            </div>
          </template>

          <template v-else-if="column.key === 'lastMessage'">
            <div class="message-cell">
              <div class="message-text">{{ record.lastMessage }}</div>
              <div class="message-meta">
                <ClockCircleOutlined />
                <span>{{ formatDateTime(record.lastMessageAt) }}</span>
              </div>
            </div>
          </template>

          <template v-else-if="column.key === 'stats'">
            <div class="stat-block">
              <span>
                <MessageOutlined /> 共 {{ record.totalMessages }} 条
              </span>
              <span>
                <BellOutlined /> 未读 {{ record.unreadCount }}
              </span>
              <span>
                <DashboardOutlined /> 等待 {{ record.waitingTime }} 分钟
              </span>
            </div>
          </template>

          <template v-else-if="column.key === 'agent'">
            <div class="agent-cell">
              <template v-if="record.assignedAgent">
                <a-avatar :src="record.assignedAgent.avatar" :size="36" />
                <div class="agent-info">
                  <span class="agent-name">{{ record.assignedAgent.name }}</span>
                  <span class="agent-title">{{ record.assignedAgent.title }}</span>
                </div>
              </template>
              <a-tag v-else color="orange">未分配</a-tag>
              <a-dropdown trigger="click">
                <a-button type="link" class="assign-btn">
                  <UserSwitchOutlined /> 转派
                </a-button>
                <template #overlay>
                  <a-menu @click="({ key }) => handleAssign(record as ConversationSession, Number(key))">
                    <a-menu-item v-for="agent in supportAgents" :key="agent.id">
                      <span>{{ agent.name }} · {{ agent.title }}</span>
                    </a-menu-item>
                  </a-menu>
                </template>
              </a-dropdown>
            </div>
          </template>

          <template v-else-if="column.key === 'status'">
            <a-tag :color="getStatusInfo(record.status).color">
              {{ getStatusInfo(record.status).label }}
            </a-tag>
          </template>

          <template v-else-if="column.key === 'updatedAt'">
            {{ formatDateTime(record.lastMessageAt) }}
          </template>

          <template v-else-if="column.key === 'action'">
            <a-space>
              <a-button type="link" size="small" @click="showDetail(record as ConversationSession)">
                <EyeOutlined /> 查看
              </a-button>
              <a-popconfirm title="确认将该会话标记为已结单？" ok-text="确认" cancel-text="取消"
                @confirm="handleResolve(record as ConversationSession)">
                <a-button type="link" size="small" :loading="updatingSessionId === record.id">
                  <CheckCircleOutlined /> 结单
                </a-button>
              </a-popconfirm>
            </a-space>
          </template>
        </template>
      </a-table>
    </a-card>

    <a-drawer v-model:open="detailVisible" width="720px" placement="right"
      :title="currentSession ? `会话 ${currentSession.sessionCode}` : '会话详情'">
      <template #extra>
        <a-button type="link" v-if="currentSession && currentSession.status !== 'resolved'"
          :loading="updatingSessionId === currentSession.id" @click="handleResolve(currentSession)">
          <CheckCircleOutlined /> 标记结单
        </a-button>
      </template>
      <div v-if="currentSession" class="drawer-content">
        <div class="drawer-section">
          <div class="drawer-customer">
            <a-avatar :src="currentSession.customer.avatar" :size="48" />
            <div class="drawer-customer-info">
              <div class="name-line">
                <span class="name">{{ currentSession.customer.nickname }}</span>
                <a-tag color="gold" v-if="currentSession.customer.vip">VIP</a-tag>
              </div>
              <div class="customer-extra">
                <EnvironmentOutlined /> {{ currentSession.customer.city }}
                <span>等级 {{ currentSession.customer.level }}</span>
              </div>
            </div>
          </div>
          <div class="drawer-meta">
            <a-tag :color="channelMap[currentSession.channel].color">{{ channelMap[currentSession.channel].label
              }}</a-tag>
            <a-tag :color="priorityMap[currentSession.priority].color">{{ priorityMap[currentSession.priority].label
              }}</a-tag>
            <a-tag :color="statusMap[currentSession.status].color">{{ statusMap[currentSession.status].label }}</a-tag>
          </div>
          <div class="drawer-tags">
            <a-tag v-for="tag in currentSession.tags" :key="tag.id" :color="tag.color">{{ tag.name }}</a-tag>
          </div>
          <div class="drawer-stats">
            <div>
              <span class="stat-label">来源</span>
              <span>{{ currentSession.source }}</span>
            </div>
            <div>
              <span class="stat-label">识别意图</span>
              <span>{{ currentSession.autoDetectedIntent }}</span>
            </div>
            <div>
              <span class="stat-label">首响</span>
              <span>{{ currentSession.firstResponseAt ? formatDateTime(currentSession.firstResponseAt) : '待响应' }}</span>
            </div>
          </div>
        </div>
        <a-divider />
        <div class="message-list">
          <div v-for="message in currentSession.messages" :key="message.id" :class="['message-item', message.sender]">
            <div class="drawer-message-meta">
              <span class="meta-name">{{ message.senderName }}</span>
              <span class="meta-time">{{ formatDateTime(message.timestamp) }}</span>
            </div>
            <div class="message-content">{{ message.content }}</div>
          </div>
        </div>
      </div>
      <a-empty v-else description="暂无会话数据" />
    </a-drawer>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import type { TablePaginationConfig } from 'ant-design-vue'
import type { Key } from 'ant-design-vue/es/table/interface'
import {
  SearchOutlined,
  ReloadOutlined,
  CustomerServiceOutlined,
  MessageOutlined,
  TeamOutlined,
  ClockCircleOutlined,
  CheckCircleOutlined,
  BellOutlined,
  DashboardOutlined,
  EyeOutlined,
  EnvironmentOutlined,
  UserSwitchOutlined
} from '@ant-design/icons-vue'
import type { ConversationAgent, ConversationChannel, ConversationPriority, ConversationSession, ConversationStatus } from '@/types'
import {
  mockGetConversationList,
  mockUpdateConversationStatus,
  mockAssignConversationAgent,
  mockGetSupportAgents
} from '@/mock'
import { formatDateTime } from '@/utils/common'

type StatusFilter = ConversationStatus | 'all'
type PriorityFilter = ConversationPriority | 'all'
type ChannelFilter = ConversationSession['channel'] | 'all'

const loading = ref(false)
const conversationList = ref<ConversationSession[]>([])
const selectedRowKeys = ref<Key[]>([])
const batchResolving = ref(false)
const updatingSessionId = ref<number | null>(null)
const detailVisible = ref(false)
const currentSession = ref<ConversationSession | null>(null)
const supportAgents = ref<ConversationAgent[]>([])

const pagination = reactive({
  current: 1,
  pageSize: 10,
  total: 0,
  showSizeChanger: true,
  showQuickJumper: true,
  showTotal: (total: number) => `共 ${total} 条`
})

const metrics = reactive({
  waitingCount: 0,
  activeCount: 0,
  pendingCount: 0,
  resolvedToday: 0,
  satisfaction: 0,
  avgFirstResponse: 0
})

const searchForm = reactive({
  keyword: '',
  status: 'all' as StatusFilter,
  channel: 'all' as ChannelFilter,
  priority: 'all' as PriorityFilter,
  vipOnly: false,
  dateRange: undefined as [string, string] | undefined
})

const overviewCards = computed(() => [
  {
    key: 'waiting',
    title: '待接入',
    value: metrics.waitingCount,
    desc: `平均等待 ${averageWaitingTime.value} 分钟`,
    icon: CustomerServiceOutlined,
    color: '#fa8c16'
  },
  {
    key: 'progress',
    title: '进行中',
    value: metrics.activeCount,
    desc: `首响 ${metrics.avgFirstResponse} 分钟`,
    icon: TeamOutlined,
    color: '#1890ff'
  },
  {
    key: 'pending',
    title: '待跟进',
    value: metrics.pendingCount,
    desc: '建议优先处理',
    icon: BellOutlined,
    color: '#722ed1'
  },
  {
    key: 'satisfaction',
    title: '满意度',
    value: `${metrics.satisfaction}/5`,
    desc: `今日结单 ${metrics.resolvedToday}`,
    icon: MessageOutlined,
    color: '#52c41a'
  }
])

const averageWaitingTime = computed(() => {
  if (!conversationList.value.length) return 0
  const total = conversationList.value.reduce((sum, item) => sum + item.waitingTime, 0)
  return Math.round(total / conversationList.value.length)
})

const statusOptions = [
  { label: '全部', value: 'all' },
  { label: '待接入', value: 'waiting' },
  { label: '进行中', value: 'active' },
  { label: '待跟进', value: 'pending' },
  { label: '已结单', value: 'resolved' }
]

const channelOptions = [
  { label: '全部渠道', value: 'all' },
  { label: 'App', value: 'app' },
  { label: 'Web', value: 'web' },
  { label: '企业微信', value: 'wechat' },
  { label: '小程序', value: 'miniapp' }
]

const priorityOptions = [
  { label: '全部优先级', value: 'all' },
  { label: '普通', value: 'normal' },
  { label: '加急', value: 'high' },
  { label: 'VIP', value: 'vip' }
]

const columns = [
  { title: '会话', key: 'session', width: 280 },
  { title: '最近内容', key: 'lastMessage', width: 260 },
  { title: '统计', key: 'stats', width: 200 },
  { title: '处理人', key: 'agent', width: 200 },
  { title: '状态', key: 'status', width: 100 },
  { title: '更新时间', key: 'updatedAt', width: 180 },
  { title: '操作', key: 'action', width: 160, fixed: 'right' as const }
]

const statusMap: Record<ConversationStatus, { label: string; color: string }> = {
  waiting: { label: '待接入', color: 'orange' },
  active: { label: '进行中', color: 'blue' },
  pending: { label: '待跟进', color: 'purple' },
  resolved: { label: '已结单', color: 'green' },
  closed: { label: '已关闭', color: 'default' }
}

const channelMap: Record<ConversationChannel, { label: string; color: string }> = {
  app: { label: 'App', color: 'blue' },
  web: { label: 'Web', color: 'geekblue' },
  wechat: { label: '企业微信', color: 'cyan' },
  miniapp: { label: '小程序', color: 'purple' }
}

const priorityMap: Record<ConversationPriority, { label: string; color: string }> = {
  normal: { label: '普通', color: 'default' },
  high: { label: '加急', color: 'orange' },
  vip: { label: 'VIP', color: 'red' }
}

// 辅助函数用于处理模板中的类型安全访问
function getChannelInfo(channel: string): { label: string; color: string } {
  return channelMap[channel as ConversationChannel] || { label: channel, color: 'default' }
}

function getPriorityInfo(priority: string): { label: string; color: string } {
  return priorityMap[priority as ConversationPriority] || { label: priority, color: 'default' }
}

function getStatusInfo(status: string): { label: string; color: string } {
  return statusMap[status as ConversationStatus] || { label: status, color: 'default' }
}

const rowSelection = computed(() => ({
  selectedRowKeys: selectedRowKeys.value,
  onChange: onSelectChange
}))

function onSelectChange(keys: Key[]) {
  selectedRowKeys.value = keys
}

async function loadSessions() {
  loading.value = true
  try {
    const res = await mockGetConversationList({
      page: pagination.current,
      pageSize: pagination.pageSize,
      keyword: searchForm.keyword || undefined,
      status: searchForm.status,
      channel: searchForm.channel,
      priority: searchForm.priority,
      vipOnly: searchForm.vipOnly,
      dateRange: searchForm.dateRange
    })
    conversationList.value = res.list
    pagination.total = res.total
    Object.assign(metrics, res.metrics)
    if (detailVisible.value && currentSession.value) {
      const refreshed = res.list.find(item => item.id === currentSession.value?.id)
      if (refreshed) {
        currentSession.value = refreshed
      }
    }
  } catch (error) {
    console.error(error)
    message.error('客服会话数据加载失败，请稍后重试')
  } finally {
    loading.value = false
  }
}

function handleSearch() {
  pagination.current = 1
  loadSessions()
}

function handleReset() {
  searchForm.keyword = ''
  searchForm.status = 'all'
  searchForm.channel = 'all'
  searchForm.priority = 'all'
  searchForm.vipOnly = false
  searchForm.dateRange = undefined
  pagination.current = 1
  loadSessions()
}

function handleTableChange(pag: TablePaginationConfig) {
  pagination.current = pag.current || 1
  pagination.pageSize = pag.pageSize || 10
  loadSessions()
}

async function handleBatchResolve() {
  if (!selectedRowKeys.value.length) return
  batchResolving.value = true
  try {
    await Promise.all(selectedRowKeys.value.map(key => mockUpdateConversationStatus(Number(key), 'resolved')))
    message.success(`已结单 ${selectedRowKeys.value.length} 条会话`)
    selectedRowKeys.value = []
    await loadSessions()
  } catch (error) {
    console.error(error)
    message.error('批量结单失败，请稍后重试')
  } finally {
    batchResolving.value = false
  }
}

async function handleResolve(record: ConversationSession) {
  updatingSessionId.value = record.id
  try {
    await mockUpdateConversationStatus(record.id, 'resolved')
    message.success('会话已结单')
    await loadSessions()
  } catch (error) {
    console.error(error)
    message.error('结单失败，请稍后重试')
  } finally {
    updatingSessionId.value = null
  }
}

async function handleAssign(record: ConversationSession, agentId: number) {
  updatingSessionId.value = record.id
  try {
    await mockAssignConversationAgent(record.id, agentId)
    message.success('分配成功')
    await loadSessions()
  } catch (error) {
    console.error(error)
    message.error('分配失败，请稍后重试')
  } finally {
    updatingSessionId.value = null
  }
}

function showDetail(record: ConversationSession) {
  currentSession.value = record
  detailVisible.value = true
}

onMounted(() => {
  supportAgents.value = mockGetSupportAgents()
  loadSessions()
})
</script>

<style scoped>
.support-page {
  display: flex;
  flex-direction: column;
  gap: 16px;
  height: 100%;
  overflow: hidden;
}

.metric-row {
  margin-bottom: 8px;
}

.metric-card {
  border-radius: 10px;
  background: linear-gradient(120deg, #f8fbff, #ffffff);
  min-height: 120px;
}

.metric-header {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #7a8194;
  font-size: 13px;
}

.metric-icon {
  font-size: 22px;
}

.metric-value {
  font-size: 32px;
  font-weight: 600;
  color: #1a1a2e;
  margin-top: 8px;
}

.metric-desc {
  font-size: 12px;
  color: #8c8c8c;
}

.metric-extra {
  font-size: 13px;
  color: #5c6370;
}

.filter-card {
  flex-shrink: 0;
}

.table-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

:deep(.table-card .ant-card-body) {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding-bottom: 12px;
}

:deep(.ant-table-wrapper) {
  flex: 1;
  min-height: 0;
}

.session-cell {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.session-top {
  display: flex;
  align-items: center;
  gap: 6px;
}

.session-code {
  font-weight: 600;
  color: #1a1a2e;
}

.session-customer {
  display: flex;
  align-items: center;
  gap: 12px;
}

.customer-info {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.customer-name {
  font-weight: 500;
  color: #1a1a2e;
}

.customer-level {
  font-size: 12px;
  color: #8c8c8c;
  margin-left: 8px;
}

.customer-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: #8c8c8c;
}

.customer-intent {
  padding: 1px 8px;
  border-radius: 999px;
  background-color: #f6ffed;
  color: #389e0d;
  font-size: 12px;
}

.session-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.message-cell {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.message-text {
  color: #1a1a2e;
  font-weight: 500;
}

.message-meta {
  font-size: 12px;
  color: #8c8c8c;
  display: flex;
  align-items: center;
  gap: 6px;
}

.stat-block {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12px;
  color: #5c6370;
}

.agent-cell {
  display: flex;
  align-items: center;
  gap: 10px;
}

.agent-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 12px;
  color: #5c6370;
}

.agent-name {
  font-weight: 500;
  color: #1a1a2e;
}

.assign-btn {
  padding-left: 0;
}

.drawer-content {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.drawer-section {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.drawer-customer {
  display: flex;
  gap: 12px;
  align-items: center;
}

.drawer-customer-info {
  display: flex;
  flex-direction: column;
}

.name-line {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 18px;
  font-weight: 600;
}

.drawer-meta {
  display: flex;
  gap: 8px;
}

.drawer-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.drawer-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  font-size: 13px;
  color: #5c6370;
}

.stat-label {
  display: block;
  font-size: 12px;
  color: #8c8c8c;
}

.message-list {
  max-height: calc(100vh - 280px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-right: 8px;
}

.message-item {
  border-radius: 8px;
  padding: 12px;
  border: 1px solid #f0f0f0;
}

.message-item.user {
  background-color: #fff7e6;
  border-color: #ffe7ba;
}

.message-item.agent {
  background-color: #f6ffed;
  border-color: #d9f7be;
}

.drawer-message-meta {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: #8c8c8c;
  margin-bottom: 4px;
}

.message-content {
  font-size: 14px;
  color: #1a1a2e;
  line-height: 1.6;
}
</style>
