/**
 * src/integrations/n8n.ts
 * تكامل n8n — Trigger n8n workflows via webhooks and manage webhook registrations
 */
import { createChildLogger } from '../utils/logger.js';
import { supabase } from '../utils/supabase.js';
const log = createChildLogger('integrations:n8n');
// ─── Workflow Trigger ────────────────────────────────────────────────
/**
 * تشغيل workflow في n8n عبر webhook
 * يرسل البيانات كـ JSON POST request
 */
export async function triggerWorkflow(webhookUrl, data) {
    try {
        log.info({ webhookUrl: webhookUrl.slice(0, 60) + '...', dataKeys: Object.keys(data) }, 'Triggering n8n workflow');
        const response = await fetch(webhookUrl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'User-Agent': 'Muassis-Gateway/0.1.0',
            },
            body: JSON.stringify({
                ...data,
                _source: 'muassis-gateway',
                _timestamp: new Date().toISOString(),
            }),
            signal: AbortSignal.timeout(30_000),
        });
        const responseData = await response.json().catch(() => null);
        if (!response.ok) {
            log.warn({ webhookUrl: webhookUrl.slice(0, 60), status: response.status }, 'n8n webhook returned non-OK status');
            return {
                success: false,
                statusCode: response.status,
                responseData,
                error: `HTTP ${response.status}`,
            };
        }
        log.info({ webhookUrl: webhookUrl.slice(0, 60), status: response.status }, 'n8n workflow triggered successfully');
        return {
            success: true,
            statusCode: response.status,
            responseData,
        };
    }
    catch (err) {
        const errorMsg = err instanceof Error ? err.message : String(err);
        log.error({ webhookUrl: webhookUrl.slice(0, 60), error: errorMsg }, 'Failed to trigger n8n workflow');
        return {
            success: false,
            error: errorMsg,
        };
    }
}
// ─── Webhook Registration ────────────────────────────────────────────
/**
 * تسجيل webhook لحدث معين لمستأجر
 * يُخزن في إعدادات المستأجر في قاعدة البيانات
 */
export async function registerWebhook(tenantId, event, webhookUrl) {
    try {
        // Validate URL
        new URL(webhookUrl);
    }
    catch {
        throw new Error(`Invalid webhook URL: ${webhookUrl}`);
    }
    // Get current tenant settings
    const { data: tenant, error: fetchError } = await supabase
        .from('tenants')
        .select('settings')
        .eq('id', tenantId)
        .single();
    if (fetchError || !tenant) {
        throw new Error(`Tenant not found: ${tenantId}`);
    }
    const settings = tenant.settings ?? {};
    const webhooks = settings['webhooks'] ?? [];
    // Remove existing registration for this event (replace)
    const filtered = webhooks.filter((w) => w['event'] !== event);
    // Add new registration
    filtered.push({
        event,
        webhookUrl,
        isActive: true,
        createdAt: new Date().toISOString(),
    });
    // Update tenant settings
    const { error: updateError } = await supabase
        .from('tenants')
        .update({
        settings: { ...settings, webhooks: filtered },
        updated_at: new Date().toISOString(),
    })
        .eq('id', tenantId);
    if (updateError) {
        throw new Error(`Failed to register webhook: ${updateError.message}`);
    }
    log.info({ tenantId, event, webhookUrl: webhookUrl.slice(0, 60) }, 'Webhook registered');
}
/**
 * إلغاء تسجيل webhook
 */
export async function unregisterWebhook(tenantId, event) {
    const { data: tenant, error: fetchError } = await supabase
        .from('tenants')
        .select('settings')
        .eq('id', tenantId)
        .single();
    if (fetchError || !tenant)
        return;
    const settings = tenant.settings ?? {};
    const webhooks = settings['webhooks'] ?? [];
    const filtered = webhooks.filter((w) => w['event'] !== event);
    await supabase
        .from('tenants')
        .update({
        settings: { ...settings, webhooks: filtered },
        updated_at: new Date().toISOString(),
    })
        .eq('id', tenantId);
    log.info({ tenantId, event }, 'Webhook unregistered');
}
/**
 * سرد جميع الـ webhooks المسجلة لمستأجر
 */
export async function listWebhooks(tenantId) {
    const { data: tenant } = await supabase
        .from('tenants')
        .select('settings')
        .eq('id', tenantId)
        .single();
    if (!tenant)
        return [];
    const settings = tenant.settings ?? {};
    const webhooks = settings['webhooks'] ?? [];
    return webhooks.map((w) => ({
        tenantId,
        event: w['event'],
        webhookUrl: w['webhookUrl'] ?? '',
        isActive: w['isActive'] ?? true,
        createdAt: w['createdAt'] ?? '',
    }));
}
// ─── Event Dispatcher ────────────────────────────────────────────────
/**
 * إطلاق جميع الـ webhooks المسجلة لحدث معين
 * يعمل بالتوازي ولا ينتظر النتائج (fire & forget بشكل آمن)
 */
export async function triggerTenantWebhooks(tenantId, event, data) {
    const registrations = await listWebhooks(tenantId);
    const matching = registrations.filter((r) => r.event === event && r.isActive);
    if (matching.length === 0) {
        log.debug({ tenantId, event }, 'No webhooks registered for this event');
        return [];
    }
    log.info({ tenantId, event, webhookCount: matching.length }, 'Triggering tenant webhooks');
    const results = await Promise.allSettled(matching.map((r) => triggerWorkflow(r.webhookUrl, {
        ...data,
        tenantId,
        event,
    })));
    return results.map((r) => r.status === 'fulfilled'
        ? r.value
        : { success: false, error: r.reason instanceof Error ? r.reason.message : String(r.reason) });
}
//# sourceMappingURL=n8n.js.map