/**
 * Error Handling Module
 * 
 * Centralized error handling for the DailyNotification plugin
 * Maps native exceptions to canonical errors with user-friendly messages
 * 
 * @author Matthew Raymer
 * @version 1.0.0
 */

import { ErrorCode, type ErrorInfo } from './bridge'

export class ErrorHandler {
  
  /**
   * Map native error to canonical error
   */
  mapNativeError(error: unknown): ErrorInfo {
    const errorMessage = (error as { message?: string })?.message || 
                        (error as { toString?: () => string })?.toString?.() || 
                        'Unknown error'
    
    // Map common error patterns
    if (errorMessage.includes('Permission denied')) {
      return {
        code: ErrorCode.PERMISSION_DENIED,
        message: 'Required permission not granted',
        hint: 'Request permission in settings'
      }
    }
    
    if (errorMessage.includes('Channel disabled')) {
      return {
        code: ErrorCode.CHANNEL_DISABLED,
        message: 'Notification channel is disabled',
        hint: 'Enable notifications in settings'
      }
    }
    
    if (errorMessage.includes('Exact alarm')) {
      return {
        code: ErrorCode.EXACT_ALARM_DENIED,
        message: 'Exact alarm permission denied',
        hint: 'Grant exact alarm permission in settings'
      }
    }
    
    if (errorMessage.includes('Doze')) {
      return {
        code: ErrorCode.DOZE_LIMIT,
        message: 'Device in Doze mode',
        hint: 'Expect delays; fallback taken'
      }
    }
    
    if (errorMessage.includes('Invalid time')) {
      return {
        code: ErrorCode.INVALID_TIME,
        message: 'Invalid time format',
        hint: 'Use 24-hour HH:mm format'
      }
    }
    
    if (errorMessage.includes('Title too long')) {
      return {
        code: ErrorCode.TITLE_TOO_LONG,
        message: 'Title exceeds 100 characters',
        hint: 'Trim title to 100 characters or less'
      }
    }
    
    if (errorMessage.includes('Body too long')) {
      return {
        code: ErrorCode.BODY_TOO_LONG,
        message: 'Body exceeds 500 characters',
        hint: 'Trim body to 500 characters or less'
      }
    }
    
    if (errorMessage.includes('Response too large')) {
      return {
        code: ErrorCode.RESPONSE_TOO_LARGE,
        message: 'Response size exceeds limit',
        hint: 'Response is too large to process'
      }
    }
    
    if (errorMessage.includes('Insecure URL')) {
      return {
        code: ErrorCode.INSECURE_URL,
        message: 'Only HTTPS URLs allowed',
        hint: 'Use secure HTTPS URLs only'
      }
    }
    
    if (errorMessage.includes('Schedule blocked')) {
      return {
        code: ErrorCode.SCHEDULE_BLOCKED,
        message: 'Cannot schedule now',
        hint: 'Check prerequisites and try again'
      }
    }
    
    // Default error
    return {
      code: 'E_UNKNOWN',
      message: errorMessage,
      hint: 'Check logs for more details'
    }
  }
  
  /**
   * Create user-friendly error message
   */
  createUserMessage(error: ErrorInfo): string {
    let message = error.message
    
    if (error.hint) {
      message += ` (${error.hint})`
    }
    
    return message
  }
  
  /**
   * Log error with context
   */
  logError(error: unknown, context = 'DailyNotification'): void {
     
    console.error(`[${context}] Error:`, error)
    
    if ((error as { stack?: string })?.stack) {
       
      console.error(`[${context}] Stack:`, (error as { stack: string }).stack)
    }
  }
  
  /**
   * Handle plugin method error
   */
  handlePluginError(error: unknown, method: string): ErrorInfo {
    this.logError(error, `Plugin.${method}`)
    return this.mapNativeError(error)
  }
}

// Singleton instance
export const errorHandler = new ErrorHandler()

// Utility functions
export function mapNativeError(error: unknown): ErrorInfo {
  return errorHandler.mapNativeError(error)
}

export function createUserMessage(error: ErrorInfo): string {
  return errorHandler.createUserMessage(error)
}

export function logError(error: unknown, context?: string): void {
  errorHandler.logError(error, context)
}

export function handlePluginError(error: unknown, method: string): ErrorInfo {
  return errorHandler.handlePluginError(error, method)
}
