<template>
  <teleport to="body">
    <transition name="history-modal">
      <div v-if="visible" class="history-overlay" @click.self="handleClose">
        <!-- Modal Container -->
        <div class="history-modal">
          <!-- Decorative Elements -->
          <div class="modal-glow"></div>

          <!-- Header -->
          <header class="modal-header">
            <div class="header-content">
              <div v-if="selectedConversation" class="header-nav">
                <button class="nav-back" @click="backToList">
                  <Icon icon="lucide:arrow-left" class="size-4" />
                  <span>返回列表</span>
                </button>
              </div>
              <div class="header-title-group">
                <h2 class="modal-title">
                  <Icon icon="lucide:history" class="title-icon" />
                  {{ selectedConversation ? '对话详情' : '历史记录' }}
                </h2>
                <p v-if="!selectedConversation" class="modal-subtitle">
                  查看你与 AI 的所有对话
                </p>
              </div>
            </div>
            <button class="close-btn" @click="handleClose">
              <Icon icon="lucide:x" class="size-4" />
            </button>
          </header>

          <!-- Content -->
          <div class="modal-body">
            <!-- Conversation List View -->
            <div v-if="!selectedConversation" class="list-view">
              <!-- Loading State -->
              <div v-if="loading" class="loading-state">
                <Icon icon="lucide:loader-2" class="size-8 animate-spin text-primary" />
              </div>

              <!-- Empty State -->
              <div v-else-if="groupedConversations.length === 0" class="empty-state">
                <div class="empty-illustration">
                  <div class="illustration-ring"></div>
                  <div class="illustration-ring delay-1"></div>
                  <Icon icon="lucide:history" class="illustration-icon" />
                </div>
                <h3 class="empty-title">暂无历史记录</h3>
                <p class="empty-desc">开始对话后，记录将保存在这里</p>
              </div>

              <!-- Grouped Conversations -->
              <div v-else class="conversation-groups">
                <div
                  v-for="(group, groupIndex) in groupedConversations"
                  :key="group.label"
                  class="conversation-group"
                  :style="{ '--group-index': groupIndex }"
                >
                  <div class="group-header">
                    <span class="group-dot"></span>
                    <span class="group-label">{{ group.label }}</span>
                    <span class="group-count">{{ group.items.length }}</span>
                  </div>
                  <div class="group-items">
                    <button
                      v-for="(item, itemIndex) in group.items"
                      :key="item.id"
                      class="conversation-item"
                      :style="{ '--item-index': itemIndex }"
                      @click="selectConversation(item)"
                    >
                      <div class="item-indicator"></div>
                      <div class="item-content">
                        <h4 class="item-title">{{ item.name || '未命名会话' }}</h4>
                        <p class="item-preview">{{ item.preview || '暂无预览内容' }}</p>
                      </div>
                      <div class="item-meta">
                        <span class="meta-time">
                          <Icon icon="lucide:clock" class="size-3" />
                          {{ formatTime(item.updatedAt || item.createdAt) }}
                        </span>
                        <div class="meta-arrow">
                          <Icon icon="lucide:chevron-right" class="size-4" />
                        </div>
                      </div>
                    </button>
                  </div>
                </div>

                <!-- Load More -->
                <div v-if="hasMore" class="load-more">
                  <button
                    class="load-more-btn"
                    :disabled="loading"
                    @click="loadConversations(true)"
                  >
                    <Icon v-if="loading" icon="lucide:loader-2" class="size-4 animate-spin" />
                    <span>{{ loading ? '加载中...' : '加载更多' }}</span>
                  </button>
                </div>
              </div>
            </div>

            <!-- Message Detail View -->
            <div v-else class="detail-view">
              <!-- Loading State -->
              <div v-if="messageLoading" class="loading-state">
                <Icon icon="lucide:loader-2" class="size-8 animate-spin text-primary" />
              </div>

              <div v-else-if="messageList.length === 0" class="empty-state">
                <Icon icon="lucide:message-circle" class="empty-icon-single" />
                <p>暂无消息记录</p>
              </div>

              <div v-else class="message-timeline">
                <div
                  v-for="(msg, index) in messageList"
                  :key="msg.id"
                  class="timeline-item"
                  :style="{ '--msg-index': index }"
                >
                  <!-- User Message -->
                  <div class="message-block message-block--user">
                    <div class="message-avatar">
                      <Icon icon="lucide:user" class="size-4" />
                    </div>
                    <div class="message-body">
                      <div class="message-header">
                        <span class="message-author">你</span>
                        <span class="message-time">{{ formatTime(msg.createdAt) }}</span>
                      </div>
                      <div class="message-content">{{ msg.query }}</div>
                    </div>
                  </div>

                  <!-- AI Response -->
                  <div class="message-block message-block--ai">
                    <div class="message-avatar">
                      <Icon icon="lucide:bot" class="size-4" />
                    </div>
                    <div class="message-body">
                      <div class="message-header">
                        <span class="message-author">AI 助手</span>
                        <button class="copy-btn" @click="copyContent(msg.answer)" title="复制">
                          <Icon icon="lucide:copy" class="size-3" />
                        </button>
                      </div>
                      <div class="message-content">{{ msg.answer }}</div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </transition>
  </teleport>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { toast } from 'vue-sonner'
