/**
 * Monitor: Notifier
 * Sends status change notifications
 */

import axios from 'axios';
import pino from 'pino';
import type { StatusNotification, SubmissionStatus } from '../types';

const logger = pino({ name: 'notifier' });

type NotificationLevel = 'info' | 'success' | 'warning' | 'error';

/**
 * Determine notification level based on status
 */
function getNotificationLevel(status: SubmissionStatus): NotificationLevel {
  switch (status) {
    case 'brand_approved':
    case 'campaign_approved':
    case 'completed':
      return 'success';
    
    case 'brand_failed':
    case 'campaign_failed':
      return 'warning';
    
    case 'manual_review':
      return 'error';
    
    case 'remediation':
      return 'warning';
    
    default:
      return 'info';
  }
}

/**
 * Send a status notification
 */
export async function sendNotification(
  notification: StatusNotification,
  webhookUrl?: string
): Promise<void> {
  const level = getNotificationLevel(notification.status);

  // Always log to console
  logger[level]({
    submissionId: notification.submissionId,
    businessName: notification.businessName,
    status: notification.status,
    message: notification.message,
    details: notification.details,
  }, 'Status notification');

  // Send webhook if URL is configured
  if (webhookUrl) {
    try {
      await sendWebhook(webhookUrl, notification, level);
    } catch (error) {
      logger.error({ error, webhookUrl }, 'Failed to send webhook notification');
    }
  }
}

/**
 * Send webhook notification
 */
async function sendWebhook(
  url: string,
  notification: StatusNotification,
  level: NotificationLevel
): Promise<void> {
  try {
    const payload = {
      ...notification,
      level,
      timestamp: notification.timestamp.toISOString(),
    };

    logger.debug({ url, payload }, 'Sending webhook notification');

    const response = await axios.post(url, payload, {
      headers: {
        'Content-Type': 'application/json',
        'User-Agent': 'A2P-AutoPilot/1.0',
      },
      timeout: 10000, // 10 second timeout
    });

    if (response.status >= 200 && response.status < 300) {
      logger.debug({ url, status: response.status }, 'Webhook notification sent successfully');
    } else {
      logger.warn({ url, status: response.status }, 'Webhook returned non-2xx status');
    }
  } catch (error) {
    if (axios.isAxiosError(error)) {
      logger.error({
        url,
        status: error.response?.status,
        data: error.response?.data,
        message: error.message,
      }, 'Webhook request failed');
    } else {
      logger.error({ error, url }, 'Unknown error sending webhook');
    }
    throw error;
  }
}

/**
 * Send batch notifications (for polling job results)
 */
export async function sendBatchNotifications(
  notifications: Array<{ notification: StatusNotification; webhookUrl?: string }>
): Promise<void> {
  logger.info({ count: notifications.length }, 'Sending batch notifications');

  const results = await Promise.allSettled(
    notifications.map(({ notification, webhookUrl }) =>
      sendNotification(notification, webhookUrl)
    )
  );

  const failed = results.filter(r => r.status === 'rejected').length;
  
  if (failed > 0) {
    logger.warn({ total: notifications.length, failed }, 'Some notifications failed');
  } else {
    logger.info({ count: notifications.length }, 'All notifications sent successfully');
  }
}

/**
 * Format a remediation notification with detailed changes
 */
export function formatRemediationNotification(
  submissionId: string,
  businessName: string,
  failureReason: string,
  fixApplied: string,
  fieldsChanged: Record<string, { old: string; new: string }>
): StatusNotification {
  const changesDescription = Object.entries(fieldsChanged)
    .map(([field, { old, new: newVal }]) => {
      const shortField = field.split('.').pop() || field;
      return `• ${shortField}: "${truncate(old, 50)}" → "${truncate(newVal, 50)}"`;
    })
    .join('\n');

  return {
    submissionId,
    businessName,
    status: 'remediation',
    message: `Auto-remediation in progress`,
    details: `
**Issue Detected:** ${failureReason}

**Fix Applied:** ${fixApplied}

**Changes Made:**
${changesDescription}

The submission has been automatically corrected and will be resubmitted shortly.
    `.trim(),
    timestamp: new Date(),
  };
}

/**
 * Helper to truncate long strings
 */
function truncate(str: string, maxLength: number): string {
  if (str.length <= maxLength) {
    return str;
  }
  return str.substring(0, maxLength - 3) + '...';
}
