import { addWebhook, listWebhooks, getWebhook, deactivateWebhook, getDeliveries, getActiveWebhooksForEvent, appendDelivery, } from '../storage/outbound-webhook-store.js';
import { dispatchToWebhooks, buildSpecLifecyclePayload, } from '../engine/outbound-webhook-dispatcher.js';
// ---------------------------------------------------------------------------
// Public fire-and-forget dispatch (orchestrates storage + engine)
// ---------------------------------------------------------------------------
/**
 * Dispatch a webhook event fire-and-forget.
 * Called from side-effects.ts after status transitions.
 */
export function dispatchWebhookEvent(projectPath, payload) {
    void runDispatch(projectPath, payload).catch(() => {
        /* best-effort — never throw */
    });
}
async function runDispatch(projectPath, payload) {
    const webhooks = await getActiveWebhooksForEvent(projectPath, payload.event);
    await dispatchToWebhooks(webhooks, payload, (delivery) => appendDelivery(projectPath, delivery));
}
export { buildSpecLifecyclePayload };
// ---------------------------------------------------------------------------
// configure_webhook
// ---------------------------------------------------------------------------
export async function handleConfigureWebhook(args) {
    const { projectPath, url, secret, events = [], label } = args;
    if (!url.startsWith('http://') && !url.startsWith('https://')) {
        return {
            content: [{ type: 'text', text: 'Error: url must start with http:// or https://' }],
            isError: true,
        };
    }
    if (!secret || secret.length < 8) {
        return {
            content: [{ type: 'text', text: 'Error: secret must be at least 8 characters.' }],
            isError: true,
        };
    }
    const config = await addWebhook(projectPath, { url, secret, events, label });
    const eventList = events.length > 0 ? events.join(', ') : 'all events';
    return {
        content: [
            {
                type: 'text',
                text: [
                    `Webhook configured successfully.`,
                    `ID: ${config.id}`,
                    `URL: ${config.url}`,
                    `Events: ${eventList}`,
                    `Label: ${config.label ?? '(none)'}`,
                    `Created: ${config.createdAt}`,
                    ``,
                    `Payloads will include header: X-Planu-Signature: sha256=<hmac>`,
                    `Use the same secret to verify the signature on your endpoint.`,
                ].join('\n'),
            },
        ],
        structuredContent: {
            webhookId: config.id,
            url: config.url,
            events: config.events,
            active: config.active,
            createdAt: config.createdAt,
        },
    };
}
// ---------------------------------------------------------------------------
// outbound_webhook_status
// ---------------------------------------------------------------------------
export async function handleOutboundWebhookStatus(args) {
    const { projectPath, webhookId } = args;
    if (webhookId !== undefined) {
        const config = await getWebhook(projectPath, webhookId);
        if (!config) {
            return {
                content: [{ type: 'text', text: `Webhook ${webhookId} not found.` }],
                isError: true,
            };
        }
        const deliveries = await getDeliveries(projectPath, webhookId);
        const lastDelivery = deliveries.at(-1);
        const successCount = deliveries.filter((d) => d.success).length;
        const health = deliveries.length === 0
            ? 'no deliveries yet'
            : successCount === deliveries.length
                ? 'healthy'
                : `failing (${String(successCount)}/${String(deliveries.length)} OK)`;
        const lines = [
            `Webhook: ${config.id}`,
            `URL: ${config.url}`,
            `Label: ${config.label ?? '(none)'}`,
            `Status: ${config.active ? 'active' : 'inactive'}`,
            `Events: ${config.events.length > 0 ? config.events.join(', ') : 'all'}`,
            `Health: ${health}`,
            `Total deliveries: ${String(deliveries.length)}`,
        ];
        if (lastDelivery !== undefined) {
            lines.push(``, `Last delivery:`, `  At: ${lastDelivery.deliveredAt}`, `  Event: ${lastDelivery.event}`, `  HTTP ${String(lastDelivery.statusCode)} — ${lastDelivery.latencyMs}ms`, `  ${lastDelivery.success ? 'OK' : `FAILED: ${lastDelivery.error ?? 'unknown'}`}`);
        }
        return {
            content: [{ type: 'text', text: lines.join('\n') }],
            structuredContent: { config, lastDelivery: lastDelivery ?? null, health },
        };
    }
    // List all webhooks
    const configs = await listWebhooks(projectPath);
    if (configs.length === 0) {
        return {
            content: [
                {
                    type: 'text',
                    text: [
                        'No outbound webhooks configured.',
                        '',
                        'Use configure_webhook to register an endpoint.',
                    ].join('\n'),
                },
            ],
        };
    }
    const lines = [`Outbound webhooks (${String(configs.length)} total):`];
    for (const c of configs) {
        const deliveries = await getDeliveries(projectPath, c.id);
        const successCount = deliveries.filter((d) => d.success).length;
        const health = deliveries.length === 0
            ? 'no deliveries'
            : successCount === deliveries.length
                ? 'healthy'
                : 'failing';
        lines.push(``, `  [${c.active ? 'active' : 'inactive'}] ${c.id} — ${c.url}`, `  Events: ${c.events.length > 0 ? c.events.join(', ') : 'all'}`, `  Health: ${health} (${String(successCount)}/${String(deliveries.length)} OK)`);
    }
    return {
        content: [{ type: 'text', text: lines.join('\n') }],
        structuredContent: { total: configs.length, webhooks: configs },
    };
}
// ---------------------------------------------------------------------------
// remove_webhook
// ---------------------------------------------------------------------------
export async function handleRemoveWebhook(args) {
    const { projectPath, webhookId } = args;
    const updated = await deactivateWebhook(projectPath, webhookId);
    if (updated === null) {
        return {
            content: [{ type: 'text', text: `Webhook ${webhookId} not found.` }],
            isError: true,
        };
    }
    return {
        content: [
            {
                type: 'text',
                text: [
                    `Webhook ${webhookId} deactivated.`,
                    `URL: ${updated.url}`,
                    `It will no longer receive events.`,
                ].join('\n'),
            },
        ],
        structuredContent: { webhookId, deactivated: true },
    };
}
//# sourceMappingURL=outbound-webhook-handler.js.map