<script setup lang="ts">
import type {
  Agent,
  AgentChatEvent,
  AgentMessage,
  ReasoningStep,
} from '#/api/ai-platform/ai-platform';
import type { ChatMessage } from '#/components/ChatBox/index';

/**
 * Agent 对话面板组件
 * 可复用于 Agent 编辑页面和 Agent 对话页面
 */
import { computed, nextTick, onUnmounted, ref, watch } from 'vue';

import { $t } from '@vben/locales';

import { ElMessage } from 'element-plus';

import {
  feedbackAgentMessageApi,
  getAgentMessagesApi,
  sendAgentMessageStream,
} from '#/api/ai-platform/ai-platform';
import { ChatBox } from '#/components/ChatBox/index';

const props = defineProps<{
  /** Agent 详情（可选，用于显示名称和欢迎配置） */
  agent?: Agent | null;
  /** Agent ID */
  agentId: string;
  /** 当前对话 ID（用于加载历史消息） */
  currentConversationId?: null | string;
  /** 是否禁用输入 */
  disabled?: boolean;
  /** 是否启用附件 */
  enableAttachment?: boolean;
  /** 是否启用图片 */
  enableImage?: boolean;
  /** 是否启用语音 */
  enableVoice?: boolean;
  /** 占位符文本 */
  placeholder?: string;
  /** 是否显示清空按钮 */
  showClearButton?: boolean;
}>();

const emit = defineEmits<{
  (e: 'conversation-created', conversationId: string): void;
}>();

// 设计面板显示状态

// 对话状态
const chatMessages = ref<AgentMessage[]>([]);
const sending = ref(false);
const streamingContent = ref('');
const streamingSteps = ref<ReasoningStep[]>([]);
const currentStep = ref('');
const conversationId = ref<null | string>(null);
const chatBoxRef = ref<InstanceType<typeof ChatBox> | null>(null);

// 对话流交互状态
const waitingForInput = ref(false);
const waitingConfig = ref<any>(null);

// 设计面板状态
let cancelStream: (() => void) | null = null;

