/**
 * Monitoring and Error Tracking Utilities
 *
 * Provides centralized functions for tracking errors, performance, and events
 * across the application using Sentry.
 */

import * as Sentry from '@sentry/nextjs';

/**
 * Track a custom event/breadcrumb in Sentry
 */
export function trackEvent(
  category: string,
  message: string,
  level: 'info' | 'warning' | 'error' = 'info',
  data?: Record<string, any>
) {
  Sentry.addBreadcrumb({
    category,
    message,
    level,
    data,
  });
}

/**
 * Track application deployment
 */
export function trackDeployment(version: string, environment: string) {
  Sentry.addBreadcrumb({
    category: 'deployment',
    message: `Deployed version ${version} to ${environment}`,
    level: 'info',
    data: { version, environment },
  });

  // Set deployment context
  Sentry.setContext('deployment', {
    version,
    environment,
    timestamp: new Date().toISOString(),
  });
}

/**
 * Track database query performance
 */
export function trackDatabaseQuery(
  query: string,
  duration: number,
  success: boolean = true
) {
  const level = duration > 1000 ? 'warning' : 'info';

  Sentry.addBreadcrumb({
    category: 'database',
    message: query,
    level,
    data: {
      duration,
      success,
      slow: duration > 1000,
    },
  });

  // Alert on very slow queries
  if (duration > 5000) {
    Sentry.captureMessage(`Slow database query: ${query}`, {
      level: 'warning',
      tags: {
        query_type: 'slow',
        duration,
      },
    });
  }
}

/**
 * Track API call performance
 */
export function trackAPICall(
  endpoint: string,
  method: string,
  duration: number,
  status: number
) {
  const level = status >= 500 ? 'error' : status >= 400 ? 'warning' : 'info';

  Sentry.addBreadcrumb({
    category: 'api',
    message: `${method} ${endpoint} - ${status}`,
    level,
    data: {
      endpoint,
      method,
      duration,
      status,
    },
  });

  // Alert on API errors
  if (status >= 500) {
    Sentry.captureMessage(`API error: ${method} ${endpoint}`, {
      level: 'error',
      tags: {
        endpoint,
        method,
        status,
      },
    });
  }
}

/**
 * Track user authentication events
 */
export function trackAuth(
  event: 'login' | 'logout' | 'signup' | 'oauth' | 'password_reset',
  success: boolean,
  userId?: string,
  metadata?: Record<string, any>
) {
  Sentry.addBreadcrumb({
    category: 'auth',
    message: `Authentication: ${event} - ${success ? 'success' : 'failed'}`,
    level: success ? 'info' : 'warning',
    data: {
      event,
      success,
      userId,
      ...metadata,
    },
  });

  // Set user context if available
  if (userId) {
    Sentry.setUser({ id: userId });
  }

  // Alert on authentication failures
  if (!success && event === 'login') {
    Sentry.captureMessage('Failed login attempt', {
      level: 'warning',
      tags: {
        event,
        success,
      },
    });
  }
}

/**
 * Track payment events
 */
export function trackPayment(
  event: 'checkout_started' | 'payment_succeeded' | 'payment_failed' | 'subscription_created',
  amount?: number,
  currency?: string,
  metadata?: Record<string, any>
) {
  const level = event.includes('failed') ? 'error' : 'info';

  Sentry.addBreadcrumb({
    category: 'payment',
    message: `Payment: ${event}`,
    level,
    data: {
      event,
      amount,
      currency,
      ...metadata,
    },
  });

  // Alert on payment failures
  if (event === 'payment_failed') {
    Sentry.captureMessage('Payment failed', {
      level: 'warning',
      tags: {
        event,
        amount,
        currency,
      },
    });
  }
}

/**
 * Track demo booking events
 */
export function trackDemoBooking(
  event: 'form_viewed' | 'form_submitted' | 'booking_confirmed' | 'booking_failed',
  metadata?: Record<string, any>
) {
  const level = event === 'booking_failed' ? 'error' : 'info';

  Sentry.addBreadcrumb({
    category: 'demo_booking',
    message: `Demo booking: ${event}`,
    level,
    data: {
      event,
      ...metadata,
    },
  });
}

