<!--
对话测试页面 - 用于测试AI模型对话功能，带日志输出
-->
<script setup lang="ts">
import type { ChatTestRequest, ChatTestResponse, LogEntry, LogType } from '#/api/chat/test';

import { nextTick, onUnmounted, ref } from 'vue';

import { Page } from '@vben/common-ui';

import {
  Button,
  Card,
  Checkbox,
  Divider,
  Form,
  FormItem,
  message,
  Select,
  Space,
  Textarea,
} from 'ant-design-vue';

import { modelList } from '#/api/chat/model';
import { sendChatMessageStream } from '#/api/chat/test';

interface ModelOption {
  label: string;
  value: string;
}

// 模型列表
const modelOptions = ref<ModelOption[]>([]);
const loading = ref(false);
const abortController = ref<(() => void) | undefined>();

// 日志输出
const logs = ref<LogEntry[]>([]);
const showLogs = ref(true);

// 表单数据
const formData = ref<ChatTestRequest>({
  model: '',
  content: '',
  enableThinking: false,
  enableInternet: false,
});

// 对话历史
interface Message {
  role: 'user' | 'assistant' | 'system';
  content: string;
  loading?: boolean;
}
const messages = ref<Message[]>([
  { role: 'system', content: '欢迎使用对话测试功能，请选择模型并输入问题。' },
]);

// 添加日志
function addLog(type: LogType, msg: string, data?: any) {
  logs.value.push({
    time: new Date().toLocaleTimeString(),
    type,
    message: msg,
    data,
  });
  // 自动滚动到底部
  nextTick(() => {
    const container = document.querySelector('.log-container');
    if (container) {
      container.scrollTop = container.scrollHeight;
    }
  });
}

// 清空日志
function clearLogs() {
  logs.value = [];
}

// 获取模型列表
async function fetchModels() {
  try {
    const res = await modelList({ pageNum: 1, pageSize: 100 });
    if (res.rows && res.rows.length > 0) {
      modelOptions.value = res.rows
        .filter((item: any) => item.modelShow !== 'N')
        .map((item: any) => ({
          label: `${item.modelName} (${item.providerCode || 'unknown'})`,
          value: item.modelName,
        }));
      addLog('success', `加载了 ${modelOptions.value.length} 个模型`);
    }
  } catch (error: any) {
    addLog('error', '获取模型列表失败', error.message);
    message.error('获取模型列表失败');
  }
}

// 发送消息
async function handleSend() {
  if (!formData.value.model) {
    message.warning('请选择模型');
    return;
  }
  if (!formData.value.content?.trim()) {
    message.warning('请输入问题');
    return;
  }

  // 清空之前的日志
  clearLogs();
  addLog('info', `开始对话，模型: ${formData.value.model}`);

  // 保存用户输入内容
  const userContent = formData.value.content;

  // 清空输入框
  formData.value.content = '';

  // 添加用户消息
  messages.value.push({
    role: 'user',
    content: userContent,
  });

  // 添加助手消息（占位）
  const assistantIndex = messages.value.length;
  messages.value.push({
    role: 'assistant',
    content: '',
    loading: true,
  });

  loading.value = true;

  try {
    abortController.value = sendChatMessageStream(
      { ...formData.value, content: userContent },
      (data: ChatTestResponse) => {
        // 更新助手消息
        if (messages.value[assistantIndex]) {
          messages.value[assistantIndex].loading = false;
          messages.value[assistantIndex].content += data.content || '';
        }
        // 滚动到底部
        nextTick(() => {
          const container = document.querySelector('.chat-container');
          if (container) {
            container.scrollTop = container.scrollHeight;
          }
        });
      },
      () => {
        // 对话完成回调
        loading.value = false;
        abortController.value = undefined;
        if (messages.value[assistantIndex]) {
          messages.value[assistantIndex].loading = false;
        }
        addLog('success', '对话已完成');
      },
      (error: Error) => {
        addLog('error', error.message);
        message.error(error.message);
        if (messages.value[assistantIndex]) {
          messages.value[assistantIndex].loading = false;
          messages.value[assistantIndex].content = '❌ 对话失败: ' + error.message;
        }
        loading.value = false;
      },
      (log: LogEntry) => {
        logs.value.push(log);
      },
    );
  } catch (error: any) {
    addLog('error', error.message);
    message.error(error.message);
    if (messages.value[assistantIndex]) {
      messages.value[assistantIndex].loading = false;
      messages.value[assistantIndex].content = '❌ 对话失败: ' + error.message;
    }
    loading.value = false;
  }
}

