// api.jsx — thin browser client for Azoth AI backend
const AZOTH_TOKEN_KEY = "azoth.auth.token";

const AzothApi = {
  token() {
    return localStorage.getItem(AZOTH_TOKEN_KEY) || "";
  },
  setToken(token) {
    if (token) localStorage.setItem(AZOTH_TOKEN_KEY, token);
    else localStorage.removeItem(AZOTH_TOKEN_KEY);
  },
  async request(path, options = {}) {
    const headers = { ...(options.headers || {}) };
    if (options.body && !headers["Content-Type"]) headers["Content-Type"] = "application/json";
    const token = AzothApi.token();
    if (token) headers.Authorization = `Bearer ${token}`;
    const res = await fetch(path, { ...options, headers });
    const text = await res.text();
    let data = {};
    if (text) {
      try { data = JSON.parse(text); }
      catch { data = { detail: text }; }
    }
    if (!res.ok) {
      const msg = data.detail || data.message || `Помилка ${res.status}`;
      throw new Error(Array.isArray(msg) ? msg.map(x => x.msg || x).join("; ") : msg);
    }
    return data;
  },
  register({ displayName, email, password }) {
    return AzothApi.request("/api/register", {
      method: "POST",
      body: JSON.stringify({ display_name: displayName, email, password }),
    });
  },
  login({ email, password }) {
    return AzothApi.request("/api/login", {
      method: "POST",
      body: JSON.stringify({ email, password }),
    });
  },
  logout() {
    return AzothApi.request("/api/logout", { method: "POST" }).catch(() => ({}))
      .finally(() => AzothApi.setToken(""));
  },
  me() {
    return AzothApi.request("/api/me");
  },
  threads() {
    return AzothApi.request("/api/threads?limit=60");
  },
  createThread(title = "Нова бесіда") {
    return AzothApi.request("/api/threads", {
      method: "POST",
      body: JSON.stringify({ title }),
    });
  },
  archiveThread(threadId) {
    return AzothApi.request(`/api/threads/${encodeURIComponent(threadId)}`, { method: "DELETE" });
  },
  history(threadId) {
    return AzothApi.request(`/api/history?thread_id=${encodeURIComponent(threadId)}&limit=80`);
  },
  async streamChat({ message, threadId, search }, handlers = {}) {
    const headers = { "Content-Type": "application/json" };
    const token = AzothApi.token();
    if (token) headers.Authorization = `Bearer ${token}`;
    const res = await fetch("/api/chat-stream", {
      method: "POST",
      headers,
      body: JSON.stringify({ message, thread_id: threadId || null, search }),
    });
    if (!res.ok || !res.body) {
      const text = await res.text();
      throw new Error(text || `Помилка ${res.status}`);
    }
    const reader = res.body.getReader();
    const decoder = new TextDecoder();
    let buffer = "";
    const dispatch = (raw) => {
      const lines = raw.split("\n");
      const event = (lines.find(l => l.startsWith("event:")) || "event: message").slice(6).trim();
      const dataLine = lines.find(l => l.startsWith("data:"));
      if (!dataLine) return;
      let data = {};
      try { data = JSON.parse(dataLine.slice(5).trim()); }
      catch { return; }
      if (handlers[event]) handlers[event](data);
      if (handlers.any) handlers.any(event, data);
    };
    while (true) {
      const { value, done } = await reader.read();
      if (done) break;
      buffer += decoder.decode(value, { stream: true });
      const parts = buffer.split("\n\n");
      buffer = parts.pop() || "";
      parts.forEach(dispatch);
    }
    if (buffer.trim()) dispatch(buffer);
  },
};

Object.assign(window, { AzothApi });
