<script setup lang="ts">
import type {
  AiChatPanelProps,
  Attachment,
  ChatMessage,
  DesignPreviewData,
  ReasoningStep,
  WorkflowVariable,
} from './types';

/**
 * AI Chat Panel - 统一聊天面板组件
 *
 * 支持三种模式：
 * - workflow: 工作流编辑器调试模式（使用草稿版本）
 * - agent-debug: 智能体编辑器调试模式
 * - agent-chat: 智能体正式对话模式（支持历史、反馈）
 */
import { computed, onUnmounted, ref, watch } from 'vue';

import { Close, Setting } from '@element-plus/icons-vue';

import {
  ElButton,
  ElDialog,
  ElForm,
  ElFormItem,
  ElInput,
  ElMessage,
} from 'element-plus';

import { AiWorkingAnimation } from '#/components/ai-loading';
import { ChatBox } from '#/components/ChatBox';
import { useChatApi } from './composables/useChatApi';
import { useEventHandler } from './composables/useEventHandler';


// ==================== Props ====================
const props = withDefaults(defineProps<AiChatPanelProps>(), {
  mode: 'workflow',
  useDraft: true,
  enableVariablesForm: undefined,
  enableHistory: undefined,
  enableFeedback: false,
  enableWelcome: undefined,
  enableNodeEvents: undefined,
  showClearButton: true,
  showCloseButton: true,
  showHeader: true,
  showAvatar: true,
  enableVoice: true,
  enableAttachment: false,
  enableImage: false,
  layout: 'sidebar',
});

// ==================== Emits ====================
const emit = defineEmits<{
  (e: 'node-start', data: any): void;
  (e: 'node-complete', data: any): void;
  (e: 'node-streaming', data: any): void;
  (e: 'loop-iteration', data: any): void;
  (e: 'clear-status'): void;
  (e: 'conversation-created', conversationId: string): void;
  (e: 'close'): void;
  (e: 'message-sent', message: string): void;
  (e: 'message-complete', conversationId: null | string): void;
}>();

// ==================== 计算默认值 ====================
const enableVariablesForm = computed(
  () => props.enableVariablesForm ?? props.mode === 'workflow',
);
const enableHistory = computed(
  () => props.enableHistory ?? props.mode === 'agent-chat',
);
const enableFeedback = computed(
  () => props.enableFeedback ?? props.mode === 'agent-chat',
);
const enableWelcome = computed(
  () => props.enableWelcome ?? props.mode.startsWith('agent'),
);
const enableNodeEvents = computed(
  () => props.enableNodeEvents ?? props.mode === 'workflow',
);

// ==================== 计算 UI 配置 ====================
const panelTitle = computed(() => {
  if (props.title) return props.title;
  switch (props.mode) {
    case 'agent-chat': {
      return props.agent?.name || '对话';
    }
    case 'agent-debug': {
      return '调试预览';
    }
    case 'workflow': {
      return '运行预览';
    }
    default: {
      return '对话';
    }
  }
});

const placeholderText = computed(() => {
  if (props.placeholder) return props.placeholder;
  if (props.disabled) return '请先发布后再进行对话';
  switch (props.mode) {
    case 'agent-chat': {
      return '输入消息开始对话...';
    }
    case 'agent-debug': {
      return '输入消息进行调试...';
    }
    case 'workflow': {
      return '输入消息运行工作流...';
    }
    default: {
      return '输入消息...';
    }
  }
});

const emptyText = computed(() => {
  if (props.emptyText) return props.emptyText;
  switch (props.mode) {
    case 'agent-chat':
    case 'agent-debug': {
      return '开始对话吧';
    }
    case 'workflow': {
      return '输入消息开始运行工作流';
    }
    default: {
      return '开始对话吧';
    }
  }
});

const assistantName = computed(() => {
  if (props.assistantName) return props.assistantName;
  switch (props.mode) {
    case 'agent-chat':
    case 'agent-debug': {
      return props.agent?.name || '助手';
    }
    case 'workflow': {
      return '工作流';
    }
    default: {
      return '助手';
    }
  }
});

// ==================== 欢迎配置 ====================
const welcomeConfig = computed(() => {
  if (!enableWelcome.value || !props.agent) return undefined;

  const isPublished = props.agent.status === 'published';
  return {
    title: props.agent.name,
    description: isPublished
      ? props.agent.welcome_message || '发送消息开始对话'
      : '请先发布智能体后再进行对话',
    suggestions: isPublished ? props.agent.suggested_questions : [],
  };
});

