import { constantTimeEquals, parseJsonRecord, readBearerOrHeaderToken, readTextBodyWithinLimit } from '../helpers.js';
function readRecord(value) {
    return value && typeof value === 'object' ? value : null;
}
function readString(value) {
    return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;
}
export async function handleIMessageSurfaceWebhook(req, context) {
    const configuredToken = String(context.configManager.get('surfaces.imessage.token') ?? '')
        || await context.serviceRegistry.resolveSecret('imessage', 'primary')
        || process.env.IMESSAGE_BRIDGE_TOKEN
        || '';
    if (configuredToken) {
        const providedToken = readBearerOrHeaderToken(req, 'x-goodvibes-imessage-token');
        if (!constantTimeEquals(configuredToken, providedToken)) {
            return Response.json({ error: 'Unauthorized' }, { status: 401 });
        }
    }
    const rawBody = await readTextBodyWithinLimit(req);
    if (rawBody instanceof Response)
        return rawBody;
    const body = parseJsonRecord(rawBody);
    if (body instanceof Response)
        return body;
    const payload = readRecord(body);
    if (!payload)
        return Response.json({ error: 'Invalid JSON body' }, { status: 400 });
    const chatId = readString(payload.chatId) ?? readString(payload.conversationId) ?? readString(payload.source);
    const message = readString(payload.message) ?? readString(payload.text) ?? '';
    if (!chatId)
        return Response.json({ error: 'Missing chatId' }, { status: 400 });
    const policy = await context.authorizeSurfaceIngress({
        surface: 'imessage',
        userId: chatId,
        channelId: chatId,
        groupId: chatId,
        threadId: readString(payload.threadId),
        conversationKind: readString(payload.threadId) ? 'thread' : 'direct',
        text: message,
        mentioned: true,
        metadata: payload,
    });
    if (!policy.allowed) {
        return Response.json({ error: `Blocked by channel policy: ${policy.reason}` }, { status: 403 });
    }
    const binding = await context.routeBindings.upsertBinding({
        kind: readString(payload.threadId) ? 'thread' : 'channel',
        surfaceKind: 'imessage',
        surfaceId: readString(payload.account) ?? readString(context.configManager.get('surfaces.imessage.account')) ?? 'imessage',
        externalId: readString(payload.threadId) ?? chatId,
        channelId: chatId,
        threadId: readString(payload.threadId),
        title: chatId,
        metadata: { ...payload },
    });
    if (!message) {
        return Response.json({
            acknowledged: true,
            queued: false,
            outcome: 'ignored',
            reason: 'no-actionable-text',
            bindingId: binding.id,
        });
    }
    const submission = await context.sessionBroker.submitMessage({
        routeId: binding.id,
        surfaceKind: 'imessage',
        surfaceId: binding.surfaceId,
        externalId: binding.externalId,
        threadId: binding.threadId ?? binding.channelId,
        userId: chatId,
        displayName: chatId,
        title: chatId,
        body: message,
        metadata: payload,
    });
    if (submission.mode === 'continued-live') {
        return Response.json({ acknowledged: true, continued: true, sessionId: submission.session.id, agentId: submission.activeAgentId ?? null });
    }
    const spawnResult = context.trySpawnAgent({ mode: 'spawn', task: submission.task }, 'handleIMessageSurfaceWebhook', submission.session.id);
    if (spawnResult instanceof Response)
        return spawnResult;
    await context.sessionBroker.bindAgent(submission.session.id, spawnResult.id);
    context.queueSurfaceReplyFromBinding(submission.routeBinding ?? binding, {
        agentId: spawnResult.id,
        task: message,
        sessionId: submission.session.id,
    });
    return Response.json({ acknowledged: true, queued: true, bindingId: binding.id, sessionId: submission.session.id, agentId: spawnResult.id });
}