// 停止生成
function handleStop() {
  if (abortController.value) {
    abortController.value();
    abortController.value = undefined;
    loading.value = false;
    // 更新最后一条消息状态
    const lastMsg = messages.value[messages.value.length - 1];
    if (lastMsg && lastMsg.role === 'assistant' && lastMsg.loading) {
      lastMsg.loading = false;
      lastMsg.content += '\n\n[已停止]';
    }
    addLog('warning', '用户停止生成');
    message.info('已停止生成');
  }
}

// 清空对话
function handleClear() {
  messages.value = [
    { role: 'system', content: '对话已清空，请继续测试。' },
  ];
  clearLogs();
  if (abortController.value) {
    abortController.value();
    abortController.value = undefined;
  }
  loading.value = false;
}

// 按 Enter 发送（Shift+Enter 换行）
function handleKeydown(e: KeyboardEvent) {
  if (e.key === 'Enter' && !e.shiftKey) {
    e.preventDefault();
    handleSend();
  }
}

// 过滤选项
function filterOption(input: string, option: any): boolean {
  return option.label?.toLowerCase().includes(input.toLowerCase());
}

// 日志颜色
function getLogColor(type: LogType): string {
  switch (type) {
    case 'error': return '#ff4d4f';
    case 'warning': return '#faad14';
    case 'success': return '#52c41a';
    default: return '#666';
  }
}

// 页面加载时获取模型列表
fetchModels();

onUnmounted(() => {
  if (abortController.value) {
    abortController.value();
  }
});
</script>

<template>
  <Page :auto-content-height="true">
    <div class="chat-test-container">
      <!-- 左侧：配置面板 -->
      <Card title="对话配置" class="config-card">
        <Form layout="vertical">
          <FormItem label="选择模型" required>
            <Select
              v-model:value="formData.model"
              placeholder="请选择AI模型"
              :options="modelOptions"
              :loading="!modelOptions.length"
              show-search
              :filter-option="filterOption"
              style="width: 100%"
            />
          </FormItem>

          <FormItem label="高级选项">
            <Space direction="vertical" style="width: 100%">
              <Checkbox v-model:checked="formData.enableThinking" disabled>
                启用深度思考（功能完善中，暂不可用）
              </Checkbox>
              <Checkbox v-model:checked="formData.enableInternet">
                启用联网搜索
              </Checkbox>
            </Space>
          </FormItem>

          <Divider />

          <FormItem label="输入问题">
            <Textarea
              v-model:value="formData.content"
              :rows="4"
              placeholder="请输入您的问题..."
              @keydown="handleKeydown"
            />
            <div class="input-tip">
              按 Enter 发送，Shift+Enter 换行
            </div>
          </FormItem>

          <FormItem>
            <Space>
              <Button
                type="primary"
                :loading="loading"
                @click="handleSend"
              >
                发送消息
              </Button>
              <Button
                v-if="loading"
                danger
                @click="handleStop"
              >
                停止生成
              </Button>
              <Button @click="handleClear">
                清空对话
              </Button>
            </Space>
          </FormItem>
        </Form>
      </Card>

      <!-- 中间：对话显示 -->
      <Card title="对话预览" class="chat-card">
        <div class="chat-container">
          <div
            v-for="(msg, index) in messages"
            :key="index"
            class="message"
            :class="msg.role"
          >
            <div class="message-role">
              <span v-if="msg.role === 'user'">👤 你</span>
              <span v-else-if="msg.role === 'assistant'">🤖 AI</span>
              <span v-else>ℹ️ 系统</span>
            </div>
            <div class="message-content">
              <template v-if="msg.loading">
                <span class="loading-dots">正在思考</span>
              </template>
              <template v-else>
                <pre>{{ msg.content || '...' }}</pre>
              </template>
            </div>
          </div>
        </div>
      </Card>

      <!-- 右侧：日志输出 -->
      <Card title="调试日志" class="log-card">
        <template #extra>
          <Button size="small" @click="clearLogs">清空</Button>
        </template>
        <div class="log-container">
          <div
            v-for="(log, index) in logs"
            :key="index"
            class="log-entry"
            :style="{ borderLeftColor: getLogColor(log.type) }"
          >
            <span class="log-time">[{{ log.time }}]</span>
            <span class="log-type" :style="{ color: getLogColor(log.type) }">
              [{{ log.type.toUpperCase() }}]
            </span>
            <span class="log-message">{{ log.message }}</span>
            <pre v-if="log.data" class="log-data">{{ JSON.stringify(log.data, null, 2) }}</pre>
          </div>
        </div>
      </Card>
    </div>
  </Page>
