import { resolveFridayNextConfig } from "../../config.js";
import { getHostOpenClawConfigSnapshot } from "../../host-config.js";
import { getFridayNextRuntime } from "../../runtime.js";
import { accountExists, requireAccountId } from "../../sync/account-identity.js";
import { sessionBelongsToAccount } from "../../sync/session-key.js";
import { readSince, upsertEvents } from "../../sync/transcript-store.js";
import { extractBearerToken } from "../middleware/auth.js";
import { readJsonBody } from "../middleware/body.js";
const VALID_KINDS = new Set([
    "user_message",
    "assistant_message",
    "thought_event",
    "tool_event",
    "outbound_text",
    "outbound_media",
]);
function decodeSessionKeyFromPath(pathname) {
    const prefix = "/friday-next/sessions/";
    if (!pathname.startsWith(prefix))
        return null;
    const rest = pathname.slice(prefix.length);
    const messagesIdx = rest.indexOf("/messages");
    if (messagesIdx < 0)
        return null;
    const encoded = rest.slice(0, messagesIdx);
    if (!encoded)
        return null;
    try {
        return decodeURIComponent(encoded);
    }
    catch {
        return null;
    }
}
export async function handleSessionsMessages(req, res) {
    const url = new URL(req.url ?? "/", "http://localhost");
    const sessionKey = decodeSessionKeyFromPath(url.pathname);
    if (!sessionKey)
        return false;
    if (!extractBearerToken(req)) {
        res.statusCode = 401;
        res.setHeader("Content-Type", "application/json");
        res.end(JSON.stringify({ error: "Unauthorized: bearer token mismatch" }));
        return true;
    }
    const accountId = requireAccountId(req);
    if (!accountId) {
        res.statusCode = 400;
        res.setHeader("Content-Type", "application/json");
        res.end(JSON.stringify({ error: "Missing or invalid X-Account-Id header" }));
        return true;
    }
    const cfg = resolveFridayNextConfig(getHostOpenClawConfigSnapshot(getFridayNextRuntime().config));
    if (!accountExists(cfg.historyDir, accountId)) {
        res.statusCode = 403;
        res.setHeader("Content-Type", "application/json");
        res.end(JSON.stringify({ error: "Unknown account" }));
        return true;
    }
    if (!sessionBelongsToAccount(sessionKey, accountId)) {
        res.statusCode = 403;
        res.setHeader("Content-Type", "application/json");
        res.end(JSON.stringify({ error: "Session does not belong to account" }));
        return true;
    }
    if (req.method === "GET") {
        const since = Math.max(0, Number.parseInt(url.searchParams.get("since") ?? "0", 10) || 0);
        const limit = Math.min(cfg.syncMaxBatchSize, Math.max(1, Number.parseInt(url.searchParams.get("limit") ?? String(cfg.syncMaxBatchSize), 10) || cfg.syncMaxBatchSize));
        const direction = url.searchParams.get("direction") === "desc" ? "desc" : "asc";
        const events = readSince({
            accountId,
            sessionKey,
            sinceSeq: since,
            limit,
            direction,
            historyDir: cfg.historyDir,
        });
        res.statusCode = 200;
        res.setHeader("Content-Type", "application/json");
        res.end(JSON.stringify({ ok: true, accountId, sessionKey, events }));
        return true;
    }
    if (req.method === "POST") {
        const body = (await readJsonBody(req));
        const rawEvents = Array.isArray(body?.events) ? body.events : [];
        if (rawEvents.length > cfg.syncMaxBatchSize) {
            res.statusCode = 400;
            res.setHeader("Content-Type", "application/json");
            res.end(JSON.stringify({ error: `Too many events (max ${cfg.syncMaxBatchSize})` }));
            return true;
        }
        const parsed = rawEvents
            .map((item) => {
            if (!item || typeof item !== "object" || Array.isArray(item))
                return null;
            const o = item;
            const kind = typeof o.kind === "string" ? o.kind : "";
            if (!VALID_KINDS.has(kind))
                return null;
            const clientId = typeof o.clientId === "string" ? o.clientId : accountId;
            const payload = o.payload && typeof o.payload === "object" && !Array.isArray(o.payload)
                ? o.payload
                : {};
            return {
                kind: kind,
                clientId,
                payload,
                messageId: typeof o.messageId === "string" ? o.messageId : undefined,
                lamport: typeof o.lamport === "number" ? o.lamport : undefined,
                ts: typeof o.ts === "number" ? o.ts : undefined,
            };
        })
            .filter((x) => x !== null);
        const result = upsertEvents({
            accountId,
            sessionKey,
            events: parsed,
            historyDir: cfg.historyDir,
        });
        res.statusCode = 200;
        res.setHeader("Content-Type", "application/json");
        res.end(JSON.stringify({
            ok: true,
            accountId,
            sessionKey,
            applied: result.applied,
            events: result.events,
        }));
        return true;
    }
    res.statusCode = 405;
    res.setHeader("Content-Type", "application/json");
    res.end(JSON.stringify({ error: "Method Not Allowed" }));
    return true;
}
