<template>
  <main class="chat-main" :class="{ 'wide-mode': isWideMode }">
    <!-- 头部 -->
    <ChatHeader
      :title="currentConversation?.title || '新对话'"
      :message-count="messages.length"
      :show-sidebar-toggle="sidebarCollapsed"
      :is-wide-mode="isWideMode"
      :is-pinned="currentConversation?.pinned"
      @toggle-sidebar="$emit('toggle-sidebar')"
      @toggle-wide-mode="toggleWideMode"
      @clear="handleClear"
      @export="handleExport"
      @pin="handlePin"
    />

    <!-- 消息列表 -->
    <MessageList
      ref="messageListRef"
      :messages="messages"
      :show-timestamp="settings.showTimestamp"
      :compact="settings.compactMode"
      :is-typing="isTyping"
      @retry="handleRetry"
      @regenerate="handleRegenerate"
      @select-suggestion="handleSuggestion"
    />

    <!-- 输入区域 -->
    <div class="input-wrapper">
      <div class="input-container" :class="{ wide: isWideMode }">
        <ChatInput
          ref="chatInputRef"
          :placeholder="inputPlaceholder"
          :is-streaming="isStreaming"
          :send-on-enter="settings.sendOnEnter"
          :disabled="false"
          :supports_thinking="currentModelCapabilities.supports_thinking"
          :supports_web_search="currentModelCapabilities.supports_web_search"
          :supports_vision="currentModelCapabilities.supports_vision"
          :supports_files="currentModelCapabilities.supports_files"
          @send="handleSend"
          @stop="handleStop"
        />
      </div>
    </div>
  </main>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick, onMounted } from "vue";
import { storeToRefs } from "pinia";
import { useChatStore } from "@/stores/chat";
import { useSettingsStore } from "@/stores/settings";
import { useAuthStore } from "@/stores/auth";
import ChatHeader from "./ChatHeader.vue";
import MessageList from "./MessageList.vue";
import ChatInput from "@/components/input/ChatInput.vue";
import { MessageType, MessageRole } from "@/types/chat";
import type { Attachment, Suggestion } from "@/types/chat";
import { chatApi, type ModelInfo } from "@/services/api";

defineEmits<{
  "toggle-sidebar": [];
}>();

const chatStore = useChatStore();
const settingsStore = useSettingsStore();
const authStore = useAuthStore();

const { currentConversation, isStreaming } = storeToRefs(chatStore);
const { settings, sidebarCollapsed } = storeToRefs(settingsStore);

const messageListRef = ref<InstanceType<typeof MessageList> | null>(null);
const chatInputRef = ref<InstanceType<typeof ChatInput> | null>(null);
const isWideMode = ref(true);
const isTyping = ref(false);
const currentStreamingMessageId = ref<string | null>(null);
const abortController: any = ref<AbortController | null>(null);

// 模型列表和当前模型能力
const availableModels = ref<ModelInfo[]>([]);

// 获取模型列表
onMounted(async () => {
  try {
    availableModels.value = await chatApi.getModels();
  } catch (error) {
    console.error("获取模型列表失败:", error);
  }
});

// 当前模型的能力
const currentModelCapabilities = computed(() => {
  const modelId = settings.value.defaultModel;
  const model = availableModels.value.find((m) => m.id === modelId);
  console.log(model);
  if (model) {
    return {
      supports_thinking: model.supports_thinking ?? false,
      supports_web_search: model.supports_web_search ?? false,
      supports_vision: model.supports_vision ?? false,
      supports_files: model.supports_files ?? false,
    };
  }
  // 默认全部支持
  return {
    supports_thinking: true,
    supports_web_search: true,
    supports_vision: true,
    supports_files: true,
  };
});

const messages: any = computed(() => currentConversation.value?.messages || []);

const inputPlaceholder = computed(() => {
  if (isStreaming.value) return "正在生成回复...";
  return "输入你的问题，按 Ctrl+Enter 发送";
});

function toggleWideMode() {
  isWideMode.value = !isWideMode.value;
}

function handleClear() {
  if (currentConversation.value) {
    chatStore.clearConversation(currentConversation.value.id);
  }
}

function handleExport() {
  if (!currentConversation.value) return;

  const data = {
    title: currentConversation.value.title,
    messages: currentConversation.value.messages,
    exportedAt: new Date().toISOString(),
  };

  const blob = new Blob([JSON.stringify(data, null, 2)], {
    type: "application/json",
  });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = `${currentConversation.value.title}.json`;
  a.click();
  URL.revokeObjectURL(url);
}

function handlePin() {
  if (currentConversation.value) {
    chatStore.togglePinConversation(currentConversation.value.id);
  }
}

