<template>
  <div class="chat-panel-section">
    <div class="chat-panel-header">
      <h3>用户消息</h3>
      <button class="refresh-btn" @click="load" :disabled="loading">刷新</button>
    </div>

    <div v-if="loading" class="chat-empty">加载中…</div>
    <div v-else-if="Object.keys(conversations).length === 0" class="chat-empty">暂无用户消息</div>

    <div v-else class="chat-layout">
      <!-- Left: conversation list -->
      <div class="conv-list">
        <div class="conv-list-title">对话列表</div>
        <div
          v-for="(msgs, account) in conversations"
          :key="account"
          :class="['conv-item', selectedAccount === account ? 'conv-item--active' : '']"
          @click="selectConv(account, msgs)"
        >
          <div class="conv-avatar">{{ (getDisplayName(msgs) || account).slice(0, 1).toUpperCase() }}</div>
          <div class="conv-info">
            <div class="conv-name">{{ getDisplayName(msgs) || account }}</div>
            <div class="conv-preview">{{ latestMsg(msgs) }}</div>
          </div>
        </div>
      </div>

      <!-- Right: message thread -->
      <div class="conv-thread" v-if="selectedAccount">
        <div class="thread-top">
          <div class="thread-user">
            <div class="thread-avatar">{{ (displayName || selectedAccount).slice(0, 1).toUpperCase() }}</div>
            <div class="thread-user-info">
              <span class="thread-name">{{ displayName || selectedAccount }}</span>
              <span class="thread-account">{{ selectedAccount }}</span>
            </div>
          </div>
          <button class="clear-btn" @click="clearConv" :disabled="clearing">清除记录</button>
        </div>

        <div class="thread-messages" ref="threadEl">
          <div
            v-for="msg in currentMessages"
            :key="msg.id"
            :class="['msg-row', msg.fromAdmin ? 'msg-row--admin' : 'msg-row--user']"
          >
            <div class="msg-bubble">
              <div class="msg-meta">
                <span class="msg-from">{{ msg.fromAdmin ? '客服' : (msg.accountName || msg.accountId) }}</span>
                <span class="msg-time">{{ formatTime(msg.sentAt) }}</span>
              </div>
              <div class="msg-content">{{ msg.content }}</div>
            </div>
          </div>
        </div>

        <form class="reply-row" @submit.prevent="sendReply">
          <input
            v-model="replyText"
            class="reply-input"
            placeholder="输入回复内容…"
            maxlength="500"
            :disabled="replying"
          />
          <button class="reply-send-btn" type="submit" :disabled="replying || !replyText.trim()">发送</button>
        </form>
        <p v-if="replyError" class="reply-error">{{ replyError }}</p>
      </div>

      <div class="conv-thread conv-thread--empty" v-else>
        <div class="empty-hint">
          <svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="opacity:0.3"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
          <p>选择左侧对话</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, nextTick, onMounted, onUnmounted } from 'vue'
import {
  fetchAdminAllConversations,
  fetchAdminConversation,
  adminSendChatReply,
  adminClearConversation
} from '../../shared/api.js'

const props = defineProps({
  adminToken: { type: String, default: '' }
})

const conversations = ref({})
const loading = ref(false)
const selectedAccount = ref('')
const currentMessages = ref([])
const displayName = ref('')
const replyText = ref('')
const replying = ref(false)
const replyError = ref('')
const clearing = ref(false)
const threadEl = ref(null)

let pollTimer = null

const formatTime = (iso) => {
  if (!iso) return ''
  const d = new Date(iso)
  return d.toLocaleString('zh-CN', { hour12: false })
}

const getDisplayName = (msgs) => {
  if (!msgs || msgs.length === 0) return '未知用户'
  const userMsg = msgs.find((m) => !m.fromAdmin)
  return userMsg?.accountName || userMsg?.accountId || '未知用户'
}

const latestMsg = (msgs) => {
  if (!msgs || msgs.length === 0) return ''
  const last = msgs[msgs.length - 1]
  const prefix = last.fromAdmin ? '[客服] ' : ''
  return prefix + (last.content.length > 20 ? last.content.slice(0, 20) + '…' : last.content)
}

