/**
 * Centralized error handling and tracking
 */

import { Context } from '../types/context'
import { logger } from './logger'

export interface ErrorContext {
  userId?: string
  requestId?: string
  resourceId?: string
  operation?: string
  metadata?: Record<string, any>
}

/**
 * Log error to tracking service (Sentry, LogRocket, etc.)
 */
export async function trackError(
  error: Error,
  context?: ErrorContext,
  dbContext?: Context
): Promise<void> {
  // Log to console in development
  logger.error('Error tracked', { error: error.message, stack: error.stack, context })

  // In production, send to error tracking service
  if (process.env.SENTRY_DSN || process.env.ERROR_TRACKING_ENABLED === 'true') {
    try {
      // Send to error tracking service
      // This could be Sentry, LogRocket, or custom service
      await fetch(process.env.ERROR_TRACKING_ENDPOINT || 'https://errors.sankofa.nexus/api/errors', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${process.env.ERROR_TRACKING_API_KEY}`,
        },
        body: JSON.stringify({
          error: {
            message: error.message,
            stack: error.stack,
            name: error.name,
          },
          context,
          timestamp: new Date().toISOString(),
          environment: process.env.NODE_ENV,
        }),
      })
    } catch (trackingError) {
      // Fail silently if tracking fails
      logger.error('Failed to track error', { error: trackingError })
    }
  }

  // Optionally store in database for analysis
  if (dbContext?.db) {
    try {
      await dbContext.db.query(
        `INSERT INTO error_logs (error_message, error_stack, context, created_at)
         VALUES ($1, $2, $3, NOW())`,
        [
          error.message,
          error.stack,
          JSON.stringify(context || {}),
        ]
      )
    } catch (dbError) {
      // Fail silently if database insert fails
      logger.error('Failed to log error to database', { error: dbError })
    }
  }
}

/**
 * Create user-friendly error message
 */
export function getUserFriendlyError(error: Error): string {
  // Map technical errors to user-friendly messages
  const errorMessages: Record<string, string> = {
    'NetworkError': 'Unable to connect to the server. Please check your connection and try again.',
    'AuthenticationError': 'Your session has expired. Please log in again.',
    'PermissionDenied': 'You do not have permission to perform this action.',
    'ResourceNotFound': 'The requested resource was not found.',
    'ValidationError': 'The provided data is invalid. Please check your input and try again.',
  }

  // Check error name first
  if (errorMessages[error.name]) {
    return errorMessages[error.name]
  }

  // Check error message patterns
  if (error.message.includes('network')) {
    return errorMessages.NetworkError
  }
  if (error.message.includes('authentication') || error.message.includes('unauthorized')) {
    return errorMessages.AuthenticationError
  }
  if (error.message.includes('permission') || error.message.includes('forbidden')) {
    return errorMessages.PermissionDenied
  }
  if (error.message.includes('not found')) {
    return errorMessages.ResourceNotFound
  }

  // Default to generic message
  return 'An unexpected error occurred. Please try again or contact support if the problem persists.'
}

/**
 * Create error response for API
 */
export function createErrorResponse(
  error: Error,
  statusCode: number = 500,
  context?: ErrorContext
) {
  return {
    error: {
      message: getUserFriendlyError(error),
      code: error.name || 'INTERNAL_ERROR',
      statusCode,
      ...(process.env.NODE_ENV === 'development' && {
        details: error.message,
        stack: error.stack,
      }),
    },
    context,
    timestamp: new Date().toISOString(),
  }
}

