import {
  resolveRemoteSessionId
} from "./chunk-WU2SRT5G.js";
import {
  assertResourceTenant
} from "./chunk-K7DLILHK.js";
import {
  authenticateAndIntercept
} from "./chunk-Z3U5AMUU.js";
import {
  forwardToAnthropic
} from "./chunk-VFSHH6I2.js";
import {
  ensureInitialized
} from "./chunk-JGWAODSJ.js";
import {
  getProxiedTenantId,
  isProxied
} from "./chunk-DZIKCTP6.js";
import {
  subscribe
} from "./chunk-4NRHKTBW.js";
import {
  getSession
} from "./chunk-SEGKFEG5.js";
import {
  getDb,
  init_client
} from "./chunk-TLEKKGH7.js";
import {
  notFound,
  toResponse
} from "./chunk-EZYKRG4W.js";

// src/handlers/anthropic-compat/stream.ts
init_client();
async function prepareSessionStream(request, sessionId) {
  try {
    await ensureInitialized();
    const result = await authenticateAndIntercept(request);
    if (result.kind === "response") {
      const headers = new Headers(result.response.headers);
      headers.set("X-Accel-Buffering", "no");
      return new Response(result.response.body, {
        status: result.response.status,
        headers
      });
    }
    const auth = result.auth;
    const tenantRow = getDb().prepare(`SELECT tenant_id FROM sessions WHERE id = ?`).get(sessionId);
    if (tenantRow) {
      assertResourceTenant(auth, tenantRow.tenant_id, `session ${sessionId} not found`);
    } else {
      const proxyTenant = getProxiedTenantId(sessionId);
      if (proxyTenant !== void 0) {
        assertResourceTenant(auth, proxyTenant, `session ${sessionId} not found`);
      }
    }
    if (isProxied(sessionId)) {
      const localSession = getSession(sessionId);
      if (!localSession) {
        const remoteId = resolveRemoteSessionId(sessionId);
        const res = await forwardToAnthropic(request, `/v1/sessions/${remoteId}/events/stream`);
        const headers = new Headers(res.headers);
        headers.set("X-Accel-Buffering", "no");
        return new Response(res.body, { status: res.status, headers });
      }
    }
    const session = getSession(sessionId);
    if (!session) throw notFound(`session ${sessionId} not found`);
    const url = new URL(request.url);
    const lastEventId = request.headers.get("last-event-id");
    const afterSeq = lastEventId ? Number(lastEventId) : Number(url.searchParams.get("after_seq") ?? "0");
    return {
      afterSeq: Number.isFinite(afterSeq) ? afterSeq : 0,
      subscribeFn: (fromSeq, onEvent) => subscribe(sessionId, fromSeq, onEvent)
    };
  } catch (err) {
    return toResponse(err);
  }
}
async function handleSessionStream(request, sessionId) {
  const result = await prepareSessionStream(request, sessionId);
  if (result instanceof Response) return result;
  const { afterSeq, subscribeFn } = result;
  const encoder = new TextEncoder();
  let controller;
  const stream = new ReadableStream({
    start(c) {
      controller = c;
    }
  });
  const write = (payload) => {
    try {
      controller.enqueue(encoder.encode(payload));
    } catch {
    }
  };
  const sub = subscribeFn(afterSeq, (evt) => {
    write(`id: ${evt.seq}
event: ${evt.type}
data: ${JSON.stringify(evt)}

`);
  });
  const keepalive = setInterval(() => {
    write(`data: {"type":"ping"}

`);
  }, 15e3);
  const abort = () => {
    clearInterval(keepalive);
    sub.unsubscribe();
    try {
      controller.close();
    } catch {
    }
  };
  request.signal.addEventListener("abort", abort);
  return new Response(stream, {
    headers: {
      "Content-Type": "text/event-stream",
      "Cache-Control": "no-cache",
      Connection: "keep-alive",
      "X-Accel-Buffering": "no"
    }
  });
}

export {
  prepareSessionStream,
  handleSessionStream
};