const scrollThreadBottom = async () => {
  await nextTick()
  if (threadEl.value) {
    threadEl.value.scrollTop = threadEl.value.scrollHeight
  }
}

const load = async () => {
  if (!props.adminToken) return
  loading.value = true
  try {
    conversations.value = await fetchAdminAllConversations(props.adminToken)
    // 若当前已选中某个会话，则刷新其消息列表
    if (selectedAccount.value) {
      currentMessages.value = conversations.value[selectedAccount.value] || []
      await scrollThreadBottom()
    }
  } finally {
    loading.value = false
  }
}

const selectConv = async (account, msgs) => {
  selectedAccount.value = account
  currentMessages.value = msgs || []
  displayName.value = getDisplayName(msgs)
  replyError.value = ''
  replyText.value = ''
  await scrollThreadBottom()
}

const sendReply = async () => {
  const content = replyText.value.trim()
  if (!content || replying.value) return
  replying.value = true
  replyError.value = ''
  try {
    const msg = await adminSendChatReply(props.adminToken, selectedAccount.value, content)
    if (msg) {
      currentMessages.value.push(msg)
      conversations.value[selectedAccount.value] = [...currentMessages.value]
      replyText.value = ''
      await scrollThreadBottom()
    }
  } catch (err) {
    replyError.value = err?.response?.data?.error || '发送失败'
  } finally {
    replying.value = false
  }
}

const clearConv = async () => {
  if (!selectedAccount.value || clearing.value) return
  if (!confirm(`确认清除与 ${selectedAccount.value} 的全部对话？`)) return
  clearing.value = true
  try {
    await adminClearConversation(props.adminToken, selectedAccount.value)
    delete conversations.value[selectedAccount.value]
    selectedAccount.value = ''
    currentMessages.value = []
  } catch {
    alert('清除失败，请重试')
  } finally {
    clearing.value = false
  }
}

onMounted(() => {
  load()
  pollTimer = setInterval(load, 8000)
})

onUnmounted(() => {
  if (pollTimer) clearInterval(pollTimer)
})
</script>

<style scoped>
.chat-panel-section {
  margin-top: 32px;
}

.chat-panel-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}

.chat-panel-header h3 {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
}

.refresh-btn {
  padding: 5px 14px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: rgba(255,255,255,0.7);
  font-size: 13px;
  cursor: pointer;
  color: var(--text);
  font-family: inherit;
}

.chat-empty {
  padding: 24px 0;
  text-align: center;
  color: var(--muted);
  font-size: 14px;
}

.chat-layout {
  display: grid;
  grid-template-columns: 200px 1fr;
  height: 520px;
  border-radius: 12px;
  border: 1px solid var(--line);
  overflow: hidden;
  background: rgba(255, 255, 255, 0.4);
  box-shadow: 0 8px 24px rgba(33, 33, 40, 0.08);
}

/* Conversation list */
.conv-list {
  border-right: 1px solid var(--line);
  overflow-y: auto;
  background: rgba(255, 255, 255, 0.65);
  display: flex;
  flex-direction: column;
}

.conv-list-title {
  padding: 12px 14px 8px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}

.conv-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  cursor: pointer;
  border-bottom: 1px solid rgba(255,255,255,0.5);
  transition: background 0.15s;
}

.conv-item:hover {
  background: rgba(180, 154, 203, 0.08);
}

.conv-item--active {
  background: rgba(180, 154, 203, 0.14);
  border-left: 3px solid var(--accent);
  padding-left: 9px;
}

.conv-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: #e8e8e8;
  color: #444;
  font-size: 14px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.conv-info {
  flex: 1;
  min-width: 0;
}

.conv-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.conv-preview {
  font-size: 11px;
  color: var(--muted);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Message thread */
.conv-thread {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.3);
}

.conv-thread--empty {
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: 14px;
}

.empty-hint {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  color: var(--muted);
  font-size: 14px;
}

