<template>
  <Teleport to="body">
    <transition name="popover-fade">
      <div
        v-if="visible"
        class="popover-overlay"
        @click.self="handleClose"
        @mousedown.self="handleClose"
      >
        <div
          class="popover-card"
          :style="popoverStyle"
          @click.stop
        >
          <!-- 头部 -->
          <div class="popover-header">
            <span class="popover-title">AI 文案生成</span>
            <button class="close-btn" @click="handleClose">
              <CloseOutlined />
            </button>
          </div>

          <!-- 内容区 -->
          <div class="popover-body">
            <!-- 智能体选择 -->
            <div class="form-item">
              <label class="form-label">选择智能体</label>
              <a-select
                v-model:value="selectedAgentId"
                :loading="loadingAgents"
                placeholder="请选择智能体"
                class="agent-select"
                :bordered="false"
                size="small"
              >
                <a-select-option
                  v-for="agent in agentList"
                  :key="agent.id"
                  :value="agent.id"
                >
                  <div class="agent-option">
                    <img v-if="agent.icon" :src="agent.icon" class="agent-icon" />
                    <span class="agent-name">{{ agent.agentName }}</span>
                  </div>
                </a-select-option>
              </a-select>
            </div>

            <!-- 主题输入 -->
            <div class="form-item">
              <label class="form-label">文案主题</label>
              <input
                v-model="theme"
                type="text"
                class="theme-input"
                placeholder="如：产品介绍、活动推广..."
                :disabled="isGenerating"
                @keydown.enter="handleGenerate"
              />
            </div>

            <!-- 生成结果预览 -->
            <div v-if="generatedText" class="result-preview">
              <div class="result-content">
                {{ generatedText }}
                <span v-if="isGenerating" class="cursor-blink">|</span>
              </div>
            </div>
          </div>

          <!-- 底部按钮 -->
          <div class="popover-footer">
            <button class="btn btn-cancel" @click="handleClose">取消</button>
            <button
              class="btn btn-primary"
              :disabled="!canGenerate || isGenerating"
              @click="handleGenerate"
            >
              <LoadingOutlined v-if="isGenerating" class="spin" />
              <span>{{ isGenerating ? '生成中...' : '生成' }}</span>
            </button>
          </div>
        </div>
      </div>
    </transition>
  </Teleport>
</template>

<script setup lang="ts">
import { ref, computed, watch, onUnmounted } from 'vue'
import { CloseOutlined, LoadingOutlined } from '@ant-design/icons-vue'
import { message } from 'ant-design-vue'
import { getAgentList, sendChatStream } from '@/api/agent'

// Props
const props = defineProps<{
  visible: boolean
  theme?: string
}>()

// Emits
const emit = defineEmits<{
  'update:visible': [value: boolean]
  'success': [text: string]
  'error': [msg: string]
}>()

// 状态
const agentList = ref<any[]>([])
const loadingAgents = ref(false)
const selectedAgentId = ref<number | null>(null)
const theme = ref('')
const generatedText = ref('')
const isGenerating = ref(false)
const abortController = ref<AbortController | null>(null)
const popoverStyle = ref<Record<string, string>>({})

// 计算属性
const canGenerate = computed(() => {
  return selectedAgentId.value && theme.value.trim().length > 0
})

// 获取智能体列表
const fetchAgents = async () => {
  loadingAgents.value = true
  try {
    const res = await getAgentList()
    if (res.code === 0 && res.data) {
      agentList.value = res.data
      // 默认选中第一个
      if (res.data.length > 0 && !selectedAgentId.value) {
        selectedAgentId.value = res.data[0].id
      }
    }
  } catch (error) {
    console.error('获取智能体列表失败:', error)
  } finally {
    loadingAgents.value = false
  }
}

// 更新气泡位置
const updatePosition = () => {
  // 找到触发按钮
  const triggerBtn = document.querySelector('.generate-text-btn')
  if (triggerBtn) {
    const rect = triggerBtn.getBoundingClientRect()
    const popoverWidth = 320
    const popoverHeight = 280

    // 计算位置，确保不超出视口
    let left = rect.right - popoverWidth
    let top = rect.bottom + 8

    // 边界检测
    if (left < 16) left = 16
    if (left + popoverWidth > window.innerWidth - 16) {
      left = window.innerWidth - popoverWidth - 16
    }
    if (top + popoverHeight > window.innerHeight - 16) {
      top = rect.top - popoverHeight - 8
    }

    popoverStyle.value = {
      position: 'fixed',
      left: `${left}px`,
      top: `${top}px`,
      width: `${popoverWidth}px`,
    }
  }
}

// 生成文案
const handleGenerate = async () => {
  if (!canGenerate.value || isGenerating.value) return

  const selectedAgent = agentList.value.find(a => a.id === selectedAgentId.value)
  if (!selectedAgent) {
    message.warning('请选择智能体')
    return
  }

  isGenerating.value = true
  generatedText.value = ''
  abortController.value = new AbortController()

  const prompt = `请根据以下主题生成一段播报文案，要求：
1. 语言流畅自然，适合口播
2. 内容简洁有吸引力
3. 不要使用markdown格式，直接输出纯文本

主题：${theme.value}`

  try {
    await sendChatStream({
      agentId: selectedAgent.id,
      content: prompt,
      ctrl: abortController.value,
      onMessage: (result: { event: string; content?: string; errorMessage?: string }) => {
        if (result.event === 'message' && result.content) {
          generatedText.value += result.content
        } else if (result.event === 'error') {
          message.error(result.errorMessage || '生成出错')
          isGenerating.value = false
        }
      },
      onError: () => {
        message.error('生成失败，请重试')
        isGenerating.value = false
      },
      onClose: () => {
        isGenerating.value = false
        // 生成完成，触发成功回调
        if (generatedText.value) {
          emit('success', generatedText.value.trim())
        }
      }
    })
  } catch (error: any) {
    if (error.name !== 'AbortError') {
      message.error('生成失败')
    }
    isGenerating.value = false
  }
}