</template>

<style scoped>
.chat-test-container {
  display: flex;
  gap: 16px;
  height: calc(100vh - 180px);
  min-height: 500px;
}

.config-card {
  width: 320px;
  flex-shrink: 0;
}

.config-card :deep(.ant-card-body) {
  overflow-y: auto;
  max-height: calc(100vh - 240px);
}

.chat-card {
  flex: 1;
  min-width: 300px;
}

.chat-card :deep(.ant-card-body) {
  padding: 0;
  height: calc(100% - 57px);
}

.chat-container {
  height: 100%;
  overflow-y: auto;
  padding: 16px;
  background: #fafafa;
}

.log-card {
  width: 380px;
  flex-shrink: 0;
}

.log-card :deep(.ant-card-body) {
  padding: 0;
  height: calc(100% - 57px);
}

.log-container {
  height: 100%;
  overflow-y: auto;
  padding: 8px;
  background: #1e1e1e;
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 12px;
}

.log-entry {
  padding: 6px 8px;
  margin-bottom: 4px;
  background: #2d2d2d;
  border-radius: 4px;
  border-left: 3px solid #666;
}

.log-time {
  color: #888;
  margin-right: 8px;
}

.log-type {
  font-weight: bold;
  margin-right: 8px;
}

.log-message {
  color: #d4d4d4;
}

.log-data {
  margin: 8px 0 0;
  padding: 8px;
  background: #1a1a1a;
  border-radius: 4px;
  color: #9cdcfe;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-all;
}

.message {
  margin-bottom: 16px;
  padding: 12px 16px;
  border-radius: 8px;
  max-width: 85%;
}

.message.user {
  margin-left: auto;
  background: #e3f2fd;
}

.message.assistant {
  margin-right: auto;
  background: #fff;
  border: 1px solid #e0e0e0;
}

.message.system {
  margin: 0 auto 16px;
  max-width: 90%;
  background: #fff3e0;
  border: 1px solid #ffcc80;
  text-align: center;
}

.message-role {
  font-size: 12px;
  font-weight: 600;
  margin-bottom: 4px;
  color: #666;
}

.message-content {
  white-space: pre-wrap;
  word-break: break-word;
  line-height: 1.6;
}

.message-content pre {
  margin: 0;
  white-space: pre-wrap;
  font-family: inherit;
}

.input-tip {
  font-size: 12px;
  color: #999;
  margin-top: 4px;
}

.loading-dots::after {
  content: '';
  animation: dots 1.5s steps(4, end) infinite;
}

@keyframes dots {
  0%, 20% { content: ''; }
  40% { content: '.'; }
  60% { content: '..'; }
  80%, 100% { content: '...'; }
}

@media (max-width: 1400px) {
  .chat-test-container {
    flex-wrap: wrap;
    height: auto;
  }

  .config-card {
    width: 100%;
    order: 1;
  }

  .chat-card {
    width: 100%;
    min-height: 300px;
    order: 2;
  }

  .log-card {
    width: 100%;
    min-height: 200px;
    order: 3;
  }
}
</style>