/**
 * Track custom business metrics
 */
export function trackMetric(
  name: string,
  value: number,
  unit: string = 'count',
  tags?: Record<string, string>
) {
  Sentry.addBreadcrumb({
    category: 'metric',
    message: `${name}: ${value} ${unit}`,
    level: 'info',
    data: {
      name,
      value,
      unit,
      tags,
    },
  });
}

/**
 * Capture exception with context
 */
export function captureException(
  error: Error,
  context?: {
    level?: 'fatal' | 'error' | 'warning' | 'info' | 'debug';
    tags?: Record<string, string>;
    user?: { id?: string; email?: string; username?: string };
    extra?: Record<string, any>;
  }
) {
  Sentry.captureException(error, {
    level: context?.level || 'error',
    tags: context?.tags,
    user: context?.user,
    extra: context?.extra,
  });
}

/**
 * Capture message with context
 */
export function captureMessage(
  message: string,
  level: 'fatal' | 'error' | 'warning' | 'info' | 'debug' = 'info',
  context?: {
    tags?: Record<string, string>;
    extra?: Record<string, any>;
  }
) {
  Sentry.captureMessage(message, {
    level,
    tags: context?.tags,
    extra: context?.extra,
  });
}

/**
 * Set user context for error tracking
 */
export function setUser(user: {
  id?: string;
  email?: string;
  username?: string;
  [key: string]: any;
} | null) {
  Sentry.setUser(user);
}

/**
 * Set custom tags for error tracking
 */
export function setTags(tags: Record<string, string>) {
  Sentry.setTags(tags);
}

/**
 * Set custom context for error tracking
 */
export function setContext(name: string, context: Record<string, any>) {
  Sentry.setContext(name, context);
}

/**
 * Start a performance transaction
 */
export function startTransaction(name: string, op: string = 'custom') {
  return Sentry.startTransaction({
    name,
    op,
  });
}

/**
 * Measure function execution time
 */
export async function measurePerformance<T>(
  name: string,
  fn: () => Promise<T>,
  metadata?: Record<string, any>
): Promise<T> {
  const transaction = Sentry.startTransaction({
    name,
    op: 'function',
    data: metadata,
  });

  try {
    const result = await fn();
    transaction.setStatus('ok');
    return result;
  } catch (error) {
    transaction.setStatus('internal_error');
    throw error;
  } finally {
    transaction.finish();
  }
}

/**
 * Track page view (for client-side analytics)
 */
export function trackPageView(path: string, locale?: string) {
  Sentry.addBreadcrumb({
    category: 'navigation',
    message: `Page view: ${path}`,
    level: 'info',
    data: {
      path,
      locale,
      timestamp: new Date().toISOString(),
    },
  });
}

/**
 * Track form submission
 */
export function trackFormSubmission(
  formName: string,
  success: boolean,
  errors?: Record<string, string>
) {
  Sentry.addBreadcrumb({
    category: 'form',
    message: `Form submission: ${formName} - ${success ? 'success' : 'failed'}`,
    level: success ? 'info' : 'warning',
    data: {
      formName,
      success,
      errors,
    },
  });
}

/**
 * Track feature flag usage
 */
export function trackFeatureFlag(
  flag: string,
  enabled: boolean,
  userId?: string
) {
  Sentry.addBreadcrumb({
    category: 'feature_flag',
    message: `Feature flag: ${flag} = ${enabled}`,
    level: 'info',
    data: {
      flag,
      enabled,
      userId,
    },
  });
}

/**
 * Track A/B test variant
 */
export function trackABTest(
  testName: string,
  variant: string,
  userId?: string
) {
  Sentry.addBreadcrumb({
    category: 'ab_test',
    message: `A/B test: ${testName} = ${variant}`,
    level: 'info',
    data: {
      testName,
      variant,
      userId,
    },
  });
}
