/**
 * SSE 工具函数
 * 用于 AI Chat 等场景的 SSE 连接，支持鉴权 Header
 */

import { getToken, formatToken } from "@/utils/auth";

export interface SSEOptions {
  /** SSE 连接 URL */
  url: string;
  /** 事件回调 */
  onEvent: (eventName: string, data: any) => void;
  /** 错误回调 */
  onError?: (error: Error) => void;
  /** 连接完成回调 */
  onComplete?: () => void;
}

/**
 * 创建带鉴权 Header 的 SSE 连接
 * 返回一个 abort 函数用于手动关闭连接
 */
export async function createSSEConnection(
  options: SSEOptions
): Promise<() => void> {
  const { url, onEvent, onError, onComplete } = options;
  const abortController = new AbortController();

  // 获取鉴权 Header
  const headers: Record<string, string> = {
    Accept: "text/event-stream",
    "Cache-Control": "no-cache"
  };

  const tokenData = getToken();
  if (tokenData?.accessToken) {
    headers["Authorization"] = formatToken(tokenData.accessToken);
  }

  try {
    const response = await fetch(url, {
      method: "GET",
      headers,
      signal: abortController.signal
    });

    if (!response.ok) {
      throw new Error(
        `SSE 连接失败: ${response.status} ${response.statusText}`
      );
    }

    if (!response.body) {
      throw new Error("SSE 响应无 body");
    }

    // 读取 SSE 流
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let buffer = "";

    // 异步读取流
    (async () => {
      try {
        while (true) {
          const { done, value } = await reader.read();

          if (done) {
            console.log("SSE 流结束");
            onComplete?.();
            break;
          }

          buffer += decoder.decode(value, { stream: true });

          // 解析 SSE 消息（以双换行分隔）
          const messages = buffer.split("\n\n");
          buffer = messages.pop() || ""; // 保留未完成的消息

          for (const msg of messages) {
            if (msg.trim()) {
              const { eventName, data } = parseSSEMessage(msg);
              if (eventName && data) {
                // 适配后端返回的嵌套数据格式
                // 后端返回格式: { type: "chat", event: "start", data: {...}, timestamp: "..." }
                // 实际事件类型在 data.event，实际数据在 data.data
                const actualEventName = data.event || eventName;
                const actualData = data.data || data;
                onEvent(actualEventName, actualData);
              }
            }
          }
        }
      } catch (error: any) {
        if (error.name === "AbortError") {
          console.log("SSE 连接已取消");
          return;
        }
        console.error("SSE 读取错误:", error);
        onError?.(error);
      }
    })();
  } catch (error: any) {
    if (error.name === "AbortError") {
      console.log("SSE 连接已取消");
      return () => {};
    }
    console.error("SSE 连接错误:", error);
    onError?.(error);
  }

  // 返回 abort 函数
  return () => {
    abortController.abort();
  };
}

/**
 * 解析 SSE 消息
 */
function parseSSEMessage(rawMessage: string): { eventName: string; data: any } {
  const lines = rawMessage.split("\n");
  let eventName = "message";
  let dataStr = "";

  for (const line of lines) {
    if (line.startsWith("event:")) {
      eventName = line.slice(6).trim();
    } else if (line.startsWith("data:")) {
      dataStr = line.slice(5).trim();
    }
  }

  if (!dataStr) {
    return { eventName, data: null };
  }

  try {
    const data = JSON.parse(dataStr);
    return { eventName, data };
  } catch (e) {
    console.error("SSE 消息解析失败:", dataStr, e);
    return { eventName, data: null };
  }
}
