/**
 * n8n Bridge — Mengo ↔ n8n webhook bridge
 *
 * Fires webhook events from Mengo to n8n workflows. This is the primary way
 * Mengo communicates outbound events to n8n. n8n workflows use "Webhook"
 * trigger nodes to receive these events.
 *
 * Usage:
 *   import { n8nBridge } from '../services/n8n/N8nBridge';
 *   n8nBridge.emit('lead.created', { leadId, email, name }, companyId);
 *
 * The bridge looks up n8n workflows tagged with the company's tag and sends
 * the event to their webhook trigger URLs. If n8n is not configured, the call
 * is a no-op (silent failure, logged).
 */

import { N8N_BASE_URL } from './N8nClient';

// ============================================
// EVENT TYPES
// ============================================

export type MengoEventType =
  // Lead & Contact events
  | 'lead.created'
  | 'lead.updated'
  | 'lead.deleted'
  | 'contact.subscribed'
  | 'contact.tag_added'
  | 'contact.tag_removed'
  // Content events
  | 'content.generated'
  | 'content.published'
  | 'content.failed'
  // Campaign events
  | 'campaign.created'
  | 'campaign.published'
  | 'campaign.completed'
  | 'campaign.failed'
  // Social media events
  | 'social.post.published'
  | 'social.post.failed'
  | 'social.comment_received'
  // Marketing events
  | 'email.sent'
  | 'email.opened'
  | 'email.link_clicked'
  | 'email.bounced'
  | 'sms.sent'
  | 'whatsapp.message_sent'
  // Backup events
  | 'backup.created'
  | 'backup.completed'
  | 'backup.failed'
  // Payment events
  | 'payment.received'
  | 'subscription.created'
  | 'subscription.cancelled'
  // AI events
  | 'ai.generation_completed'
  | 'ai.generation_failed'
  // Custom (anything else)
  | string;

export interface MengoEvent {
  event: MengoEventType;
  companyId: string;
  timestamp: string;
  data: Record<string, any>;
}

// ============================================
// COMPANY TAG HELPER
// ============================================

/**
 * Generate a consistent n8n tag for a company.
 * Tags are used to scope workflows per company in n8n.
 */
export function getCompanyTag(companyId: string): string {
  return `mengo:${companyId}`;
}

// ============================================
// WEBHOOK URL HELPER
// ============================================

/**
 * Build the webhook URL for a Mengo event on the n8n instance.
 * n8n webhook URLs follow the pattern:
 *   {N8N_BASE_URL}/webhook/{path}
 *   {N8N_BASE_URL}/webhook-test/{path}  (for testing)
 *
 * We use a convention of: /webhook/mengo/{event}/{companyId}
 */
export function getWebhookPath(event: MengoEventType, companyId: string): string {
  return `/webhook/mengo/${event}/${companyId}`;
}

export function getWebhookUrl(event: MengoEventType, companyId: string): string {
  return `${N8N_BASE_URL}${getWebhookPath(event, companyId)}`;
}

// ============================================
// BRIDGE CLASS
// ============================================

class N8nBridge {
  /**
   * Emit a Mengo event to n8n.
   *
   * Sends a POST request to the webhook URL for this event + company.
   * If n8n is not configured or unreachable, logs a warning and returns
   * silently (non-blocking).
   */
  async emit(event: MengoEventType, data: Record<string, any>, companyId: string): Promise<void> {
    if (!N8N_BASE_URL) {
      // n8n not configured — skip silently
      return;
    }

    const payload: MengoEvent = {
      event,
      companyId,
      timestamp: new Date().toISOString(),
      data,
    };

    const webhookUrl = getWebhookUrl(event, companyId);

    try {
      const response = await fetch(webhookUrl, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });

      if (!response.ok) {
        // n8n webhook not found is common (no workflow listening for this event)
        // Only log non-404 errors as warnings
        if (response.status !== 404) {
          console.warn(`[N8nBridge] Webhook ${event} returned ${response.status} for company ${companyId}`);
        }
      }
    } catch (error: any) {
      // Network errors — n8n may be down, don't crash Mengo
      console.warn(`[N8nBridge] Failed to emit ${event} for company ${companyId}:`, error.message);
    }
  }

  /**
   * Emit an event to all matching n8n webhook URLs (wildcard — no company filter).
   * Useful for global events like system health, AI generation status, etc.
   */
  async emitGlobal(event: MengoEventType, data: Record<string, any>): Promise<void> {
    if (!N8N_BASE_URL) return;

    const payload = {
      event,
      timestamp: new Date().toISOString(),
      data,
    };

    const webhookUrl = `${N8N_BASE_URL}/webhook/mengo/${event}`;

    try {
      await fetch(webhookUrl, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });
    } catch (error: any) {
      console.warn(`[N8nBridge] Failed to emit global ${event}:`, error.message);
    }
  }
}

export const n8nBridge = new N8nBridge();