import { Icon } from '@iconify/vue'
import dayjs from 'dayjs'
import { getConversations, getMessages } from '@/api/agent'
import { copyToClipboard } from '@/utils/clipboard'

const props = defineProps({
  visible: { type: Boolean, default: false },
  agentId: { type: [String, Number], default: null }
})

const emit = defineEmits(['close'])

// State
const loading = ref(false)
const conversationList = ref([])
const selectedConversation = ref(null)
const messageList = ref([])
const messageLoading = ref(false)
const lastId = ref(null)
const hasMore = ref(true)

// 按日期分组（先排序再分组）
const groupedConversations = computed(() => {
  const today = dayjs().startOf('day')
  const yesterday = dayjs().subtract(1, 'day').startOf('day')
  const week = dayjs().subtract(7, 'day').startOf('day')

  const groups = {
    today: { label: '今天', items: [] },
    yesterday: { label: '昨天', items: [] },
    week: { label: '近7天', items: [] },
    older: { label: '更早', items: [] }
  }

  // 按时间降序排序
  const sortedList = [...conversationList.value].sort((a, b) => {
    const timeA = (a.updatedAt || a.createdAt) * 1000
    const timeB = (b.updatedAt || b.createdAt) * 1000
    return timeB - timeA
  })

  sortedList.forEach(item => {
    const date = dayjs((item.updatedAt || item.createdAt) * 1000)
    if (date.isAfter(today)) {
      groups.today.items.push(item)
    } else if (date.isAfter(yesterday)) {
      groups.yesterday.items.push(item)
    } else if (date.isAfter(week)) {
      groups.week.items.push(item)
    } else {
      groups.older.items.push(item)
    }
  })

  return Object.values(groups).filter(g => g.items.length > 0)
})

// Methods
const loadConversations = async (loadMore = false) => {
  if (!props.agentId) return
  if (loadMore && !hasMore.value) return

  loading.value = true
  try {
    const params = { agentId: props.agentId, limit: 20 }
    if (loadMore && lastId.value) {
      params.lastId = lastId.value
    }
    const res = await getConversations(params)
    if (res.code === 0) {
      const data = res.data?.data || []
      if (loadMore) {
        conversationList.value = [...conversationList.value, ...data]
      } else {
        conversationList.value = data
      }
      // 更新分页状态
      lastId.value = data.length > 0 ? data[data.length - 1].id : null
      hasMore.value = data.length === 20 && res.data?.hasMore !== false
    }
  } catch (e) {
    console.error('加载会话列表失败:', e)
  } finally {
    loading.value = false
  }
}

const selectConversation = async (conversation) => {
  selectedConversation.value = conversation
  messageLoading.value = true
  messageList.value = []
  try {
    const res = await getMessages({
      agentId: props.agentId,
      conversationId: conversation.id,
      limit: 50
    })
    if (res.code === 0) {
      messageList.value = (res.data?.data || []).reverse()
    }
  } catch (e) {
    console.error('加载消息详情失败:', e)
  } finally {
    messageLoading.value = false
  }
}

const backToList = () => {
  selectedConversation.value = null
  messageList.value = []
}

const handleClose = () => {
  emit('close')
  backToList()
}

const copyContent = async (content) => {
  const success = await copyToClipboard(content)
  if (success) {
    toast.success('已复制到剪贴板')
  } else {
    toast.error('复制失败')
  }
}

const formatTime = (timestamp) => {
  if (!timestamp) return ''
  const date = dayjs(timestamp * 1000)
  const now = dayjs()

  if (date.isSame(now, 'day')) return date.format('HH:mm')
  if (date.isSame(now.subtract(1, 'day'), 'day')) return '昨天 ' + date.format('HH:mm')
  if (date.isAfter(now.subtract(7, 'day'))) return date.format('dddd HH:mm')
  return date.format('MM-DD HH:mm')
}

// Watch
watch(() => props.visible, (val) => {
  if (val) {
    backToList()
    loadConversations()
  }
})
</script>

<style scoped lang="less">
// ========================================
// Overlay & Modal Container
// ========================================
.history-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.4);
  backdrop-filter: blur(8px);
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
}

