import type { ApiResponse, CaptchaResult, ChatMessage, ChatSession, LoginResult, UserProfile } from "../types/api";

const API_BASE = import.meta.env.VITE_API_BASE_URL ?? "http://127.0.0.1:8100/api";
const TOKEN_KEY = "ai-kb-user-token";

export function getToken() {
  return window.localStorage.getItem(TOKEN_KEY);
}

export function saveToken(token: string) {
  window.localStorage.setItem(TOKEN_KEY, token);
}

export function clearToken() {
  window.localStorage.removeItem(TOKEN_KEY);
}

async function request<T>(path: string, init: RequestInit = {}): Promise<T> {
  const headers = new Headers(init.headers);
  headers.set("Content-Type", "application/json");
  const token = getToken();
  if (token) {
    headers.set("Authorization", `Bearer ${token}`);
  }
  const response = await fetch(`${API_BASE}${path}`, { ...init, headers });
  const body = (await response.json()) as ApiResponse<T>;
  if (!response.ok || body.code !== 0) {
    throw new Error(body.message || `${response.status} ${response.statusText}`);
  }
  return body.data;
}

export const api = {
  captcha: () => request<CaptchaResult>("/auth/captcha"),
  sendSms: (phone: string, captchaId: string, captchaCode: string) =>
    request<null>("/auth/sms/send", { method: "POST", body: JSON.stringify({ phone, captchaId, captchaCode }) }),
  login: (phone: string, code: string) =>
    request<LoginResult>("/auth/login", { method: "POST", body: JSON.stringify({ phone, code }) }),
  logout: () => request<null>("/auth/logout", { method: "POST", body: JSON.stringify({}) }),
  profile: () => request<UserProfile>("/user/profile"),
  createSession: () => request<{ sessionId: number }>("/chat/session", { method: "POST", body: JSON.stringify({}) }),
  listSessions: () => request<ChatSession[]>("/chat/session/list"),
  history: (sessionId: number) => request<ChatMessage[]>(`/chat/history?sessionId=${sessionId}`),
  renameSession: (sessionId: number, title: string) =>
    request<ChatSession>("/chat/session/title", { method: "PUT", body: JSON.stringify({ sessionId, title }) }),
  deleteSession: (sessionId: number) => request<null>(`/chat/session/${sessionId}`, { method: "DELETE" }),
  stop: (sessionId: number) => request<null>("/chat/stop", { method: "POST", body: JSON.stringify({ sessionId }) }),
};

export async function streamChat(
  sessionId: number,
  message: string,
  onChunk: (chunk: string) => void,
  onStatus?: (message: string, type: string) => void,
  signal?: AbortSignal,
) {
  const token = getToken();
  const response = await fetch(`${API_BASE}/chat/completions`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      ...(token ? { Authorization: `Bearer ${token}` } : {}),
    },
    body: JSON.stringify({ sessionId, message }),
    signal,
  });
  if (!response.ok || !response.body) {
    const message = await readErrorMessage(response);
    throw new Error(message || "AI 回复连接失败");
  }
  const reader = response.body.getReader();
  const decoder = new TextDecoder("utf-8");
  let buffer = "";
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    buffer += decoder.decode(value, { stream: true });
    const parts = buffer.split("\n\n");
    buffer = parts.pop() ?? "";
    for (const part of parts) {
      const line = part.trim();
      if (!line.startsWith("data:")) continue;
      const payload = line.slice(5).trim();
      if (payload === "[DONE]") return;
      const parsed = JSON.parse(payload) as { type?: string; content?: string; message?: string };
      if (parsed.type === "queued" || parsed.type === "generating") {
        onStatus?.(parsed.message || "", parsed.type);
        continue;
      }
      if (parsed.type === "error") {
        throw new Error(parsed.message || "AI 回复失败");
      }
      if (parsed.content) onChunk(parsed.content);
    }
  }
}

async function readErrorMessage(response: Response) {
  try {
    const body = (await response.json()) as ApiResponse<unknown>;
    return body.message;
  } catch {
    return "";
  }
}