// 生成消息 ID
const generateId = () =>
  `msg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;

// 转换消息格式为 ChatMessage
const formattedMessages = computed<ChatMessage[]>(() => {
  return chatMessages.value.map((msg) => ({
    id: msg.id,
    role: msg.role as 'assistant' | 'user',
    content: msg.content,
    status: msg.status as any,
    timestamp: msg.created_at,
    elapsed_time: msg.elapsed_time,
    tokens_used: msg.total_tokens,
    error_message: msg.error_message,
    feedback: (msg.feedback as any) || null,
    reasoning_steps: msg.reasoning_steps?.map((step) => ({
      type: step.type as any,
      content: step.content || '',
      tool: step.tool,
      params: step.params,
    })),
    interaction: msg.interaction,
    voice: msg.voice as any,
  }));
});

// 欢迎配置
const welcomeConfig = computed(() => {
  if (!props.agent) return undefined;
  return {
    title: props.agent.name,
    description:
      props.agent.status === 'published'
        ? props.agent.welcome_message ||
          $t('ai-platform.agent.chatPanel.sendToStart')
        : $t('ai-platform.agent.chatPanel.publishFirst'),
    suggestions:
      props.agent.status === 'published' ? props.agent.suggested_questions : [],
  };
});

// 监听 agentId 变化，清空对话
watch(
  () => props.agentId,
  () => {
    clearChat();
  },
);

// 监听 currentConversationId 变化，加载历史消息
watch(
  () => props.currentConversationId,
  async (newId) => {
    if (newId) {
      await loadMessages(newId);
    } else {
      clearChat();
    }
  },
  { immediate: true },
);

// 加载历史消息
async function loadMessages(convId: string) {
  // 如果正在发送消息或等待用户输入，跳过加载以避免覆盖当前状态
  if (sending.value || waitingForInput.value) {
    conversationId.value = convId;
    return;
  }

  try {
    const res = await getAgentMessagesApi(convId, { pageSize: 100 });
    chatMessages.value = res.items;
    conversationId.value = convId;
    await nextTick();
    scrollToBottom();
  } catch (error) {
    console.error('加载消息失败:', error);
  }
}

// 发送消息 (由 ChatBox 触发)
async function handleSendMessage(message: string) {
  if (!message.trim() || sending.value) return;

  // 如果正在等待用户输入（对话流模式），处理恢复逻辑
  if (waitingForInput.value) {
    // 移除最后一条助手消息的交互配置
    const lastAssistantMsg = chatMessages.value.findLast(
      (m) => m.role === 'assistant',
    );
    if (lastAssistantMsg && lastAssistantMsg.interaction) {
      const msgIndex = chatMessages.value.findIndex(
        (m) => m.id === lastAssistantMsg.id,
      );
      if (msgIndex !== -1) {
        chatMessages.value[msgIndex] = {
          ...lastAssistantMsg,
          interaction: undefined,
        };
      }
    }

    // 添加用户消息
    const userMsg: AgentMessage = {
      id: generateId(),
      role: 'user',
      content: message,
      status: 'completed',
      reasoning_steps: [],
      tool_calls: [],
      prompt_tokens: 0,
      completion_tokens: 0,
      total_tokens: 0,
      elapsed_time: 0,
      error_message: '',
      feedback: '',
      created_at: new Date().toISOString(),
    };
    chatMessages.value.push(userMsg);

    // 重置等待状态并继续工作流
    waitingForInput.value = false;
    waitingConfig.value = null;
    doSendMessage(message, false);
    return;
  }

  doSendMessage(message, true);
}

// 实际发送消息的函数
async function doSendMessage(message: string, addUserMessage: boolean = true) {
  sending.value = true;
  streamingContent.value = '';
  streamingSteps.value = [];
  currentStep.value = '';

  // 添加用户消息
  if (addUserMessage) {
    const userMessage: AgentMessage = {
      id: generateId(),
      role: 'user',
      content: message,
      status: 'completed',
      reasoning_steps: [],
      tool_calls: [],
      prompt_tokens: 0,
      completion_tokens: 0,
      total_tokens: 0,
      elapsed_time: 0,
      error_message: '',
      feedback: '',
      created_at: new Date().toISOString(),
    };
    chatMessages.value.push(userMessage);
  }

  // 添加助手消息占位
  const assistantMessage: AgentMessage = {
    id: generateId(),
    role: 'assistant',
    content: '',
    status: 'pending',
    reasoning_steps: [],
    tool_calls: [],
    prompt_tokens: 0,
    completion_tokens: 0,
    total_tokens: 0,
    elapsed_time: 0,
    error_message: '',
    feedback: '',
    created_at: new Date().toISOString(),
  };
  chatMessages.value.push(assistantMessage);

  await nextTick();
  scrollToBottom();

  // 发送流式请求
  // 系统变量（application_id 等）由 API 层自动注入
  cancelStream = sendAgentMessageStream(
    props.agentId,
    {
      message,
      conversation_id: conversationId.value || undefined,
    },
    (event: AgentChatEvent) => handleStreamEvent(event, assistantMessage),
    (error) => {
      console.error('Stream error:', error);
      assistantMessage.status = 'failed';
      assistantMessage.error_message = error.message;
      sending.value = false;
    },
    () => {
      sending.value = false;
    },
  );
}

// 处理流式事件
function handleStreamEvent(
  event: AgentChatEvent,
  assistantMessage: AgentMessage,
) {
  const msgIndex = chatMessages.value.findIndex(
    (m) => m.id === assistantMessage.id,
  );

  switch (event.type) {
    case 'action': {
      currentStep.value = 'action';
      streamingSteps.value.push({
        type: 'action',
        content: '',
        tool: event.tool,
        params: event.params,
        timestamp: new Date().toISOString(),
      });
      assistantMessage.reasoning_steps = [...streamingSteps.value];
      break;
    }

    case 'annotation_reply':

    case 'knowledge_retrieval': {
      currentStep.value = event.type;
      streamingSteps.value.push({
        type: event.type as 'annotation_reply' | 'knowledge_retrieval',
        content: event.content || '',
        status: 'completed',
        timestamp: new Date().toISOString(),
      });
      assistantMessage.reasoning_steps = [...streamingSteps.value];
      break;
    }

    case 'answer': {
      currentStep.value = 'answering';
      streamingContent.value = event.content || '';
      assistantMessage.content = streamingContent.value;
      break;
    }

    case 'complete': {
      assistantMessage.status = 'completed';
      assistantMessage.total_tokens = event.tokens_used || 0;
      assistantMessage.elapsed_time = event.elapsed_time || 0;
      currentStep.value = '';
      break;
    }

    case 'error': {
      assistantMessage.status = 'failed';
      assistantMessage.error_message =
        event.content || $t('ai-platform.agent.chatPanel.executionFailed');
      currentStep.value = '';
      break;
    }

    case 'node_complete': {
      // 查找已存在的 node_start 步骤并更新为 node_complete
      const existingIndex = streamingSteps.value.findIndex(
        (s) => s.node_id === event.node_id && s.type === 'node_start',
      );
      if (existingIndex === -1) {
        // 如果没有找到对应的 start，添加新的 complete 步骤
        streamingSteps.value.push({
          type: 'node_complete',
          content: event.node_label || event.node_type || '',
          node_id: event.node_id,
          node_type: event.node_type,
          output: event.outputs,
          status: 'completed',
          timestamp: new Date().toISOString(),
        });
      } else {
        const existingStep = streamingSteps.value[existingIndex]!;
        // 更新已存在的步骤
        streamingSteps.value[existingIndex] = {
          ...existingStep,
          type: 'node_complete',
          content: event.node_label || event.node_type || '',
          output: event.outputs,
          status: 'completed',
          timestamp: existingStep.timestamp || new Date().toISOString(),
        };
      }
      assistantMessage.reasoning_steps = [...streamingSteps.value];
      break;
    }
    case 'node_event': {
      // 节点事件（如消息节点发送消息）
      const nodeEvent = event.event;
      if (nodeEvent?.type === 'message') {
        // 从消息列表中查找初始消息，检查其内容是否为空
        const initialMsg = chatMessages.value.find(
          (m) => m.id === assistantMessage.id,
        );
        if (initialMsg && !initialMsg.content?.trim()) {
          // 更新初始消息（typing indicator -> 实际内容）
          initialMsg.content = nodeEvent.content || '';
          initialMsg.status = 'completed';
        } else {
          // 已有内容，创建新消息
          const newMsg: AgentMessage = {
            id: generateId(),
            role: 'assistant',
            content: nodeEvent.content || '',
            status: 'completed',
            reasoning_steps: [],
            tool_calls: [],
            prompt_tokens: 0,
            completion_tokens: 0,
            total_tokens: 0,
            elapsed_time: 0,
            error_message: '',
            feedback: '',
            created_at: new Date().toISOString(),
          };
          chatMessages.value.push(newMsg);
        }
      }
      break;
    }

    case 'node_start': {
      // 检查是否已存在相同 node_id 的步骤（避免重复）
      const existingIndex = streamingSteps.value.findIndex(
        (s) => s.node_id === event.node_id,
      );
      if (existingIndex === -1) {
        // 添加新的执行步骤
        streamingSteps.value.push({
          type: 'node_start',
          content: `${event.node_label || event.node_type}`,
          node_id: event.node_id,
          node_type: event.node_type,
          status: 'running',
          timestamp: new Date().toISOString(),
        });
      }
      assistantMessage.reasoning_steps = [...streamingSteps.value];
      break;
    }

    case 'observation': {
      currentStep.value = 'observation';
      streamingSteps.value.push({
        type: 'observation',
        content: event.content || '',
        timestamp: new Date().toISOString(),
      });
      assistantMessage.reasoning_steps = [...streamingSteps.value];
      break;
    }

    case 'start': {
      if (event.conversation_id && !conversationId.value) {
        conversationId.value = event.conversation_id;
        emit('conversation-created', event.conversation_id);
      }
      if (event.message_id) {
        assistantMessage.id = event.message_id;
      }
      break;
    }

    case 'thought': {
      currentStep.value = 'thinking';
      streamingSteps.value.push({
        type: 'thought',
        content: event.content || '',
        timestamp: new Date().toISOString(),
      });
      assistantMessage.reasoning_steps = [...streamingSteps.value];
      break;
    }

    case 'waiting_input': {
      assistantMessage.status = 'completed';
      currentStep.value = '';
      waitingForInput.value = true;
      waitingConfig.value = event.config;

      const configData = event.config as any;

      // 检查是否是设计预览类型
      const newMsg: AgentMessage = {
        id: generateId(),
        role: 'assistant',
        content: getWaitingPrompt(event.config),
        status: 'completed',
        reasoning_steps: [],
        tool_calls: [],
        prompt_tokens: 0,
        completion_tokens: 0,
        total_tokens: 0,
        elapsed_time: 0,
        error_message: '',
        feedback: '',
        created_at: new Date().toISOString(),
      };
      chatMessages.value.push(newMsg);
      sending.value = false;
      break;
    }
  }

  if (msgIndex !== -1) {
    chatMessages.value[msgIndex] = { ...assistantMessage };
  }

  scrollToBottom();
}

// 获取等待提示文本
function getWaitingPrompt(config: any) {
  if (!config) return $t('ai-platform.agent.chatPanel.waitingInput');
  switch (config.type) {
    case 'choice': {
      return config.question || $t('ai-platform.agent.chatPanel.selectPrompt');
    }
    case 'confirm': {
      return `**${config.title || $t('ai-platform.agent.chatPanel.confirm')}**\n\n${config.content || $t('ai-platform.agent.chatPanel.confirmContinue')}`;
    }
    case 'question': {
      return config.question || $t('ai-platform.agent.chatPanel.inputPrompt');
    }
    default: {
      return $t('ai-platform.agent.chatPanel.waitingInput');
    }
  }
}

// 处理交互提交
function handleInteractionSubmit(messageId: string, value: any) {
  const msgIndex = chatMessages.value.findIndex((m) => m.id === messageId);
  if (msgIndex !== -1) {
    const msg = chatMessages.value[msgIndex];
    if (msg) {
      chatMessages.value[msgIndex] = { ...msg, interaction: undefined };
    }
  }

  const userMsg: AgentMessage = {
    id: generateId(),
    role: 'user',
    content: formatInteractionValue(value),
    status: 'completed',
    reasoning_steps: [],
    tool_calls: [],
    prompt_tokens: 0,
    completion_tokens: 0,
    total_tokens: 0,
    elapsed_time: 0,
    error_message: '',
    feedback: '',
    created_at: new Date().toISOString(),
  };
  chatMessages.value.push(userMsg);

  waitingForInput.value = false;
  waitingConfig.value = null;

  doSendMessage(String(value), false);
}

// 处理交互取消
function handleInteractionCancel(messageId: string) {
  const msgIndex = chatMessages.value.findIndex((m) => m.id === messageId);
  if (msgIndex !== -1) {
    const msg = chatMessages.value[msgIndex];
    if (msg) {
      chatMessages.value[msgIndex] = { ...msg, interaction: undefined };
    }
  }

  const userMsg: AgentMessage = {
    id: generateId(),
    role: 'user',
    content:
      waitingConfig.value?.cancel_text ||
      $t('ai-platform.agent.chatPanel.cancelText'),
    status: 'completed',
    reasoning_steps: [],
    tool_calls: [],
    prompt_tokens: 0,
    completion_tokens: 0,
    total_tokens: 0,
    elapsed_time: 0,
    error_message: '',
    feedback: '',
    created_at: new Date().toISOString(),
  };
  chatMessages.value.push(userMsg);

  waitingForInput.value = false;
  waitingConfig.value = null;

  doSendMessage('false', false);
}

// 格式化交互值显示
function formatInteractionValue(value: any) {
  if (value === true) {
    return (
      waitingConfig.value?.confirm_text ||
      $t('ai-platform.agent.chatPanel.confirm')
    );
  }
  if (value === false) {
    return (
      waitingConfig.value?.cancel_text ||
      $t('ai-platform.agent.chatPanel.cancelText')
    );
  }
  if (Array.isArray(value)) {
    const options = waitingConfig.value?.options || [];
    const labels = value.map((v: string) => {
      const opt = options.find((o: any) => o.value === v);
      return opt?.label || v;
    });
    return labels.join(', ');
  }
  if (waitingConfig.value?.type === 'choice') {
    const options = waitingConfig.value?.options || [];
    const opt = options.find((o: any) => o.value === value);
    return opt?.label || value;
  }
  return String(value);
}

// 滚动到底部
function scrollToBottom() {
  chatBoxRef.value?.scrollToBottom();
}

// 清空对话
function clearChat() {
  chatMessages.value = [];
  conversationId.value = null;
  streamingContent.value = '';
  streamingSteps.value = [];
  waitingForInput.value = false;
  waitingConfig.value = null;
}

// 添加消息（语音消息用）
function handleAddMessage(message: any) {
  const agentMsg: AgentMessage = {
    id: message.id || generateId(),
    role: message.role || 'user',
    content: message.content || '',
    status: 'completed',
    reasoning_steps: [],
    tool_calls: [],
    prompt_tokens: 0,
    completion_tokens: 0,
    total_tokens: 0,
    elapsed_time: 0,
    error_message: '',
    feedback: '',
    created_at: new Date().toISOString(),
    voice: message.voice,
  };
  chatMessages.value.push(agentMsg);
  scrollToBottom();
}

// 更新消息（语音识别完成后用）
function handleUpdateMessage(messageId: string, updates: any) {
  const msgIndex = chatMessages.value.findIndex((m) => m.id === messageId);
  if (msgIndex !== -1) {
    const msg = chatMessages.value[msgIndex]!;
    chatMessages.value[msgIndex] = { ...msg, ...updates };

    // 如果语音识别成功，触发发送
    if (updates.content && !updates.content.startsWith('[')) {
      doSendMessage(updates.content, false);
    }
  }
}

// 消息反馈
async function handleChatFeedback(
  messageId: string,
  feedback: 'dislike' | 'like',
) {
  if (messageId.startsWith('temp-') || messageId.startsWith('msg-')) return;

  try {
    await feedbackAgentMessageApi(messageId, { feedback });
    const msg = chatMessages.value.find((m) => m.id === messageId);
    if (msg) {
      msg.feedback = feedback;
    }
    ElMessage.success($t('ai-platform.agent.chatPanel.feedbackThanks'));
  } catch (error) {
    console.error('反馈失败:', error);
  }
}

// 设计面板确认
defineExpose({
  clearChat,
  scrollToBottom,
});

onUnmounted(() => {
  cancelStream?.();
});
</script>

<template>
  <div class="flex h-full overflow-hidden">
    <!-- 聊天区域 -->
    <div
      class="h-full overflow-hidden"
      class="flex-1"
    >
      <ChatBox
        ref="chatBoxRef"
        :messages="formattedMessages"
        :loading="sending"
        :streaming-content="streamingContent"
        :assistant-name="agent?.name"
        :welcome-config="welcomeConfig"
        :disabled="disabled"
        :placeholder="
          placeholder || $t('ai-platform.agent.chatPanel.inputPlaceholder')
        "
        :enable-feedback="true"
        :enable-regenerate="false"
        :enable-attachment="enableAttachment ?? false"
        :enable-image="enableImage ?? false"
        :enable-voice="enableVoice ?? true"
        :show-clear-button="showClearButton ?? true"
        class="h-full"
        @send="handleSendMessage"
        @feedback="handleChatFeedback"
        @clear="clearChat"
        @interaction-submit="handleInteractionSubmit"
        @interaction-cancel="handleInteractionCancel"
        @add-message="handleAddMessage"
        @update-message="handleUpdateMessage"
      />
    </div>
  </div>
</template>