.history-modal {
  position: relative;
  width: 100%;
  max-width: 720px;
  max-height: calc(100vh - 80px);
  background: var(--color-bg-page);
  border-radius: 20px;
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.1),
    0 20px 50px -12px rgba(0, 0, 0, 0.25),
    0 8px 20px -8px rgba(0, 0, 0, 0.15);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.modal-glow {
  position: absolute;
  top: -50%;
  left: -50%;
  width: 200%;
  height: 200%;
  background: radial-gradient(
    circle at 30% 20%,
    rgba(59, 130, 246, 0.08) 0%,
    transparent 40%
  );
  pointer-events: none;
}

// ========================================
// Header
// ========================================
.modal-header {
  position: relative;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 24px 28px 20px;
  border-bottom: 1px solid var(--color-gray-200);
  background: linear-gradient(to bottom, rgba(255,255,255,0.8), rgba(255,255,255,0));
}

.header-content {
  flex: 1;
}

.header-nav {
  margin-bottom: 12px;
}

.nav-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: none;
  background: var(--color-gray-100);
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--color-gray-600);
  cursor: pointer;
  transition: all 0.2s ease;

  &:hover {
    background: var(--color-gray-200);
    color: var(--color-gray-900);
  }
}

.header-title-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.modal-title {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 20px;
  font-weight: 700;
  color: var(--color-gray-900);
  margin: 0;
  letter-spacing: -0.02em;
}

.title-icon {
  font-size: 18px;
  color: var(--color-primary-500);
}

.modal-subtitle {
  font-size: 14px;
  color: var(--color-gray-500);
  margin: 0;
  padding-left: 28px;
}

.close-btn {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border: none;
  background: var(--color-gray-100);
  border-radius: 10px;
  color: var(--color-gray-500);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;

  &:hover {
    background: var(--color-error-100);
    color: var(--color-error-500);
    transform: scale(1.05);
  }
}

// ========================================
// Modal Body
// ========================================
.modal-body {
  flex: 1;
  overflow-y: auto;
  padding: 20px 28px 28px;

  &::-webkit-scrollbar {
    width: 6px;
  }

  &::-webkit-scrollbar-track {
    background: transparent;
  }

  &::-webkit-scrollbar-thumb {
    background: var(--color-gray-300);
    border-radius: 3px;

    &:hover {
      background: var(--color-gray-400);
    }
  }
}

// ========================================
// Loading State
// ========================================
.loading-state {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
}

// ========================================
// Empty State
// ========================================
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 60px 20px;
  text-align: center;
}

.empty-illustration {
  position: relative;
  width: 80px;
  height: 80px;
  margin-bottom: 24px;
}

.illustration-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid var(--color-gray-200);
  animation: ringPulse 3s ease-in-out infinite;

  &.delay-1 {
    inset: 8px;
    animation-delay: 0.5s;
  }
}

@keyframes ringPulse {
  0%, 100% {
    transform: scale(1);
    opacity: 0.5;
  }
  50% {
    transform: scale(1.05);
    opacity: 1;
  }
}

.illustration-icon {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 28px;
  color: var(--color-gray-400);
}

.empty-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--color-gray-900);
  margin: 0 0 6px;
}

.empty-desc {
  font-size: 14px;
  color: var(--color-gray-500);
  margin: 0;
}

.empty-icon-single {
  font-size: 40px;
  color: var(--color-gray-300);
  margin-bottom: 16px;
}

// ========================================
// Conversation Groups
// ========================================
.conversation-groups {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.load-more {
  display: flex;
  justify-content: center;
  padding-top: 8px;
}

.load-more-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 20px;
  border: 1px solid var(--color-gray-200);
  background: var(--color-bg-card);
  border-radius: 10px;
  font-size: 14px;
  color: var(--color-gray-600);
  cursor: pointer;
  transition: all 0.2s ease;

  &:hover:not(:disabled) {
    border-color: var(--color-primary-300);
    color: var(--color-primary-500);
  }

  &:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
}

.conversation-group {
  animation: groupFadeIn 0.4s ease-out backwards;
  animation-delay: calc(var(--group-index) * 0.1s);
}

@keyframes groupFadeIn {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.group-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
  padding: 0 4px;
}

.group-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-primary-500);
}

.group-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-gray-700);
  letter-spacing: 0.02em;
}

.group-count {
  font-size: 11px;
  font-weight: 600;
  color: var(--color-gray-500);
  background: var(--color-gray-100);
  padding: 2px 8px;
  border-radius: 10px;
}