// 关闭弹窗
const handleClose = () => {
  if (isGenerating.value) {
    abortController.value?.abort()
    isGenerating.value = false
  }
  generatedText.value = ''
  theme.value = ''
  emit('update:visible', false)
}

// 监听 visible 变化
watch(() => props.visible, (val) => {
  if (val) {
    fetchAgents()
    updatePosition()
    // 监听窗口大小变化
    window.addEventListener('resize', updatePosition)
  } else {
    window.removeEventListener('resize', updatePosition)
  }
})

// 清理
onUnmounted(() => {
  window.removeEventListener('resize', updatePosition)
  if (abortController.value) {
    abortController.value.abort()
  }
})
</script>

<style scoped lang="less">
// Notion 风格配色
@bg-popover: #ffffff;
@bg-hover: #f7f6f3;
@text-primary: #37352f;
@text-secondary: #787774;
@text-tertiary: #b4b4b4;
@border-color: #e9e9e7;
@primary-color: #2e75cc;
@primary-hover: #1f63cb;

// 过渡动画
.popover-fade-enter-active,
.popover-fade-leave-active {
  transition: all 0.2s ease;
}

.popover-fade-enter-from,
.popover-fade-leave-to {
  opacity: 0;
  transform: translateY(-4px);
}

// 遮罩层（透明，仅用于点击外部关闭）
.popover-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
}

// 气泡卡片
.popover-card {
  background: @bg-popover;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08), 0 0 1px rgba(0, 0, 0, 0.1);
  border: 1px solid @border-color;
  overflow: hidden;
  z-index: 1001;
}

// 头部
.popover-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 14px;
  border-bottom: 1px solid @border-color;
}

.popover-title {
  font-size: 13px;
  font-weight: 600;
  color: @text-primary;
}

.close-btn {
  width: 22px;
  height: 22px;
  padding: 0;
  border: none;
  background: transparent;
  border-radius: 4px;
  color: @text-tertiary;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  transition: all 0.15s ease;

  &:hover {
    background: @bg-hover;
    color: @text-secondary;
  }
}

// 内容区
.popover-body {
  padding: 14px;
}

.form-item {
  margin-bottom: 14px;

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

.form-label {
  display: block;
  font-size: 12px;
  font-weight: 500;
  color: @text-secondary;
  margin-bottom: 6px;
}

.agent-select {
  width: 100%;

  :deep(.ant-select-selector) {
    background: @bg-hover !important;
    border-radius: 6px !important;
    padding: 4px 10px !important;
    min-height: 32px !important;
    display: flex !important;
    align-items: center !important;
  }

  :deep(.ant-select-selection-item) {
    font-size: 13px;
    color: @text-primary;
    line-height: 24px !important;
    display: flex !important;
    align-items: center !important;
  }
}

.agent-option {
  display: flex;
  align-items: center;
  gap: 8px;
}

.agent-icon {
  width: 18px;
  height: 18px;
  border-radius: 4px;
  object-fit: cover;
}

.agent-name {
  font-size: 13px;
  color: @text-primary;
}

.theme-input {
  width: 100%;
  height: 32px;
  padding: 0 10px;
  border: 1px solid @border-color;
  border-radius: 6px;
  font-size: 13px;
  color: @text-primary;
  background: @bg-hover;
  outline: none;
  transition: all 0.15s ease;

  &::placeholder {
    color: @text-tertiary;
  }

  &:focus {
    border-color: @primary-color;
    box-shadow: 0 0 0 2px rgba(46, 117, 204, 0.1);
  }

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

// 生成结果预览
.result-preview {
  margin-top: 12px;
  padding: 10px;
  background: @bg-hover;
  border-radius: 6px;
  max-height: 120px;
  overflow-y: auto;

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

  &::-webkit-scrollbar-thumb {
    background: @text-tertiary;
    border-radius: 2px;
  }
}

.result-content {
  font-size: 13px;
  line-height: 1.5;
  color: @text-primary;
  white-space: pre-wrap;
  word-break: break-word;
}

.cursor-blink {
  color: @primary-color;
  animation: blink 1s infinite;
}

@keyframes blink {
  0%, 50% { opacity: 1; }
  51%, 100% { opacity: 0; }
}

// 底部按钮
.popover-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 12px 14px;
  border-top: 1px solid @border-color;
}

.btn {
  height: 30px;
  padding: 0 14px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.15s ease;
  display: inline-flex;
  align-items: center;
  gap: 4px;

  &.btn-cancel {
    background: transparent;
    border: none;
    color: @text-secondary;

    &:hover {
      background: @bg-hover;
      color: @text-primary;
    }
  }

  &.btn-primary {
    background: @primary-color;
    border: none;
    color: #fff;

    &:hover:not(:disabled) {
      background: @primary-hover;
    }

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

.spin {
  font-size: 12px;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}
</style>
