import { resolveAccountIdFromRequest } from "../../sync/account-identity.js";
import { getTranscriptStore } from "../../sync/transcript-store.js";
import { extractBearerToken } from "../middleware/auth.js";
import { readJsonBody } from "../middleware/body.js";
const allowedKinds = new Set([
    "user_message",
    "assistant_message",
    "thought_event",
    "tool_event",
    "outbound_text",
    "outbound_media",
    "sync_upsert",
]);
function sessionKeyFromPath(pathname) {
    const prefix = "/friday-next/sessions/";
    const suffix = "/messages";
    if (!pathname.startsWith(prefix) || !pathname.endsWith(suffix))
        return "";
    return decodeURIComponent(pathname.slice(prefix.length, -suffix.length));
}
function parseEvent(raw, accountId) {
    if (!raw || typeof raw !== "object" || Array.isArray(raw))
        return null;
    const obj = raw;
    const kind = typeof obj.kind === "string" && allowedKinds.has(obj.kind)
        ? obj.kind
        : null;
    if (!kind)
        return null;
    const payload = obj.payload && typeof obj.payload === "object" && !Array.isArray(obj.payload)
        ? obj.payload
        : null;
    if (!payload)
        return null;
    return {
        eventId: typeof obj.eventId === "string" ? obj.eventId.trim() : undefined,
        clientId: typeof obj.clientId === "string" && obj.clientId.trim() ? obj.clientId.trim() : accountId,
        kind,
        payload,
        ts: typeof obj.ts === "number" ? obj.ts : undefined,
        lamportTs: typeof obj.lamportTs === "number" ? obj.lamportTs : undefined,
    };
}
export async function handleSessionMessagesPost(req, res) {
    if (req.method !== "POST") {
        res.statusCode = 405;
        res.setHeader("Content-Type", "application/json");
        res.end(JSON.stringify({ error: "Method Not Allowed" }));
        return true;
    }
    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 = resolveAccountIdFromRequest(req);
    if (!accountId) {
        res.statusCode = 403;
        res.setHeader("Content-Type", "application/json");
        res.end(JSON.stringify({ error: "Unknown or missing X-Account-Id" }));
        return true;
    }
    const url = new URL(req.url ?? "/", "http://localhost");
    const sessionKey = sessionKeyFromPath(url.pathname);
    if (!sessionKey) {
        res.statusCode = 400;
        res.setHeader("Content-Type", "application/json");
        res.end(JSON.stringify({ error: "Missing session key in path" }));
        return true;
    }
    if (!sessionKey.includes(`friday:account:${accountId}:`) && !sessionKey.startsWith("friday:direct:")) {
        res.statusCode = 403;
        res.setHeader("Content-Type", "application/json");
        res.end(JSON.stringify({ error: "Session does not belong to account" }));
        return true;
    }
    const body = await readJsonBody(req, 8 * 1024 * 1024);
    const rawEvents = Array.isArray(body?.events) ? body.events : [];
    const events = rawEvents.map((e) => parseEvent(e, accountId)).filter((e) => e !== null);
    if (events.length !== rawEvents.length) {
        res.statusCode = 400;
        res.setHeader("Content-Type", "application/json");
        res.end(JSON.stringify({ error: "Invalid transcript event batch" }));
        return true;
    }
    const appended = getTranscriptStore().appendEvents(accountId, sessionKey, events);
    res.statusCode = 200;
    res.setHeader("Content-Type", "application/json");
    res.end(JSON.stringify({ ok: true, appended: appended.length, events: appended }));
    return true;
}