.group-items {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

// ========================================
// Conversation Item
// ========================================
.conversation-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 16px 18px;
  background: var(--color-bg-card);
  border: 1px solid var(--color-gray-200);
  border-radius: 14px;
  cursor: pointer;
  text-align: left;
  transition: all 0.25s ease;
  animation: itemFadeIn 0.3s ease-out backwards;
  animation-delay: calc(var(--group-index) * 0.1s + var(--item-index) * 0.05s);

  &:hover {
    border-color: var(--color-primary-300);
    background: rgba(59, 130, 246, 0.02);
    box-shadow:
      0 4px 12px rgba(59, 130, 246, 0.08),
      0 0 0 1px rgba(59, 130, 246, 0.1);
    transform: translateY(-2px);

    .item-indicator {
      background: var(--color-primary-500);
      transform: scaleY(1);
    }

    .meta-arrow {
      color: var(--color-primary-500);
      transform: translateX(3px);
    }
  }
}

@keyframes itemFadeIn {
  from {
    opacity: 0;
    transform: translateX(-8px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

.item-indicator {
  width: 4px;
  height: 32px;
  border-radius: 2px;
  background: var(--color-gray-200);
  flex-shrink: 0;
  transition: all 0.25s ease;
  transform: scaleY(0.6);
}

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

.item-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--color-gray-900);
  margin: 0 0 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.item-preview {
  font-size: 13px;
  color: var(--color-gray-500);
  margin: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.4;
}

.item-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

.meta-time {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  color: var(--color-gray-400);
  white-space: nowrap;
}

.meta-arrow {
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-gray-300);
  font-size: 10px;
  transition: all 0.25s ease;
}

// ========================================
// Message Detail View
// ========================================
.detail-view {
  min-height: 200px;
}

.message-timeline {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.timeline-item {
  animation: msgFadeIn 0.35s ease-out backwards;
  animation-delay: calc(var(--msg-index) * 0.08s);
}

@keyframes msgFadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.message-block {
  display: flex;
  gap: 12px;
  margin-bottom: 12px;

  &:last-child {
    margin-bottom: 0;
  }
}

.message-avatar {
  width: 32px;
  height: 32px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 14px;

  .message-block--user & {
    background: linear-gradient(135deg, var(--color-gray-100), var(--color-gray-200));
    color: var(--color-gray-600);
  }

  .message-block--ai & {
    background: linear-gradient(135deg, var(--color-primary-500), #8b5cf6);
    color: white;
  }
}

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

.message-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
}

.message-author {
  font-size: 12px;
  font-weight: 600;
  color: var(--color-gray-700);
}

.message-time {
  font-size: 11px;
  color: var(--color-gray-400);
}

.copy-btn {
  margin-left: auto;
  width: 24px;
  height: 24px;
  border: none;
  background: transparent;
  color: var(--color-gray-400);
  border-radius: 6px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  transition: all 0.2s ease;

  &:hover {
    background: var(--color-primary-100);
    color: var(--color-primary-500);
  }
}

.message-content {
  padding: 14px 16px;
  border-radius: 12px;
  font-size: 14px;
  line-height: 1.7;
  color: var(--color-gray-800);
  white-space: pre-wrap;
  word-break: break-word;

  .message-block--user & {
    background: var(--color-gray-100);
    border: 1px solid var(--color-gray-200);
  }

  .message-block--ai & {
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.06), rgba(139, 92, 246, 0.04));
    border: 1px solid rgba(59, 130, 246, 0.15);
  }
}

// ========================================
// Transitions
// ========================================
.history-modal-enter-active {
  animation: modalIn 0.35s cubic-bezier(0.32, 0.72, 0, 1);
}

.history-modal-leave-active {
  animation: modalOut 0.25s cubic-bezier(0.32, 0.72, 0, 1);
}

@keyframes modalIn {
  from {
    opacity: 0;

    .history-modal {
      transform: scale(0.95) translateY(10px);
    }
  }
  to {
    opacity: 1;

    .history-modal {
      transform: scale(1) translateY(0);
    }
  }
}

@keyframes modalOut {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

.history-modal-enter-active .history-modal {
  animation: modalScaleIn 0.35s cubic-bezier(0.32, 0.72, 0, 1);
}

.history-modal-leave-active .history-modal {
  animation: modalScaleOut 0.25s cubic-bezier(0.32, 0.72, 0, 1);
}

@keyframes modalScaleIn {
  from {
    opacity: 0;
    transform: scale(0.95) translateY(10px);
  }
  to {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

@keyframes modalScaleOut {
  from {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
  to {
    opacity: 0;
    transform: scale(0.98) translateY(5px);
  }
}

// ========================================
// Responsive
// ========================================
@media (max-width: 768px) {
  .history-overlay {
    padding: 0;
    align-items: stretch;
  }

  .history-modal {
    max-width: 100%;
    max-height: 100vh;
    height: 100vh;
    border-radius: 0;
  }

  .modal-header {
    padding: 16px 20px;
  }

  .modal-body {
    padding: 16px 20px 24px;
  }

  .conversation-item {
    padding: 14px 16px;
  }

  .item-indicator {
    display: none;
  }
}
</style>
