import { buildSessionKey, init_session_key, parseSessionKey } from "../../../routing/session-key.js";
import { agentExists, getDefaultAgentId, init_resolve_route } from "../../../routing/resolve-route.js";
import { messagesToClientHistory } from "../../../session/client-history.js";
import { computeUserRoundDeleteRange } from "../../../session/user-round-delete.js";
import { respondStartupUnavailable } from "../lib/startup-unavailable.js";
//#region src/gateway/hono/routes/sessions.ts
init_session_key();
init_resolve_route();
function ensureGatewayReadyForSessions(c, service, method) {
	if (service.isGatewayReady()) return null;
	return respondStartupUnavailable(c, method);
}
function registerSessionsRoutes(authenticated, deps) {
	const { service } = deps;
	authenticated.post("/api/sessions", async (c) => {
		const body = await c.req.json().catch(() => ({}));
		const channel = body.channel || "webchat";
		const routingCfg = service.currentConfig;
		let agentId = typeof body.agentId === "string" && body.agentId.trim() ? body.agentId.trim().toLowerCase() : getDefaultAgentId(routingCfg);
		if (!agentExists(agentId, routingCfg)) agentId = getDefaultAgentId(routingCfg);
		if (body.chat_id) {
			const sessionKey = buildSessionKey({
				agentId,
				source: channel,
				accountId: "default",
				peerKind: "direct",
				peerId: body.chat_id
			});
			await service.sessionIndexInstance.saveMessages(sessionKey, []);
			const session = await service.sessions.getSession(sessionKey);
			return c.json({ session }, 201);
		}
		const emptySession = (await service.sessions.listSessions({
			channel,
			limit: 50,
			sortBy: "updatedAt",
			sortOrder: "desc"
		})).items.find((s) => {
			if (s.messageCount !== 0) return false;
			return parseSessionKey(s.key)?.agentId === agentId;
		});
		if (emptySession) {
			const session = await service.sessions.getSession(emptySession.key);
			return c.json({
				session,
				reused: true
			}, 200);
		}
		const chatId = `chat_${Date.now()}`;
		const sessionKey = buildSessionKey({
			agentId,
			source: channel,
			accountId: "default",
			peerKind: "direct",
			peerId: chatId
		});
		await service.sessionIndexInstance.saveMessages(sessionKey, []);
		const session = await service.sessions.getSession(sessionKey);
		return c.json({ session }, 201);
	});
	authenticated.get("/api/sessions", async (c) => {
		const blocked = ensureGatewayReadyForSessions(c, service, "sessions.list");
		if (blocked) return blocked;
		const query = c.req.query();
		const result = await service.sessions.listSessions({
			status: query.status,
			search: query.search,
			channel: query.channel,
			limit: query.limit ? parseInt(query.limit) : void 0,
			offset: query.offset ? parseInt(query.offset) : void 0
		});
		return c.json(result);
	});
	authenticated.get("/api/sessions/stats", async (c) => {
		const result = await service.sessions.stats();
		return c.json(result);
	});
	authenticated.get("/api/sessions/chat-ids", async (c) => {
		const channel = c.req.query("channel");
		const chatIds = await service.sessions.chatIds(channel || void 0);
		return c.json({
			ok: true,
			payload: { chatIds }
		});
	});
	authenticated.get("/api/sessions/:key/run", async (c) => {
		const blocked = ensureGatewayReadyForSessions(c, service, "sessions.run");
		if (blocked) return blocked;
		const key = c.req.param("key");
		if (!await service.sessions.getSession(key)) return c.json({
			ok: false,
			error: "Session not found"
		}, 404);
		return c.json({
			ok: true,
			payload: service.sessions.getActiveRun(key)
		});
	});
	authenticated.get("/api/sessions/:key/agent-config", async (c) => {
		const key = c.req.param("key");
		const payload = await service.sessions.getAgentConfig(key);
		return c.json({
			ok: true,
			payload
		});
	});
	authenticated.patch("/api/sessions/:key/agent-config", async (c) => {
		const key = c.req.param("key");
		const body = await c.req.json().catch(() => ({}));
		const result = await service.sessions.patchAgentConfig(key, body);
		if (!result.ok) return c.json({
			ok: false,
			error: result.error
		}, 400);
		return c.json({ ok: true });
	});
	authenticated.get("/api/sessions/:key/messages", async (c) => {
		const blocked = ensureGatewayReadyForSessions(c, service, "sessions.messages");
		if (blocked) return blocked;
		const key = c.req.param("key");
		const limitRaw = c.req.query("limit");
		const parsedLimit = limitRaw ? Number.parseInt(limitRaw, 10) : void 0;
		const limit = parsedLimit !== void 0 && Number.isFinite(parsedLimit) ? Math.min(500, Math.max(1, parsedLimit)) : void 0;
		const before = c.req.query("before")?.trim();
		const offsetRaw = c.req.query("offset");
		const parsedOffset = offsetRaw ? Number.parseInt(offsetRaw, 10) : 0;
		const offset = Number.isFinite(parsedOffset) ? Math.max(0, parsedOffset) : 0;
		const result = await service.sessions.getMessagePage(key, {
			limit,
			offset,
			...before ? { before } : {}
		});
		if (!result) return c.json({
			ok: false,
			error: "Session not found"
		}, 404);
		const messages = messagesToClientHistory(result.session.messages, { limit });
		return c.json({
			ok: true,
			payload: { messages },
			pagination: result.pagination
		});
	});
	authenticated.get("/api/sessions/:key/history", async (c) => {
		const blocked = ensureGatewayReadyForSessions(c, service, "sessions.history");
		if (blocked) return blocked;
		const key = c.req.param("key");
		const offsetRaw = c.req.query("offset");
		const limitRaw = c.req.query("limit");
		const before = c.req.query("before")?.trim();
		const parsedOffset = offsetRaw ? Number.parseInt(offsetRaw, 10) : 0;
		const parsedLimit = limitRaw ? Number.parseInt(limitRaw, 10) : 50;
		const offset = Number.isFinite(parsedOffset) ? Math.max(0, parsedOffset) : 0;
		const limit = Number.isFinite(parsedLimit) ? Math.min(200, Math.max(1, parsedLimit)) : 50;
		const result = await service.sessions.getMessagePage(key, {
			offset,
			limit,
			...before ? { before } : {}
		});
		if (!result) return c.json({ error: "Session not found" }, 404);
		return c.json(result);
	});
	authenticated.post("/api/sessions/:key/transcript/context", async (c) => {
		const key = c.req.param("key");
		if (!await service.sessionIndexInstance.getSessionMetadata(key)) return c.json({
			ok: false,
			error: "Session not found"
		}, 404);
		const body = await c.req.json().catch(() => ({}));
		const id = typeof body.id === "string" && body.id.trim() ? body.id.trim() : void 0;
		const text = typeof body.text === "string" ? body.text : void 0;
		const data = body.data !== void 0 && typeof body.data === "object" && body.data !== null && !Array.isArray(body.data) ? body.data : void 0;
		await service.sessionIndexInstance.appendTranscriptContextEntry(key, {
			id,
			text,
			data
		});
		return c.json({ ok: true });
	});
	authenticated.get("/api/sessions/:key/compaction/checkpoints", async (c) => {
		const key = c.req.param("key");
		if (!await service.sessionIndexInstance.getSessionMetadata(key)) return c.json({
			ok: false,
			error: "Session not found"
		}, 404);
		const checkpoints = await service.sessions.listCompactionCheckpoints(key);
		return c.json({
			ok: true,
			payload: { checkpoints }
		});
	});
	authenticated.get("/api/sessions/:key/compaction/checkpoints/:checkpointId", async (c) => {
		const key = c.req.param("key");
		const checkpointId = c.req.param("checkpointId");
		const checkpoint = await service.sessions.getCompactionCheckpoint(key, checkpointId);
		if (!checkpoint) return c.json({
			ok: false,
			error: "Checkpoint not found"
		}, 404);
		return c.json({
			ok: true,
			payload: { checkpoint }
		});
	});
	authenticated.post("/api/sessions/:key/compaction/restore", async (c) => {
		const key = c.req.param("key");
		const body = await c.req.json().catch(() => ({}));
		const checkpointId = typeof body.checkpointId === "string" ? body.checkpointId.trim() : "";
		if (!checkpointId) return c.json({
			ok: false,
			error: "checkpointId required"
		}, 400);
		try {
			await service.sessions.restoreCompactionCheckpoint(key, checkpointId);
		} catch (err) {
			const msg = err instanceof Error ? err.message : String(err);
			if (msg.includes("not found") || msg.includes("Invalid")) return c.json({
				ok: false,
				error: msg
			}, 404);
			return c.json({
				ok: false,
				error: msg
			}, 500);
		}
		const session = await service.sessions.getSession(key);
		if (!session) return c.json({
			ok: false,
			error: "Session not found"
		}, 404);
		return c.json({
			ok: true,
			session
		});
	});
	authenticated.post("/api/sessions/:key/compaction/run", async (c) => {
		const key = c.req.param("key");
		if (!await service.sessions.getSession(key)) return c.json({
			ok: false,
			error: "Session not found"
		}, 404);
		const body = await c.req.json().catch(() => ({}));
		const instructions = typeof body.instructions === "string" ? body.instructions : void 0;
		const force = typeof body.force === "boolean" ? body.force : true;
		const result = await service.sessions.runCompaction(key, {
			instructions,
			force
		});
		return c.json({
			ok: true,
			payload: { result }
		});
	});
	authenticated.get("/api/sessions/:key", async (c) => {
		const key = c.req.param("key");
		const includeRaw = c.req.query("include") ?? "";
		const includeSet = new Set(includeRaw.split(",").map((s) => s.trim()).filter(Boolean));
		const includeTranscript = includeSet.has("transcript");
		const includeTranscriptRows = includeSet.has("transcriptRows");
		const offsetRaw = c.req.query("offset");
		const limitRaw = c.req.query("limit");
		if (offsetRaw !== void 0 || limitRaw !== void 0) {
			const blocked = ensureGatewayReadyForSessions(c, service, "sessions.history");
			if (blocked) return blocked;
			const parsedOffset = offsetRaw ? Number.parseInt(offsetRaw, 10) : 0;
			const parsedLimit = limitRaw ? Number.parseInt(limitRaw, 10) : 50;
			const offset = Number.isFinite(parsedOffset) ? Math.max(0, parsedOffset) : 0;
			const limit = Number.isFinite(parsedLimit) ? Math.min(200, Math.max(1, parsedLimit)) : 50;
			const result = await service.sessions.getMessagePage(key, {
				offset,
				limit,
				includeTranscriptSummary: includeTranscript,
				includeTranscriptRows
			});
			if (!result) return c.json({ error: "Session not found" }, 404);
			return c.json(result);
		}
		const session = await service.sessions.getSession(key, {
			includeTranscriptSummary: includeTranscript,
			includeTranscriptRows
		});
		if (!session) return c.json({ error: "Session not found" }, 404);
		return c.json({ session });
	});
	authenticated.patch("/api/sessions/:key", async (c) => {
		const key = c.req.param("key");
		const body = await c.req.json().catch(() => ({}));
		const patch = {};
		if (typeof body.name === "string") patch.name = body.name;
		if (Array.isArray(body.tags)) patch.tags = body.tags;
		if (typeof body.replaceTags === "boolean") patch.replaceTags = body.replaceTags;
		if (body.customData !== void 0 && typeof body.customData === "object" && body.customData !== null) patch.customData = body.customData;
		const result = await service.sessions.patch(key, patch);
		if (result.ok === false) return c.json({
			ok: false,
			error: result.error
		}, 404);
		const session = await service.sessions.getSession(key);
		return c.json({
			ok: true,
			session
		});
	});
	authenticated.get("/api/sessions/:key/export", async (c) => {
		const key = c.req.param("key");
		const format = c.req.query("format") || "json";
		const result = await service.sessions.export(key, format);
		return c.json(result);
	});
	authenticated.delete("/api/sessions/:key/messages", async (c) => {
		const key = c.req.param("key");
		const body = await c.req.json().catch(() => ({}));
		const loaded = await service.sessionIndexInstance.loadMessages(key);
		if (!loaded) return c.json({ error: "Session not found" }, 404);
		let startIndex = typeof body.startIndex === "number" ? body.startIndex : -1;
		let count = typeof body.count === "number" ? body.count : 0;
		const userRoundIndex = typeof body.userRoundIndex === "number" ? body.userRoundIndex : void 0;
		if (userRoundIndex !== void 0) {
			const range = computeUserRoundDeleteRange(loaded, userRoundIndex);
			if (!range) return c.json({ error: "User round index out of range" }, 400);
			startIndex = range.startIndex;
			count = range.count;
		}
		if (startIndex < 0 || count <= 0) return c.json({ error: "Invalid startIndex or count" }, 400);
		if (startIndex >= loaded.length) return c.json({ error: "Index out of range" }, 400);
		const deleteCount = Math.min(count, loaded.length - startIndex);
		const next = loaded.slice(0, startIndex).concat(loaded.slice(startIndex + deleteCount));
		await service.sessionIndexInstance.saveMessages(key, next);
		return c.json({
			ok: true,
			deleted: deleteCount
		});
	});
	authenticated.post("/api/sessions/:key/reset", async (c) => {
		const blocked = ensureGatewayReadyForSessions(c, service, "sessions.reset");
		if (blocked) return blocked;
		const key = c.req.param("key");
		const result = await service.sessions.reset(key);
		if (result.ok === false) {
			const status = result.error === "Session not found" ? 404 : 400;
			return c.json({
				ok: false,
				error: result.error
			}, status);
		}
		const session = await service.sessions.getSession(key);
		return c.json({
			ok: true,
			reset: true,
			sessionId: result.sessionId,
			previousSessionId: result.previousSessionId,
			session
		});
	});
	authenticated.delete("/api/sessions/:key", async (c) => {
		const key = c.req.param("key");
		const result = await service.sessions.delete(key);
		return c.json(result);
	});
	authenticated.post("/api/sessions/:key/archive", async (c) => {
		const key = c.req.param("key");
		const result = await service.sessions.archive(key);
		return c.json(result);
	});
	authenticated.post("/api/sessions/:key/unarchive", async (c) => {
		const key = c.req.param("key");
		const result = await service.sessions.unarchive(key);
		return c.json(result);
	});
	authenticated.post("/api/sessions/:key/pin", async (c) => {
		const key = c.req.param("key");
		const result = await service.sessions.pin(key);
		return c.json(result);
	});
	authenticated.post("/api/sessions/:key/unpin", async (c) => {
		const key = c.req.param("key");
		const result = await service.sessions.unpin(key);
		return c.json(result);
	});
	authenticated.post("/api/sessions/:key/rename", async (c) => {
		const key = c.req.param("key");
		const { name } = await c.req.json();
		const result = await service.sessions.rename(key, name);
		return c.json(result);
	});
	authenticated.get("/api/subagents", async (c) => {
		const query = c.req.query();
		const result = await service.sessions.listSubagents({
			limit: query.limit ? parseInt(query.limit) : void 0,
			offset: query.offset ? parseInt(query.offset) : void 0
		});
		return c.json(result);
	});
	authenticated.get("/api/subagents/:key", async (c) => {
		const key = c.req.param("key");
		if (!key.startsWith("subagent:")) return c.json({ error: "Not a subagent session" }, 400);
		const includeRaw = c.req.query("include") ?? "";
		const includeSet = new Set(includeRaw.split(",").map((s) => s.trim()).filter(Boolean));
		const session = await service.sessions.getSession(key, {
			includeTranscriptSummary: includeSet.has("transcript"),
			includeTranscriptRows: includeSet.has("transcriptRows")
		});
		if (!session) return c.json({ error: "Subagent session not found" }, 404);
		return c.json({ session });
	});
}
//#endregion
export { registerSessionsRoutes };

//# sourceMappingURL=sessions.js.map