import { clientId } from "./api.js";

class ChatClient {
  connected = $state(false);
  turn = $state(null); // 最新 turn 快照（任意 session），供活动脊
  currentSessionId = $state(null);
  statsBySession = $state({});
  #socket = null;
  #handlers = new Set();
  #reconnectTimer = null;
  #stopped = false;

  connect() {
    if (this.#socket) return;
    this.#stopped = false;
    clearTimeout(this.#reconnectTimer);
    const scheme = location.protocol === "https:" ? "wss" : "ws";
    const ws = new WebSocket(`${scheme}://${location.host}/ws?client_id=${encodeURIComponent(clientId())}`);
    this.#socket = ws;
    ws.onopen = () => {
      if (this.#socket !== ws) return;
      this.connected = true;
      this.#dispatch({ type: "_open" });
    };
    ws.onerror = () => ws.close();
    ws.onclose = () => {
      if (this.#socket !== ws) return;
      this.connected = false;
      this.#socket = null;
      this.#dispatch({ type: "_close" });
      if (!this.#stopped) this.#reconnectTimer = setTimeout(() => this.connect(), 1800);
    };
    ws.onmessage = (event) => {
      if (this.#socket !== ws) return;
      let frame;
      try { frame = JSON.parse(event.data); } catch { return; }
      if (frame.type === "turn_updated" && frame.snapshot) this.turn = frame.snapshot;
      if (frame.type === "session_stats" && frame.stats?.session_id) {
        this.statsBySession[frame.stats.session_id] = frame.stats;
      }
      this.#dispatch(frame);
    };
  }

  disconnect() {
    this.#stopped = true;
    clearTimeout(this.#reconnectTimer);
    this.#socket?.close();
    this.#socket = null;
    this.connected = false;
  }

  send(frame) {
    if (this.#socket?.readyState === WebSocket.OPEN) {
      this.#socket.send(JSON.stringify(frame));
      return true;
    }
    return false;
  }

  get currentStats() {
    return this.currentSessionId ? this.statsBySession[this.currentSessionId] ?? null : null;
  }

  subscribe(handler) {
    this.#handlers.add(handler);
    return () => this.#handlers.delete(handler);
  }

  #dispatch(frame) {
    for (const handler of this.#handlers) handler(frame);
  }
}

export const chat = new ChatClient();