.thread-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 16px;
  border-bottom: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.75);
  flex-shrink: 0;
}

.thread-user {
  display: flex;
  align-items: center;
  gap: 10px;
}

.thread-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #e8e8e8;
  color: #444;
  font-size: 13px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.thread-user-info {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.thread-name {
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.2;
}

.thread-account {
  font-size: 11px;
  color: var(--muted);
}

.clear-btn {
  padding: 5px 12px;
  border-radius: 6px;
  border: 1px solid rgba(210, 70, 70, 0.3);
  background: rgba(210, 70, 70, 0.06);
  color: #c04040;
  font-size: 12px;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.15s;
  white-space: nowrap;
}

.clear-btn:hover:not(:disabled) {
  background: rgba(210, 70, 70, 0.14);
}

.thread-messages {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.msg-row {
  display: flex;
}

.msg-row--user {
  justify-content: flex-start;
}

.msg-row--admin {
  justify-content: flex-end;
}

.msg-bubble {
  display: flex;
  flex-direction: column;
  gap: 3px;
  max-width: 72%;
}

.msg-row--admin .msg-bubble {
  align-items: flex-end;
}

.msg-meta {
  display: flex;
  gap: 6px;
  align-items: baseline;
  padding: 0 2px;
}

.msg-from {
  font-size: 11px;
  font-weight: 600;
  color: var(--muted);
}

.msg-time {
  font-size: 10px;
  color: var(--muted);
  opacity: 0.75;
}

.msg-content {
  padding: 9px 13px;
  border-radius: 12px;
  font-size: 14px;
  line-height: 1.55;
  white-space: pre-wrap;
  word-break: break-word;
}

.msg-row--user .msg-content {
  background: rgba(255, 255, 255, 0.85);
  color: var(--text);
  border: 1px solid var(--line);
  border-bottom-left-radius: 4px;
}

.msg-row--admin .msg-content {
  background: #2c2b2d;
  color: #fff;
  border-bottom-right-radius: 4px;
}

.reply-row {
  display: flex;
  gap: 8px;
  padding: 10px 14px;
  border-top: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.7);
}

.reply-input {
  flex: 1;
  padding: 8px 12px;
  border-radius: 7px;
  border: 1px solid var(--line);
  font-size: 14px;
  font-family: inherit;
  background: rgba(255, 255, 255, 0.9);
  color: var(--text);
  outline: none;
}

.reply-input:focus {
  border-color: var(--accent, #7c6af0);
}

.reply-send-btn {
  padding: 8px 18px;
  border-radius: 7px;
  background: #2c2b2d;
  color: #fff;
  border: none;
  cursor: pointer;
  font-size: 14px;
  font-family: inherit;
  font-weight: 600;
  transition: opacity 0.2s;
}

.reply-send-btn:disabled {
  opacity: 0.45;
  cursor: default;
}

.reply-send-btn:not(:disabled):hover {
  opacity: 0.82;
}

.reply-error {
  font-size: 12px;
  color: #d64848;
  padding: 0 14px 8px;
  text-align: right;
}

@media (max-width: 900px) {
  .chat-panel-section {
    margin-top: 16px;
  }

  .chat-layout {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
    height: 520px;
  }

  .conv-list {
    border-right: none;
    border-bottom: 1px solid var(--line);
    overflow-x: auto;
    overflow-y: hidden;
    flex-direction: row;
    max-height: 72px;
    scrollbar-width: none;
  }

  .conv-list::-webkit-scrollbar {
    display: none;
  }

  .conv-list-title {
    display: none;
  }

  .conv-item {
    flex-shrink: 0;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    min-width: 70px;
    max-width: 80px;
    padding: 8px 6px;
    border-bottom: none;
    border-right: 1px solid var(--line);
    text-align: center;
  }

  .conv-info {
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  .conv-name {
    font-size: 11px;
    max-width: 64px;
  }

  .conv-preview {
    display: none;
  }

  .conv-avatar {
    width: 28px;
    height: 28px;
    font-size: 12px;
  }
}
</style>