// 发送消息 - 使用真实 API
async function handleSend(
  text: string,
  attachments: Attachment[],
  options?: {
    deepSearch?: boolean;
    webSearch?: boolean;
    deepThinking?: boolean;
    systemPrompt?: string;
  },
) {
  // 检查认证状态
  if (!authStore.isAuthenticated) {
    window.$toast?.('请先登录', 'error');
    return;
  }

  console.log("handleSend", text, attachments, options);
  // 检查是否还有正在上传的附件
  const uploadingAttachments = attachments.filter((a) => a.uploading);
  if (uploadingAttachments.length > 0) {
    // 等待所有上传完成
    const uploads = uploadingAttachments.map(async (attachment) => {
      // 这里我们可以通过检查附件状态来判断是否上传完成
      // 但更简单的方法是等待一小段时间，让上传有机会完成
      return new Promise<void>((resolve) => {
        const checkUpload = () => {
          const stillUploading = attachments.some(
            (a) => a.id === attachment.id && a.uploading,
          );
          if (!stillUploading) {
            resolve();
          } else {
            setTimeout(checkUpload, 100); // 每100ms检查一次
          }
        };
        checkUpload();
      });
    });

    try {
      await Promise.all(uploads);
    } catch (error) {
      console.error("等待上传完成时发生错误:", error);
    }
  }

  // 如果没有当前对话，创建新对话
  if (!currentConversation.value) {
    await chatStore.createConversation();
  }

  // 从当前会话中提取历史消息（用于上下文记忆），在添加新消息之前提取
  const existingMessages = currentConversation.value?.messages || [];
  const MAX_HISTORY_ROUNDS = 20; // 最多保留最近 20 轮（40 条消息）
  const historyMessages = existingMessages
    .filter(
      (m: any) =>
        m.role === MessageRole.USER || m.role === MessageRole.ASSISTANT,
    )
    .filter((m: any) => m.content?.text) // 过滤掉空消息
    .slice(-(MAX_HISTORY_ROUNDS * 2))
    .map((m: any) => ({ role: m.role, content: m.content.text }));

  // 添加用户消息
  await chatStore.addMessage(MessageRole.USER, {
    type: MessageType.TEXT,
    text,
    images: attachments.filter((a) => a.type === "image"),
    files: attachments.filter((a) => a.type === "file"),
  });

  // 添加 AI 消息占位符
  const aiMessage = await chatStore.addMessage(MessageRole.ASSISTANT, {
    type: MessageType.TEXT,
    text: "",
  });

  currentStreamingMessageId.value = aiMessage.id;
  chatStore.updateMessage(aiMessage.id, { isStreaming: true });
  chatStore.startStreaming();
  isTyping.value = true;

  // 创建 AbortController
  abortController.value = new AbortController();
  try {
    // 提取图片URL用于发送给API
    const imageUrls = attachments
      .filter((a) => a.type === "image")
      .map((a) => a.url);

    // 提取非图片文件URL（txt, pdf, docx 等）
    const fileUrls = attachments
      .filter((a) => a.type === "file")
      .map((a) => a.url);

    const stream = chatApi.streamChat(
      {
        message: text,
        conversationId: currentConversation.value?.id || "",
        images: imageUrls,
        files: fileUrls,
        model: settings.value.defaultModel,
        stream: true,
        history: historyMessages,
        deepSearch: options?.deepSearch,
        webSearch: options?.webSearch,
        deepThinking: options?.deepThinking,
        systemPrompt: options?.systemPrompt,
      },
      abortController.value.signal,
    );

    let fullText = "";
    let reasoningText = "";
    let isInReasoning = false;
    isTyping.value = false;

    for await (const chunk of stream) {
      if (abortController.value?.signal.aborted) break;

      if (chunk.type === "reasoning") {
        // 深度思考内容
        if (!isInReasoning) {
          // 开始深度思考块
          reasoningText = "";
          isInReasoning = true;
          fullText += "<think>\n";
        }
        reasoningText += chunk.text;
        fullText += chunk.text;
      } else {
        // 普通内容
        if (isInReasoning) {
          // 结束深度思考块
          isInReasoning = false;
          fullText += "\n</think>\n";
        }
        fullText += chunk.text;
      }
      chatStore.updateMessageContent(aiMessage.id, fullText);
    }

    // 如果最后还在深度思考块中，关闭它
    if (isInReasoning) {
      fullText += "\n</think>";
    }

    if (!abortController.value?.signal.aborted) {
      chatStore.updateMessage(aiMessage.id, {
        isStreaming: false,
        content: {
          type: MessageType.TEXT,
          text: fullText,
        },
      });
    }
  } catch (error: any) {
    if (error.name !== "AbortError") {
      chatStore.updateMessage(aiMessage.id, {
        isStreaming: false,
        isError: true,
        errorMessage: error.message || "请求失败",
      });
    }
  } finally {
    chatStore.stopStreaming();
    currentStreamingMessageId.value = null;
  }
}

