<template>
  <div>
    <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;">
      <h3 style="margin: 0;">聊天记录</h3>
      <div style="display: flex; gap: 8px;">
        <el-input v-model="searchKeyword" placeholder="搜索订单号/昵称" clearable style="width: 200px;"
          @clear="fetchList" @keyup.enter="fetchList" />
        <el-select v-model="statusFilter" placeholder="订单状态" clearable style="width: 140px;" @change="fetchList">
          <el-option label="进行中" value="InProgress" />
          <el-option label="待确认" value="WaitConfirm" />
          <el-option label="已完成" value="Completed" />
          <el-option label="申诉中" value="Appealing" />
        </el-select>
        <el-button type="primary" @click="fetchList">查询</el-button>
      </div>
    </div>

    <el-table :data="filteredList" v-loading="loading" border>
      <el-table-column prop="orderNo" label="订单编号" width="160" show-overflow-tooltip />
      <el-table-column prop="orderType" label="类型" width="80">
        <template #default="{ row }">{{ typeLabel(row.orderType) }}</template>
      </el-table-column>
      <el-table-column label="状态" width="90">
        <template #default="{ row }">
          <el-tag :type="statusTagType(row.status)" size="small">{{ statusLabel(row.status) }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="单主" min-width="120">
        <template #default="{ row }">
          <div style="display: flex; align-items: center; gap: 6px;">
            <el-avatar :size="28" :src="row.ownerAvatar || undefined">
              <span style="font-size: 12px">{{ (row.ownerNickname || '?')[0] }}</span>
            </el-avatar>
            <span>{{ row.ownerNickname }}</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="跑腿" min-width="120">
        <template #default="{ row }">
          <div style="display: flex; align-items: center; gap: 6px;">
            <el-avatar :size="28" :src="row.runnerAvatar || undefined">
              <span style="font-size: 12px">{{ (row.runnerNickname || '?')[0] }}</span>
            </el-avatar>
            <span>{{ row.runnerNickname }}</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="itemName" label="内容" show-overflow-tooltip />
      <el-table-column prop="createdAt" label="下单时间" width="170">
        <template #default="{ row }">{{ formatTime(row.createdAt) }}</template>
      </el-table-column>
      <el-table-column label="操作" width="120" fixed="right" align="center">
        <template #default="{ row }">
          <el-button size="small" type="primary" @click="viewChat(row)">查看聊天</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 聊天记录弹窗 -->
    <el-dialog v-model="chatDialogVisible" :title="chatDialogTitle" width="600px" top="5vh" destroy-on-close>
      <div v-loading="chatLoading" class="chat-container">
        <div v-if="chatMessages.length === 0 && !chatLoading" class="chat-empty">暂无聊天记录</div>
        <div v-for="(msg, index) in chatMessages" :key="index" class="chat-msg-wrap">
          <!-- 时间分割 -->
          <div v-if="msg.showTime" class="chat-time-divider">
            <span>{{ msg.timeLabel }}</span>
          </div>
          <!-- 系统消息 -->
          <div v-if="msg.isSystem" class="chat-system-msg">
            <span>{{ msg.text }}</span>
          </div>
          <!-- 普通消息 -->
          <div v-else :class="['chat-bubble-row', msg.isOwner ? 'chat-right' : 'chat-left']">
            <el-avatar :size="32" :src="msg.avatar || undefined" class="chat-avatar-item">
              <span style="font-size: 12px">{{ (msg.nickname || '?')[0] }}</span>
            </el-avatar>
            <div class="chat-bubble-wrap">
              <div class="chat-nickname">{{ msg.nickname }}</div>
              <div :class="['chat-bubble', msg.isOwner ? 'bubble-right' : 'bubble-left']">
                <img v-if="msg.type === 'image'" :src="msg.text" class="chat-img" @click="previewImage(msg.text)" />
                <span v-else>{{ msg.text }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </el-dialog>

    <!-- 图片预览 -->
    <el-image-viewer v-if="previewVisible" :url-list="[previewUrl]" @close="previewVisible = false" />
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import request from '../utils/request'

const loading = ref(false)
const chatLoading = ref(false)
const list = ref([])
const searchKeyword = ref('')
const statusFilter = ref('')
const chatDialogVisible = ref(false)
const chatDialogTitle = ref('')
const chatMessages = ref([])
const previewVisible = ref(false)
const previewUrl = ref('')

const typeLabel = (t) => ({ Pickup: '代取', Delivery: '代送', Help: '万能帮', Purchase: '代购', Food: '美食街' }[t] || t)
const statusLabel = (s) => ({ Pending: '待接单', InProgress: '进行中', WaitConfirm: '待确认', Completed: '已完成', Cancelled: '已取消', Appealing: '申诉中' }[s] || s)
const statusTagType = (s) => ({ Pending: 'info', InProgress: 'primary', WaitConfirm: 'warning', Completed: 'success', Cancelled: 'danger', Appealing: '' }[s] || 'info')
const formatTime = (t) => t ? new Date(t).toLocaleString('zh-CN') : ''

const filteredList = computed(() => {
  let data = list.value
  if (statusFilter.value) {
    data = data.filter(item => item.status === statusFilter.value)
  }
  if (searchKeyword.value) {
    const kw = searchKeyword.value.toLowerCase()
    data = data.filter(item =>
      (item.orderNo || '').toLowerCase().includes(kw) ||
      (item.ownerNickname || '').toLowerCase().includes(kw) ||
      (item.runnerNickname || '').toLowerCase().includes(kw)
    )
  }
  return data
})

async function fetchList() {
  loading.value = true
  try {
    list.value = await request.get('/admin/chat-list')
  } finally {
    loading.value = false
  }
}

async function viewChat(row) {
  chatDialogTitle.value = `聊天记录 - ${row.orderNo} (${row.ownerNickname} ↔ ${row.runnerNickname})`
  chatDialogVisible.value = true
  chatLoading.value = true
  chatMessages.value = []

  try {
    const res = await request.get('/admin/chat-messages', {
      params: { ownerUserId: row.ownerId, runnerUserId: row.runnerId }
    })
    chatMessages.value = parseIMMessages(res, row)
  } catch (e) {
    console.error('拉取聊天记录失败:', e)
  } finally {
    chatLoading.value = false
  }
}

function parseIMMessages(imResponse, orderInfo) {
  const msgList = imResponse.MsgList || imResponse.msgList || []
  if (!msgList.length) return []

  const ownerImId = `user_${orderInfo.ownerId}`
  const result = []
  let lastTime = 0

  const sorted = [...msgList].sort((a, b) => {
    const ta = a.MsgTimeStamp || a.msgTimeStamp || 0
    const tb = b.MsgTimeStamp || b.msgTimeStamp || 0
    return ta - tb
  })

  for (const msg of sorted) {
    const from = msg.From_Account || msg.from_Account || ''
    const timestamp = (msg.MsgTimeStamp || msg.msgTimeStamp || 0) * 1000
    const isOwner = from === ownerImId
    const nickname = isOwner ? orderInfo.ownerNickname : orderInfo.runnerNickname
    const avatar = isOwner ? orderInfo.ownerAvatar : orderInfo.runnerAvatar

    const showTime = timestamp - lastTime > 300000
    let timeLabel = ''
    if (showTime && timestamp) {
      timeLabel = new Date(timestamp).toLocaleString('zh-CN')
      lastTime = timestamp
    }

    const bodies = msg.MsgBody || msg.msgBody || []
    for (const body of bodies) {
      const msgType = body.MsgType || body.msgType || ''
      const content = body.MsgContent || body.msgContent || {}

      if (msgType === 'TIMTextElem') {
        result.push({
          type: 'text',
          text: content.Text || content.text || '',
          isOwner, nickname, avatar, showTime, timeLabel, isSystem: false
        })
      } else if (msgType === 'TIMImageElem') {
        const imgList = content.ImageInfoArray || content.imageInfoArray || []
        const imgUrl = imgList[1]?.URL || imgList[1]?.url || imgList[0]?.URL || imgList[0]?.url || ''
        result.push({
          type: 'image',
          text: imgUrl,
          isOwner, nickname, avatar, showTime, timeLabel, isSystem: false
        })
      } else if (msgType === 'TIMCustomElem') {
        const desc = content.Desc || content.desc || ''
        const dataStr = content.Data || content.data || ''
        let displayText = desc || '[自定义消息]'
        try {
          const parsed = JSON.parse(dataStr)
          if (parsed.bizType === 'order-status') {
            result.push({
              type: 'system', text: parsed.description || '[订单状态变更]',
              isOwner: false, nickname: '', avatar: '', showTime, timeLabel, isSystem: true
            })
            continue
          }
          if (parsed.bizType === 'price-change') {
            displayText = `${parsed.changeTypeLabel || '改价'}申请: ¥${parsed.originalPrice} → ¥${parsed.newPrice}`
          }
        } catch {}
        result.push({
          type: 'text', text: displayText,
          isOwner, nickname, avatar, showTime, timeLabel, isSystem: false
        })
      } else {
        result.push({
          type: 'text', text: '[暂不支持的消息类型]',
          isOwner, nickname, avatar, showTime, timeLabel, isSystem: false
        })
      }
    }
  }

  return result
}

function previewImage(url) {
  previewUrl.value = url
  previewVisible.value = true
}

onMounted(fetchList)
</script>

<style scoped>
.chat-container {
  max-height: 60vh;
  overflow-y: auto;
  padding: 12px 0;
}

.chat-empty {
  text-align: center;
  color: #999;
  padding: 40px 0;
}

.chat-time-divider {
  text-align: center;
  margin: 12px 0 8px;
}

.chat-time-divider span {
  font-size: 12px;
  color: #999;
  background: #f0f0f0;
  padding: 2px 10px;
  border-radius: 10px;
}

.chat-system-msg {
  text-align: center;
  margin: 8px 0;
}

.chat-system-msg span {
  font-size: 12px;
  color: #999;
  background: #f5f5f5;
  padding: 4px 12px;
  border-radius: 4px;
}

.chat-msg-wrap {
  margin-bottom: 4px;
}

.chat-bubble-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin: 4px 12px;
}

.chat-left {
  flex-direction: row;
}

.chat-right {
  flex-direction: row-reverse;
}

.chat-avatar-item {
  flex-shrink: 0;
}

.chat-bubble-wrap {
  max-width: 70%;
}

.chat-nickname {
  font-size: 12px;
  color: #999;
  margin-bottom: 2px;
}

.chat-right .chat-nickname {
  text-align: right;
}

.chat-bubble {
  display: inline-block;
  padding: 8px 12px;
  border-radius: 8px;
  font-size: 14px;
  line-height: 1.5;
  word-break: break-all;
}

.bubble-left {
  background: #f0f0f0;
  color: #333;
  border-top-left-radius: 2px;
}

.bubble-right {
  background: #409eff;
  color: #fff;
  border-top-right-radius: 2px;
}

.chat-right .chat-bubble-wrap {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

.chat-img {
  max-width: 200px;
  max-height: 200px;
  border-radius: 6px;
  cursor: pointer;
}
</style>