// ==================== 核心状态 ====================
const messages = ref<ChatMessage[]>([]);
const running = ref(false);
const streamingContent = ref('');
const currentSteps = ref<ReasoningStep[]>([]);
const currentRunId = ref('');
const currentAssistantMsgId = ref<null | string>(null);
const waitingForInput = ref(false);
const waitingConfig = ref<any>(null);
let cancelStream: (() => void) | null = null;

// ==================== 多变量输入对话框 ====================
const variablesDialogVisible = ref(false);
const variablesForm = ref<Record<string, any>>({});
const pendingMessage = ref('');


// AI 工作动画状态（用于 application 类型工作流）
const showLoadingAnimation = ref(false);
const loadingAnimationTitle = ref('AI 正在开发...');

// 是否有任何设计面板打开
const hasAnyDesignPanelOpen = computed(() => showLoadingAnimation.value);

// ==================== 工作流变量 ====================
const startNode = computed(() => props.nodes?.find((n) => n.type === 'start'));
const variables = computed<WorkflowVariable[]>(
  () => startNode.value?.data?.variables || [],
);
const hasMultipleVariables = computed(() => variables.value.length > 1);

// 初始化变量表单
watch(
  variables,
  (vars) => {
    const newForm: Record<string, any> = {};
    vars.forEach((v) => {
      newForm[v.variable] =
        variablesForm.value[v.variable] || v.default_value || '';
    });
    variablesForm.value = newForm;
  },
  { immediate: true },
);

// ==================== API 适配器 ====================
const { adapter: chatApi, conversationId } = useChatApi(props);

// 创建一个类型安全的 conversationId 引用用于事件处理器
const safeConversationId = ref<null | string>(conversationId.value ?? null);
watch(conversationId, (newId) => {
  safeConversationId.value = newId ?? null;
});

// 监听 running 状态变化，执行完成时关闭加载动画
watch(running, (isRunning) => {
  if (!isRunning && showLoadingAnimation.value) {
    showLoadingAnimation.value = false;
  }
});