// 停止生成
function handleStop() {
  if (abortController.value) {
    abortController.value.abort();
    abortController.value = null;
  }

  chatStore.stopStreaming();
  chatApi.stopChat(messages.value.at(-1)["messageId"]);
  if (currentStreamingMessageId.value) {
    chatStore.updateMessage(currentStreamingMessageId.value, {
      isStreaming: false,
    });
    currentStreamingMessageId.value = null;
  }
}

// 重试
async function handleRetry(messageId: string) {
  // 检查认证状态
  if (!authStore.isAuthenticated) {
    window.$toast?.('请先登录', 'error');
    return;
  }

  const message = messages.value.find((m: any) => m.id === messageId);
  if (!message || message.role !== MessageRole.ASSISTANT) return;

  const messageIndex = messages.value.findIndex((m: any) => m.id === messageId);
  if (messageIndex <= 0) return;

  const userMessage = messages.value[messageIndex - 1];
  if (userMessage.role !== MessageRole.USER) return;

  // 提取重试位置之前的历史消息（用于上下文记忆）
  const MAX_HISTORY_ROUNDS = 20;
  const priorMessages = messages.value
    .slice(0, messageIndex - 1) // 不包含当前 user 消息和要重试的 assistant 消息
    .filter(
      (m: any) =>
        m.role === MessageRole.USER || m.role === MessageRole.ASSISTANT,
    )
    .filter((m: any) => m.content?.text)
    .slice(-(MAX_HISTORY_ROUNDS * 2))
    .map((m: any) => ({ role: m.role, content: m.content.text }));

  // 重置消息状态
  chatStore.updateMessage(messageId, {
    isError: false,
    errorMessage: undefined,
    isStreaming: true,
    isEnd: true,
    content: { type: MessageType.TEXT, text: "" },
  });

  currentStreamingMessageId.value = messageId;
  chatStore.startStreaming();
  abortController.value = new AbortController();

  try {
    const stream = chatApi.streamChat(
      {
        message: userMessage.content.text || "",
        conversationId: currentConversation.value?.id,
        model: settings.value.defaultModel,
        stream: true,
        history: priorMessages,
      },
      abortController.value.signal,
    );

    let fullText = "";
    let reasoningText = "";
    let isInReasoning = false;

    for await (const chunk of stream) {
      if (abortController.value?.signal.aborted) break;

      if (chunk.type === "reasoning") {
        // 深度思考内容
        if (!isInReasoning) {
          // 开始深度思考块
          reasoningText = "";
          isInReasoning = true;
          fullText += "<think>\n";
        }
        reasoningText += chunk.text;
        fullText += chunk.text;
      } else {
        // 普通内容
        if (isInReasoning) {
          // 结束深度思考块
          isInReasoning = false;
          fullText += "\n</think>\n";
        }
        fullText += chunk.text;
      }
      chatStore.updateMessageContent(messageId, fullText);
    }

    // 如果最后还在深度思考块中，关闭它
    if (isInReasoning) {
      fullText += "\n</think>";
    }

    if (!abortController.value?.signal.aborted) {
      chatStore.updateMessage(messageId, {
        isStreaming: false,
        content: {
          type: MessageType.TEXT,
          text: fullText,
        },
      });
    }
  } catch (error: any) {
    if (error.name !== "AbortError") {
      chatStore.updateMessage(messageId, {
        isStreaming: false,
        isError: true,
        errorMessage: error.message || "请求失败",
      });
    }
  } finally {
    chatStore.stopStreaming();
    currentStreamingMessageId.value = null;
  }
}

function handleRegenerate(messageId: string) {
  handleRetry(messageId);
}

function handleSuggestion(suggestion: Suggestion) {
  handleSend(suggestion.text, [], { systemPrompt: suggestion.systemPrompt });
}

function focusInput() {
  chatInputRef.value?.focus();
}

defineExpose({
  focusInput,
  messageListRef,
});

watch(
  () => currentConversation.value?.id,
  () => {
    nextTick(() => {
      focusInput();
    });
  },
);
</script>

<style lang="scss" scoped>
.chat-main {
  display: flex;
  flex-direction: column;
  flex: 1;
  height: 100vh;
  background: #ffffff;
  overflow: hidden;
  border-radius: 15px;
  min-height: 0;

  .dark & {
    background: #11111b;
  }

  &.wide-mode {
    .input-container {
    //  min-width: 1000px;
    }
  }
}

.input-wrapper {
  flex-shrink: 0;
  padding: 16px 10% 24px;
  background: linear-gradient(to top, white 80%, transparent);

  .dark & {
    background: linear-gradient(to top, #11111b 80%, transparent);
  }
}

.input-container {
  width: 100%;
 // min-width: 1000px;
  // margin: 0 auto;
  transition: max-width 0.3s ease;

  &.wide {
  //  min-width: 1000px;
  }
}
</style>