// ==================== 事件处理器 ====================
const generateId = () =>
  `msg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;

const handleDesignPreview = (data: DesignPreviewData) => {
  showLoadingAnimation.value = false;
  const content = [data.title, data.message].filter(Boolean).join('\n\n');
  if (content) {
    messages.value.push({
      id: generateId(),
      role: 'assistant',
      content,
      timestamp: new Date(),
      status: 'completed',
    });
  }
};

const { handleStreamEvent, updateAssistantMessage } = useEventHandler({
  props: {
    ...props,
    enableNodeEvents: enableNodeEvents.value,
  },
  emit: emit as any,
  messages,
  currentSteps,
  currentRunId,
  currentAssistantMsgId,
  waitingForInput,
  waitingConfig,
  running,
  conversationId: safeConversationId,
  onDesignPreview: handleDesignPreview,
});

// ==================== 加载历史消息 ====================
watch(
  () => props.conversationId,
  async (newId) => {
    if (enableHistory.value && newId && chatApi.loadHistory) {
      try {
        const history = await chatApi.loadHistory(newId);
        messages.value = history;
      } catch (error) {
        console.error('加载历史消息失败:', error);
      }
    } else if (!newId) {
      messages.value = [];
    }
  },
  { immediate: true },
);

// ==================== 发送消息 ====================
// 存储待发送的附件
const pendingAttachments = ref<Attachment[]>([]);

const handleSend = (text: string, attachments?: Attachment[]) => {
  if (!text || running.value) return;

  emit('message-sent', text);

  // 如果正在等待用户输入，恢复执行
  if (waitingForInput.value && currentRunId.value) {
    const lastAssistantMsg = messages.value.findLast(
      (m) => m.role === 'assistant',
    );
    if (lastAssistantMsg?.interaction) {
      const msgIndex = messages.value.findIndex(
        (m) => m.id === lastAssistantMsg.id,
      );
      if (msgIndex !== -1) {
        messages.value[msgIndex] = {
          ...lastAssistantMsg,
          interaction: undefined,
        };
      }
    }

    const userMsg: ChatMessage = {
      id: generateId(),
      role: 'user',
      content: text,
      timestamp: new Date(),
    };
    messages.value.push(userMsg);

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

    resumeExecution(text);
    return;
  }

  // 工作流模式：检查多变量
  if (
    props.mode === 'workflow' &&
    enableVariablesForm.value &&
    hasMultipleVariables.value
  ) {
    pendingMessage.value = text;
    pendingAttachments.value = attachments || [];
    const firstVar = variables.value[0];
    if (firstVar) {
      variablesForm.value[firstVar.variable] = text;
    }
    variablesDialogVisible.value = true;
    return;
  }

  // 检查最后一条用户消息是否是语音消息且内容已更新
  // 如果是，则跳过创建新消息，直接发送给 AI
  const lastUserMsg = messages.value.findLast((m) => m.role === 'user');
  const isVoiceMessageUpdate =
    lastUserMsg?.voice && lastUserMsg.content === text;

  if (isVoiceMessageUpdate) {
    // 语音消息已存在，直接发送给 AI（不创建新消息）
    const inputs =
      props.mode === 'workflow'
        ? { user_input: text }
        : props.initialInputs || undefined;
    runMessageWithExistingUserMsg(lastUserMsg, inputs);
  } else {
    // 发送消息（创建新的用户消息）
    const inputs =
      props.mode === 'workflow'
        ? { user_input: text }
        : props.initialInputs || undefined;
    runMessage(text, inputs, attachments);
  }
};

// 确认变量表单后运行
const handleVariablesConfirm = () => {
  variablesDialogVisible.value = false;
  runMessage(
    pendingMessage.value,
    variablesForm.value,
    pendingAttachments.value,
  );
  pendingAttachments.value = [];
};

// 运行消息（使用已存在的用户消息，用于语音消息）
const runMessageWithExistingUserMsg = (
  userMsg: ChatMessage,
  inputs?: Record<string, any>,
) => {
  // 如果是 application 类型工作流且是全屏布局，显示加载动画
  if (
    props.layout === 'fullscreen' &&
    props.agent?.workflow_type === 'application'
  ) {
    showLoadingAnimation.value = true;
    loadingAnimationTitle.value = 'AI 正在开发...';
  }

  // 添加 AI 消息（pending 状态）
  const assistantMsgId = generateId();
  const assistantMsg: ChatMessage = {
    id: assistantMsgId,
    role: 'assistant',
    content: '',
    timestamp: new Date(),
    status: 'pending',
    reasoning_steps: [],
  };
  messages.value.push(assistantMsg);
  currentAssistantMsgId.value = assistantMsgId;
  currentSteps.value = [];
  streamingContent.value = '';

  running.value = true;

  cancelStream = chatApi.sendMessage(
    userMsg.content,
    inputs,
    (event) => handleStreamEvent(event, assistantMsgId),
    (error) => {
      console.error('Stream error:', error);
      updateAssistantMessage(assistantMsgId, {
        status: 'failed',
        error_message: error.message || '执行失败',
      });
      running.value = false;
      ElMessage.error(error.message || '执行失败');
    },
    () => {
      cancelStream = null;
    },
    userMsg.attachments,
  );
};

// 运行消息
const runMessage = (
  userMessage: string,
  inputs?: Record<string, any>,
  attachments?: Attachment[],
) => {
  // 添加用户消息（包含附件）
  // 附件使用 file_id 关联文件管理系统
  const userMsg: ChatMessage = {
    id: generateId(),
    role: 'user',
    content: userMessage,
    timestamp: new Date(),
    attachments: attachments?.map((att) => ({
      file_id: att.file_id || att.id,
      id: att.file_id || att.id,
      type: att.type as 'audio' | 'file' | 'image' | 'video',
      name: att.name,
      url: att.url,
      size: att.size,
      thumbnail: att.thumbnail,
    })),
  };
  messages.value.push(userMsg);

  // 如果是 application 类型工作流且是全屏布局，显示加载动画
  if (
    props.layout === 'fullscreen' &&
    props.agent?.workflow_type === 'application'
  ) {
    showLoadingAnimation.value = true;
    loadingAnimationTitle.value = 'AI 正在开发...';
  }

  // 添加 AI 消息（pending 状态）
  const assistantMsgId = generateId();
  const assistantMsg: ChatMessage = {
    id: assistantMsgId,
    role: 'assistant',
    content: '',
    timestamp: new Date(),
    status: 'pending',
    reasoning_steps: [],
  };
  messages.value.push(assistantMsg);
  currentAssistantMsgId.value = assistantMsgId;
  currentSteps.value = [];
  streamingContent.value = '';

  running.value = true;

  cancelStream = chatApi.sendMessage(
    userMessage,
    inputs,
    (event) => handleStreamEvent(event, assistantMsgId),
    (error) => {
      console.error('Stream error:', error);
      updateAssistantMessage(assistantMsgId, {
        status: 'failed',
        error_message: error.message || '执行失败',
      });
      running.value = false;
      ElMessage.error(error.message || '执行失败');
    },
    () => {
      cancelStream = null;
    },
    attachments,
  );
};

// 恢复执行
const resumeExecution = (userInput: any) => {
  // 工作流模式需要 runId，Agent 模式需要 conversationId
  if (props.mode === 'workflow' && !currentRunId.value) return;
  if (props.mode !== 'workflow' && !conversationId.value) return;

  const assistantMsgId = generateId();
  const assistantMsg: ChatMessage = {
    id: assistantMsgId,
    role: 'assistant',
    content: '',
    timestamp: new Date(),
    status: 'pending',
  };
  messages.value.push(assistantMsg);
  currentAssistantMsgId.value = assistantMsgId;

  running.value = true;

  cancelStream = chatApi.resumeExecution(
    currentRunId.value || conversationId.value || '',
    userInput,
    (event) => handleStreamEvent(event, assistantMsgId),
    (error) => {
      console.error('Resume stream error:', error);
      updateAssistantMessage(assistantMsgId, {
        status: 'failed',
        error_message: error.message || '恢复执行失败',
      });
      running.value = false;
      // 关闭加载动画
      showLoadingAnimation.value = false;
      ElMessage.error(error.message || '恢复执行失败');
    },
    () => {
      cancelStream = null;
    },
  );
};

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

  // 全屏布局且是 application 类型工作流时，显示加载动画
  if (
    props.layout === 'fullscreen' &&
    props.agent?.workflow_type === 'application'
  ) {
    showLoadingAnimation.value = true;
    loadingAnimationTitle.value = 'AI 正在继续开发...';
  }

  const userMsg: ChatMessage = {
    id: generateId(),
    role: 'user',
    content: formatInteractionValue(value),
    timestamp: new Date(),
  };
  messages.value.push(userMsg);

  // 工作流模式需要 runId，Agent 模式需要 conversationId
  if (
    currentRunId.value ||
    (props.mode !== 'workflow' && conversationId.value)
  ) {
    resumeExecution(value);
  }

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

const handleInteractionCancel = (messageId: string) => {
  const msgIndex = messages.value.findIndex((m) => m.id === messageId);
  if (msgIndex !== -1) {
    const msg = messages.value[msgIndex];
    if (msg) {
      messages.value[msgIndex] = { ...msg, interaction: undefined };
    }
  }

  // 全屏布局且是 application 类型工作流时，显示加载动画
  if (
    props.layout === 'fullscreen' &&
    props.agent?.workflow_type === 'application'
  ) {
    showLoadingAnimation.value = true;
    loadingAnimationTitle.value = 'AI 正在继续开发...';
  }

  const userMsg: ChatMessage = {
    id: generateId(),
    role: 'user',
    content: waitingConfig.value?.cancel_text || '取消',
    timestamp: new Date(),
  };
  messages.value.push(userMsg);

  // 工作流模式需要 runId，Agent 模式需要 conversationId
  if (
    currentRunId.value ||
    (props.mode !== 'workflow' && conversationId.value)
  ) {
    resumeExecution(false);
  }

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

const formatInteractionValue = (value: any): string => {
  if (value === true) {
    return waitingConfig.value?.confirm_text || '确认';
  }
  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);
};

// ==================== 其他操作 ====================
const handleStop = () => {
  cancelStream?.();
  cancelStream = null;
  running.value = false;

  if (currentAssistantMsgId.value) {
    updateAssistantMessage(currentAssistantMsgId.value, {
      status: 'failed',
      error_message: '用户停止',
    });
    currentAssistantMsgId.value = null;
  }
};

const handleClear = () => {
  messages.value = [];
  streamingContent.value = '';
  currentSteps.value = [];
  currentRunId.value = '';
  waitingForInput.value = false;
  waitingConfig.value = null;
  emit('clear-status');
};

const handleFeedback = (messageId: string, feedback: 'dislike' | 'like') => {
  if (chatApi.sendFeedback) {
    chatApi.sendFeedback(messageId, feedback);
    const msgIndex = messages.value.findIndex((m) => m.id === messageId);
    if (msgIndex !== -1) {
      messages.value[msgIndex] = {
        ...messages.value[msgIndex]!,
        feedback,
      };
    }
  }
};

const handleAddMessage = (message: ChatMessage) => {
  messages.value.push(message);
};

const handleUpdateMessage = (
  messageId: string,
  updates: Partial<ChatMessage>,
) => {
  const idx = messages.value.findIndex((m) => m.id === messageId);
  if (idx !== -1) {
    messages.value[idx] = { ...messages.value[idx]!, ...updates };
  }
};

// ==================== 设计预览处理 ====================
defineExpose({
  clearChat: handleClear,
  sendMessage: handleSend,
});

// ==================== 生命周期 ====================
onUnmounted(() => {
  cancelStream?.();
});
</script>

<template>
  <div class="flex h-full overflow-hidden">
    <!-- 聊天面板 -->
    <div
      class="flex h-full flex-col overflow-hidden"
      :class="[
        layout === 'fullscreen'
          ? hasAnyDesignPanelOpen
            ? 'w-[400px] flex-shrink-0'
            : 'flex-1'
          : 'bg-card w-96 rounded-[8px] shadow-xl',
      ]"
    >
      <!-- 头部 -->
      <div
        v-if="showHeader"
        class="flex items-center justify-between px-4 py-4"
      >
        <div class="text-foreground flex items-center gap-2 font-medium">
          {{ panelTitle }}
        </div>
        <div class="flex items-center gap-1">
          <!-- 变量设置按钮（工作流模式且有多变量时显示） -->
          <ElButton
            v-if="
              mode === 'workflow' && enableVariablesForm && hasMultipleVariables
            "
            link
            :icon="Setting"
            title="配置输入变量"
            @click="variablesDialogVisible = true"
          />
          <ElButton
            v-if="showCloseButton"
            link
            :icon="Close"
            @click="$emit('close')"
          />
        </div>
      </div>

      <!-- ChatBox 组件 -->
      <ChatBox
        :messages="messages"
        :loading="running"
        :streaming-content="streamingContent"
        :show-avatar="showAvatar"
        :assistant-name="assistantName"
        :placeholder="placeholderText"
        :disabled="disabled"
        :enable-attachment="enableAttachment"
        :enable-image="enableImage"
        :enable-voice="enableVoice"
        :enable-feedback="enableFeedback"
        :show-clear-button="showClearButton"
        :empty-text="emptyText"
        :welcome-config="welcomeConfig"
        class="flex-1 rounded-none border-0"
        @send="handleSend"
        @stop="handleStop"
        @clear="handleClear"
        @feedback="handleFeedback"
        @interaction-submit="handleInteractionSubmit"
        @interaction-cancel="handleInteractionCancel"
        @add-message="handleAddMessage"
        @update-message="handleUpdateMessage"
      />

      <!-- 多变量输入对话框 -->
      <ElDialog
        v-model="variablesDialogVisible"
        title="配置输入变量"
        width="400px"
        :close-on-click-modal="false"
      >
        <ElForm label-position="top">
          <ElFormItem
            v-for="v in variables"
            :key="v.variable"
            :label="v.variable"
            :required="v.required"
          >
            <ElInput
              v-model="variablesForm[v.variable]"
              :placeholder="`请输入 ${v.variable}`"
              :type="v.type === 'text' ? 'textarea' : 'text'"
              :rows="v.type === 'text' ? 3 : undefined"
            />
          </ElFormItem>
        </ElForm>
        <template #footer>
          <ElButton @click="variablesDialogVisible = false">取消</ElButton>
          <ElButton type="primary" @click="handleVariablesConfirm">
            开始运行
          </ElButton>
        </template>
      </ElDialog>
    </div>

    <!-- 设计面板区域（全屏布局时并排显示） -->
    <div
      v-if="layout === 'fullscreen' && hasAnyDesignPanelOpen"
      class="flex flex-1 flex-col overflow-hidden"
    >
      <!-- AI 工作动画 -->
      <AiWorkingAnimation
        v-if="showLoadingAnimation"
        :title="loadingAnimationTitle"
        subtitle="正在分析需求并生成代码"
        :show-background="false"
        class="ml-3 h-full min-h-[400px] flex-1 rounded-lg"
      />

      <!-- 设计编辑面板 -->
    </div>
  </div>
</template>
