/**
 * Graceful degradation strategies with marine-specific adaptations
 */

import {
  MarineEnvironmentStatus,
  ResilienceEvent,
  ResilienceResult
} from '../types';

import {
  OperationalContext
} from '../types/marine-constants';

/**
 * Service quality level
 */
export enum ServiceQualityLevel {
  /**
   * Full functionality with optimal performance
   */
  OPTIMAL = 'optimal',
  
  /**
   * Full functionality with reduced performance
   */
  REDUCED = 'reduced',
  
  /**
   * Core functionality only
   */
  MINIMAL = 'minimal',
  
  /**
   * Critical functionality only
   */
  CRITICAL = 'critical',
  
  /**
   * Emergency functionality only
   */
  EMERGENCY = 'emergency'
}

/**
 * Feature priority for degradation decisions
 */
export enum FeaturePriority {
  /**
   * Critical for vessel safety
   */
  CRITICAL = 'critical',
  
  /**
   * Essential for operation
   */
  ESSENTIAL = 'essential',
  
  /**
   * Important but can be degraded
   */
  IMPORTANT = 'important',
  
  /**
   * Useful but non-essential
   */
  USEFUL = 'useful',
  
  /**
   * Comfort or convenience only
   */
  COMFORT = 'comfort'
}

/**
 * Degradation strategy configuration
 */
export interface DegradationConfig {
  /**
   * Default service quality level
   */
  defaultQualityLevel: ServiceQualityLevel;
  
  /**
   * Whether to adapt to marine conditions
   */
  adaptToMarineConditions: boolean;
  
  /**
   * Whether to adapt to power status
   */
  powerAware: boolean;
  
  /**
   * Whether to adapt to connectivity quality
   */
  connectivityAware: boolean;
  
  /**
   * Quality level thresholds for different conditions
   */
  qualityThresholds: {
    /**
     * Sea state thresholds
     */
    seaState: {
      rough: ServiceQualityLevel;
      veryRough: ServiceQualityLevel;
    };
    
    /**
     * Power status thresholds
     */
    powerStatus: {
      conservation: ServiceQualityLevel;
      critical: ServiceQualityLevel;
    };
    
    /**
     * Connectivity quality thresholds (0-1)
     */
    connectivityQuality: {
      low: number;
      lowQualityLevel: ServiceQualityLevel;
      veryLow: number;
      veryLowQualityLevel: ServiceQualityLevel;
    };
  };
  
  /**
   * Feature toggles configuration
   */
  featureToggles: {
    /**
     * Whether to enable automatic feature toggling
     */
    autoToggleFeatures: boolean;
    
    /**
     * Minimum priority level for each quality level
     */
    qualityLevelMinPriority: {
      [ServiceQualityLevel.OPTIMAL]: FeaturePriority;
      [ServiceQualityLevel.REDUCED]: FeaturePriority;
      [ServiceQualityLevel.MINIMAL]: FeaturePriority;
      [ServiceQualityLevel.CRITICAL]: FeaturePriority;
      [ServiceQualityLevel.EMERGENCY]: FeaturePriority;
    };
  };
  
  /**
   * Resource limits for different quality levels
   */
  resourceLimits: {
    /**
     * CPU usage percentage (0-100)
     */
    cpu: {
      [ServiceQualityLevel.OPTIMAL]: number;
      [ServiceQualityLevel.REDUCED]: number;
      [ServiceQualityLevel.MINIMAL]: number;
      [ServiceQualityLevel.CRITICAL]: number;
      [ServiceQualityLevel.EMERGENCY]: number;
    };
    
    /**
     * Memory usage percentage (0-100)
     */
    memory: {
      [ServiceQualityLevel.OPTIMAL]: number;
      [ServiceQualityLevel.REDUCED]: number;
      [ServiceQualityLevel.MINIMAL]: number;
      [ServiceQualityLevel.CRITICAL]: number;
      [ServiceQualityLevel.EMERGENCY]: number;
    };
    
    /**
     * Network bandwidth usage (KB/s)
     */
    bandwidth: {
      [ServiceQualityLevel.OPTIMAL]: number;
      [ServiceQualityLevel.REDUCED]: number;
      [ServiceQualityLevel.MINIMAL]: number;
      [ServiceQualityLevel.CRITICAL]: number;
      [ServiceQualityLevel.EMERGENCY]: number;
    };
    
    /**
     * Storage I/O operations per second
     */
    storageIops: {
      [ServiceQualityLevel.OPTIMAL]: number;
      [ServiceQualityLevel.REDUCED]: number;
      [ServiceQualityLevel.MINIMAL]: number;
      [ServiceQualityLevel.CRITICAL]: number;
      [ServiceQualityLevel.EMERGENCY]: number;
    };
  };
}

/**
 * Feature toggle definition
 */
export interface FeatureToggle {
  /**
   * Feature ID
   */
  id: string;
  
  /**
   * Feature name
   */
  name: string;
  
  /**
   * Feature description
   */
  description: string;
  
  /**
   * Feature priority
   */
  priority: FeaturePriority;
  
  /**
   * Whether the feature is currently enabled
   */
  enabled: boolean;
  
  /**
   * Whether the feature can be manually toggled
   */
  manualToggleAllowed: boolean;
  
  /**
   * Power consumption in watts when enabled
   */
  powerConsumption: number;
  
  /**
   * CPU usage percentage when enabled
   */
  cpuUsage: number;
  
  /**
   * Memory usage in MB when enabled
   */
  memoryUsage: number;
  
  /**
   * Network bandwidth usage in KB/s when enabled
   */
  bandwidthUsage: number;
  
  /**
   * Storage I/O operations per second when enabled
   */
  storageIops: number;
  
  /**
   * Marine-specific settings
   */
  marineSettings: {
    /**
     * Whether this feature is required in rough seas
     */
    requiredInRoughSeas: boolean;
    
    /**
     * Whether this feature is required for navigation
     */
    requiredForNavigation: boolean;
    
    /**
     * Whether this feature is required for safety
     */
    requiredForSafety: boolean;
    
    /**
     * Whether this feature requires good connectivity
     */
    requiresGoodConnectivity: boolean;
  };
}

/**
 * Degradation metrics
 */
export interface DegradationMetrics {
  /**
   * Current service quality level
   */
  currentQualityLevel: ServiceQualityLevel;
  
  /**
   * Previous service quality level
   */
  previousQualityLevel: ServiceQualityLevel;
  
  /**
   * Time spent at each quality level (ms)
   */
  timeAtQualityLevel: {
    [key in ServiceQualityLevel]: number;
  };
  
  /**
   * Number of quality level changes
   */
  qualityLevelChanges: number;
  
  /**
   * Feature toggle metrics
   */
  featureToggles: {
    /**
     * Total number of features
     */
    total: number;
    
    /**
     * Number of enabled features
     */
    enabled: number;
    
    /**
     * Number of disabled features
     */
    disabled: number;
    
    /**
     * Number of features toggled automatically
     */
    autoToggled: number;
    
    /**
     * Number of features toggled manually
     */
    manuallyToggled: number;
  };
  
  /**
   * Resource usage metrics
   */
  resourceUsage: {
    /**
     * CPU usage percentage
     */
    cpu: number;
    
    /**
     * Memory usage percentage
     */
    memory: number;
    
    /**
     * Network bandwidth usage (KB/s)
     */
    bandwidth: number;
    
    /**
     * Storage I/O operations per second
     */
    storageIops: number;
    
    /**
     * Power consumption in watts
     */
    power: number;
  };
  
  /**
   * Marine-specific metrics
   */
  marineMetrics: {
    /**
     * Time spent in rough seas (ms)
     */
    timeInRoughSeas: number;
    
    /**
     * Time spent in power conservation mode (ms)
     */
    timeInPowerConservation: number;
    
    /**
     * Time spent with poor connectivity (ms)
     */
    timeWithPoorConnectivity: number;
    
    /**
     * Time spent in emergency mode (ms)
     */
    timeInEmergencyMode: number;
  };
}

/**
 * Degradation manager for graceful service degradation
 */
export class DegradationManager {
  private config: DegradationConfig;
  private currentQualityLevel: ServiceQualityLevel;
  private featureToggles: Map<string, FeatureToggle> = new Map();
  private metrics: DegradationMetrics;
  private eventListeners: ((event: ResilienceEvent) => void)[] = [];
  private marineEnvironment?: MarineEnvironmentStatus;
  private qualityLevelTimestamps: Map<ServiceQualityLevel, number> = new Map();
  private lastQualityUpdateTime: number = Date.now();
  
  constructor(config?: Partial<DegradationConfig>) {
    this.config = {
      defaultQualityLevel: ServiceQualityLevel.OPTIMAL,
      adaptToMarineConditions: true,
      powerAware: true,
      connectivityAware: true,
      qualityThresholds: {
        seaState: {
          rough: ServiceQualityLevel.REDUCED,
          veryRough: ServiceQualityLevel.MINIMAL
        },
        powerStatus: {
          conservation: ServiceQualityLevel.REDUCED,
          critical: ServiceQualityLevel.CRITICAL
        },
        connectivityQuality: {
          low: 0.3,
          lowQualityLevel: ServiceQualityLevel.REDUCED,
          veryLow: 0.1,
          veryLowQualityLevel: ServiceQualityLevel.MINIMAL
        }
      },
      featureToggles: {
        autoToggleFeatures: true,
        qualityLevelMinPriority: {
          [ServiceQualityLevel.OPTIMAL]: FeaturePriority.COMFORT,
          [ServiceQualityLevel.REDUCED]: FeaturePriority.USEFUL,
          [ServiceQualityLevel.MINIMAL]: FeaturePriority.IMPORTANT,
          [ServiceQualityLevel.CRITICAL]: FeaturePriority.ESSENTIAL,
          [ServiceQualityLevel.EMERGENCY]: FeaturePriority.CRITICAL
        }
      },
      resourceLimits: {
        cpu: {
          [ServiceQualityLevel.OPTIMAL]: 80,
          [ServiceQualityLevel.REDUCED]: 60,
          [ServiceQualityLevel.MINIMAL]: 40,
          [ServiceQualityLevel.CRITICAL]: 30,
          [ServiceQualityLevel.EMERGENCY]: 20
        },
        memory: {
          [ServiceQualityLevel.OPTIMAL]: 80,
          [ServiceQualityLevel.REDUCED]: 60,
          [ServiceQualityLevel.MINIMAL]: 40,
          [ServiceQualityLevel.CRITICAL]: 30,
          [ServiceQualityLevel.EMERGENCY]: 20
        },
        bandwidth: {
          [ServiceQualityLevel.OPTIMAL]: 1000,
          [ServiceQualityLevel.REDUCED]: 500,
          [ServiceQualityLevel.MINIMAL]: 200,
          [ServiceQualityLevel.CRITICAL]: 50,
          [ServiceQualityLevel.EMERGENCY]: 10
        },
        storageIops: {
          [ServiceQualityLevel.OPTIMAL]: 1000,
          [ServiceQualityLevel.REDUCED]: 500,
          [ServiceQualityLevel.MINIMAL]: 200,
          [ServiceQualityLevel.CRITICAL]: 50,
          [ServiceQualityLevel.EMERGENCY]: 10
        }
      },
      ...config
    };
    
    this.currentQualityLevel = this.config.defaultQualityLevel;
    this.metrics = this.initializeMetrics();
    
    // Initialize quality level timestamps
    Object.values(ServiceQualityLevel).forEach(level => {
      this.qualityLevelTimestamps.set(level, 0);
    });
    this.qualityLevelTimestamps.set(this.currentQualityLevel, Date.now());
  }
  
  /**
   * Register a feature toggle
   */
  registerFeature(feature: FeatureToggle): void {
    this.featureToggles.set(feature.id, feature);
    this.updateMetrics();
    
    this.emitEvent('recovery', `feature-${feature.id}`, {
      action: 'feature_registered',
      featureId: feature.id,
      featureName: feature.name,
      priority: feature.priority,
      enabled: feature.enabled
    }, 'info');
    
    // Apply current quality level to the feature
    this.applyQualityLevelToFeature(feature);
  }
  
  /**
   * Unregister a feature toggle
   */
  unregisterFeature(featureId: string): boolean {
    const feature = this.featureToggles.get(featureId);
    if (!feature) {
      return false;
    }
    
    this.featureToggles.delete(featureId);
    this.updateMetrics();
    
    this.emitEvent('recovery', `feature-${featureId}`, {
      action: 'feature_unregistered',
      featureId
    }, 'info');
    
    return true;
  }
  
  /**
   * Check if a feature is enabled
   */
  isFeatureEnabled(featureId: string): boolean {
    const feature = this.featureToggles.get(featureId);
    return feature ? feature.enabled : false;
  }
  
  /**
   * Manually enable a feature
   */
  enableFeature(featureId: string): boolean {
    const feature = this.featureToggles.get(featureId);
    if (!feature || !feature.manualToggleAllowed) {
      return false;
    }
    
    if (!feature.enabled) {
      feature.enabled = true;
      this.updateMetrics();
      
      this.emitEvent('recovery', `feature-${featureId}`, {
        action: 'feature_enabled',
        featureId,
        featureName: feature.name,
        manual: true
      }, 'info');
    }
    
    return true;
  }
  
  /**
   * Manually disable a feature
   */
  disableFeature(featureId: string): boolean {
    const feature = this.featureToggles.get(featureId);
    if (!feature || !feature.manualToggleAllowed) {
      return false;
    }
    
    // Don't disable critical features in emergency mode
    if (this.currentQualityLevel === ServiceQualityLevel.EMERGENCY && 
        feature.priority === FeaturePriority.CRITICAL) {
      return false;
    }
    
    if (feature.enabled) {
      feature.enabled = false;
      this.updateMetrics();
      
      this.emitEvent('recovery', `feature-${featureId}`, {
        action: 'feature_disabled',
        featureId,
        featureName: feature.name,
        manual: true
      }, 'info');
    }
    
    return true;
  }
  
  /**
   * Get current service quality level
   */
  getQualityLevel(): ServiceQualityLevel {
    return this.currentQualityLevel;
  }
  
  /**
   * Set service quality level manually
   */
  setQualityLevel(level: ServiceQualityLevel): void {
    if (level === this.currentQualityLevel) {
      return;
    }
    
    const previousLevel = this.currentQualityLevel;
    this.currentQualityLevel = level;
    
    // Update quality level timestamps
    const now = Date.now();
    const timeInPreviousLevel = now - this.lastQualityUpdateTime;
    const previousTime = this.qualityLevelTimestamps.get(previousLevel) || 0;
    this.qualityLevelTimestamps.set(previousLevel, previousTime + timeInPreviousLevel);
    this.lastQualityUpdateTime = now;
    
    // Apply quality level to all features
    this.applyQualityLevelToAllFeatures();
    
    // Update metrics
    this.metrics.previousQualityLevel = previousLevel;
    this.metrics.currentQualityLevel = level;
    this.metrics.qualityLevelChanges++;
    this.updateMetrics();
    
    this.emitEvent('recovery', 'degradation-manager', {
      action: 'quality_level_changed',
      previousLevel,
      newLevel: level,
      manual: true
    }, 'warning');
  }
  
  /**
   * Update marine environment for adaptive degradation
   */
  updateMarineEnvironment(environment: MarineEnvironmentStatus): void {
    this.marineEnvironment = environment;
    
    // Update marine-specific metrics
    if (environment.seaState === 'rough' || environment.seaState === 'very_rough') {
      this.metrics.marineMetrics.timeInRoughSeas += Date.now() - this.lastQualityUpdateTime;
    }
    
    if (environment.powerStatus === 'conservation' || environment.powerStatus === 'critical') {
      this.metrics.marineMetrics.timeInPowerConservation += Date.now() - this.lastQualityUpdateTime;
    }
    
    if (environment.connectivityQuality < this.config.qualityThresholds.connectivityQuality.low) {
      this.metrics.marineMetrics.timeWithPoorConnectivity += Date.now() - this.lastQualityUpdateTime;
    }
    
    if (environment.criticalOperationsOnly) {
      this.metrics.marineMetrics.timeInEmergencyMode += Date.now() - this.lastQualityUpdateTime;
    }
    
    this.lastQualityUpdateTime = Date.now();
    
    // Determine appropriate quality level based on marine conditions
    const newQualityLevel = this.determineQualityLevelFromEnvironment(environment);
    
    if (newQualityLevel !== this.currentQualityLevel) {
      const previousLevel = this.currentQualityLevel;
      this.currentQualityLevel = newQualityLevel;
      
      // Update quality level timestamps
      const now = Date.now();
      const timeInPreviousLevel = now - this.lastQualityUpdateTime;
      const previousTime = this.qualityLevelTimestamps.get(previousLevel) || 0;
      this.qualityLevelTimestamps.set(previousLevel, previousTime + timeInPreviousLevel);
      this.lastQualityUpdateTime = now;
      
      // Apply quality level to all features
      this.applyQualityLevelToAllFeatures();
      
      // Update metrics
      this.metrics.previousQualityLevel = previousLevel;
      this.metrics.currentQualityLevel = newQualityLevel;
      this.metrics.qualityLevelChanges++;
      
      this.emitEvent('recovery', 'degradation-manager', {
        action: 'quality_level_changed',
        previousLevel,
        newLevel: newQualityLevel,
        manual: false,
        environmentalCause: true,
        seaState: environment.seaState,
        powerStatus: environment.powerStatus,
        connectivityQuality: environment.connectivityQuality,
        criticalOperationsOnly: environment.criticalOperationsOnly
      }, 'warning');
    }
    
    this.emitEvent('recovery', 'degradation-manager', {
      action: 'marine_environment_updated',
      seaState: environment.seaState,
      powerStatus: environment.powerStatus,
      connectivityQuality: environment.connectivityQuality,
      criticalOperationsOnly: environment.criticalOperationsOnly
    }, 'info');
  }
  
  /**
   * Get current degradation metrics
   */
  getMetrics(): DegradationMetrics {
    this.updateMetrics();
    return { ...this.metrics };
  }
  
  /**
   * Get all registered features
   */
  getAllFeatures(): FeatureToggle[] {
    return Array.from(this.featureToggles.values());
  }
  
  /**
   * Get enabled features
   */
  getEnabledFeatures(): FeatureToggle[] {
    return Array.from(this.featureToggles.values()).filter(feature => feature.enabled);
  }
  
  /**
   * Get disabled features
   */
  getDisabledFeatures(): FeatureToggle[] {
    return Array.from(this.featureToggles.values()).filter(feature => !feature.enabled);
  }
  
  /**
   * Add event listener
   */
  onEvent(listener: (event: ResilienceEvent) => void): void {
    this.eventListeners.push(listener);
  }
  
  /**
   * Remove event listener
   */
  removeEventListener(listener: (event: ResilienceEvent) => void): void {
    const index = this.eventListeners.indexOf(listener);
    if (index > -1) {
      this.eventListeners.splice(index, 1);
    }
  }
  
  /**
   * Determine quality level from marine environment
   */
  private determineQualityLevelFromEnvironment(environment: MarineEnvironmentStatus): ServiceQualityLevel {
    // Start with default quality level
    let qualityLevel = this.config.defaultQualityLevel;
    
    // Emergency mode takes precedence
    if (environment.criticalOperationsOnly) {
      return ServiceQualityLevel.EMERGENCY;
    }
    
    // Check power status if configured
    if (this.config.powerAware) {
      if (environment.powerStatus === 'critical') {
        qualityLevel = this.getMoreRestrictiveLevel(
          qualityLevel, 
          this.config.qualityThresholds.powerStatus.critical
        );
      } else if (environment.powerStatus === 'conservation') {
        qualityLevel = this.getMoreRestrictiveLevel(
          qualityLevel, 
          this.config.qualityThresholds.powerStatus.conservation
        );
      }
    }
    
    // Check sea state if configured
    if (this.config.adaptToMarineConditions) {
      if (environment.seaState === 'very_rough') {
        qualityLevel = this.getMoreRestrictiveLevel(
          qualityLevel, 
          this.config.qualityThresholds.seaState.veryRough
        );
      } else if (environment.seaState === 'rough') {
        qualityLevel = this.getMoreRestrictiveLevel(
          qualityLevel, 
          this.config.qualityThresholds.seaState.rough
        );
      }
    }
    
    // Check connectivity quality if configured
    if (this.config.connectivityAware) {
      if (environment.connectivityQuality < this.config.qualityThresholds.connectivityQuality.veryLow) {
        qualityLevel = this.getMoreRestrictiveLevel(
          qualityLevel, 
          this.config.qualityThresholds.connectivityQuality.veryLowQualityLevel
        );
      } else if (environment.connectivityQuality < this.config.qualityThresholds.connectivityQuality.low) {
        qualityLevel = this.getMoreRestrictiveLevel(
          qualityLevel, 
          this.config.qualityThresholds.connectivityQuality.lowQualityLevel
        );
      }
    }
    
    return qualityLevel;
  }
  
  /**
   * Get the more restrictive of two quality levels
   */
  private getMoreRestrictiveLevel(level1: ServiceQualityLevel, level2: ServiceQualityLevel): ServiceQualityLevel {
    const levelOrder = [
      ServiceQualityLevel.OPTIMAL,
      ServiceQualityLevel.REDUCED,
      ServiceQualityLevel.MINIMAL,
      ServiceQualityLevel.CRITICAL,
      ServiceQualityLevel.EMERGENCY
    ];
    
    const index1 = levelOrder.indexOf(level1);
    const index2 = levelOrder.indexOf(level2);
    
    // Ensure we don't return undefined
    return levelOrder[Math.max(index1, index2)] || ServiceQualityLevel.OPTIMAL;
  }
  
  /**
   * Apply quality level to all features
   */
  private applyQualityLevelToAllFeatures(): void {
    if (!this.config.featureToggles.autoToggleFeatures) {
      return;
    }
    
    for (const feature of this.featureToggles.values()) {
      this.applyQualityLevelToFeature(feature);
    }
  }
  
  /**
   * Apply quality level to a specific feature
   */
  private applyQualityLevelToFeature(feature: FeatureToggle): void {
    if (!this.config.featureToggles.autoToggleFeatures || !feature.manualToggleAllowed) {
      return;
    }
    
    const minPriority = this.config.featureToggles.qualityLevelMinPriority[this.currentQualityLevel];
    const priorityOrder = [
      FeaturePriority.COMFORT,
      FeaturePriority.USEFUL,
      FeaturePriority.IMPORTANT,
      FeaturePriority.ESSENTIAL,
      FeaturePriority.CRITICAL
    ];
    
    const featurePriorityIndex = priorityOrder.indexOf(feature.priority);
    const minPriorityIndex = priorityOrder.indexOf(minPriority);
    
    const shouldBeEnabled = featurePriorityIndex >= minPriorityIndex;
    
    // Special case for marine-specific features
    if (this.marineEnvironment) {
      // Always enable safety features in rough seas
      if (feature.marineSettings.requiredForSafety && 
          (this.marineEnvironment.seaState === 'rough' || 
           this.marineEnvironment.seaState === 'very_rough')) {
        if (!feature.enabled) {
          feature.enabled = true;
          this.emitEvent('recovery', `feature-${feature.id}`, {
            action: 'feature_enabled',
            featureId: feature.id,
            featureName: feature.name,
            reason: 'safety_required_in_rough_seas',
            manual: false
          }, 'info');
        }
        return;
      }
      
      // Always enable navigation features when sailing or motoring
      if (feature.marineSettings.requiredForNavigation && 
          (this.marineEnvironment.seaState === 'rough' || 
           this.marineEnvironment.seaState === 'very_rough')) {
        if (!feature.enabled) {
          feature.enabled = true;
          this.emitEvent('recovery', `feature-${feature.id}`, {
            action: 'feature_enabled',
            featureId: feature.id,
            featureName: feature.name,
            reason: 'navigation_required_in_rough_seas',
            manual: false
          }, 'info');
        }
        return;
      }
      
      // Disable connectivity-dependent features when connectivity is poor
      if (feature.marineSettings.requiresGoodConnectivity && 
          this.marineEnvironment.connectivityQuality < this.config.qualityThresholds.connectivityQuality.low) {
        if (feature.enabled) {
          feature.enabled = false;
          this.emitEvent('recovery', `feature-${feature.id}`, {
            action: 'feature_disabled',
            featureId: feature.id,
            featureName: feature.name,
            reason: 'poor_connectivity',
            manual: false
          }, 'info');
        }
        return;
      }
    }
    
    // Apply standard priority-based rules
    if (feature.enabled !== shouldBeEnabled) {
      feature.enabled = shouldBeEnabled;
      
      this.emitEvent('recovery', `feature-${feature.id}`, {
        action: shouldBeEnabled ? 'feature_enabled' : 'feature_disabled',
        featureId: feature.id,
        featureName: feature.name,
        reason: 'quality_level_change',
        qualityLevel: this.currentQualityLevel,
        featurePriority: feature.priority,
        minPriority,
        manual: false
      }, 'info');
    }
  }
  
  /**
   * Update metrics
   */
  private updateMetrics(): void {
    // Update time at quality level
    const now = Date.now();
    const timeInCurrentLevel = now - this.lastQualityUpdateTime;
    const currentTime = this.qualityLevelTimestamps.get(this.currentQualityLevel) || 0;
    this.qualityLevelTimestamps.set(this.currentQualityLevel, currentTime + timeInCurrentLevel);
    this.lastQualityUpdateTime = now;
    
    // Update time at quality level metrics
    Object.values(ServiceQualityLevel).forEach(level => {
      this.metrics.timeAtQualityLevel[level] = this.qualityLevelTimestamps.get(level) || 0;
    });
    
    // Update feature toggle metrics
    const features = Array.from(this.featureToggles.values());
    this.metrics.featureToggles.total = features.length;
    this.metrics.featureToggles.enabled = features.filter(f => f.enabled).length;
    this.metrics.featureToggles.disabled = features.filter(f => !f.enabled).length;
    
    // Update resource usage metrics
    let totalCpu = 0;
    let totalMemory = 0;
    let totalBandwidth = 0;
    let totalStorageIops = 0;
    let totalPower = 0;
    
    for (const feature of features) {
      if (feature.enabled) {
        totalCpu += feature.cpuUsage;
        totalMemory += feature.memoryUsage;
        totalBandwidth += feature.bandwidthUsage;
        totalStorageIops += feature.storageIops;
        totalPower += feature.powerConsumption;
      }
    }
    
    this.metrics.resourceUsage.cpu = totalCpu;
    this.metrics.resourceUsage.memory = totalMemory;
    this.metrics.resourceUsage.bandwidth = totalBandwidth;
    this.metrics.resourceUsage.storageIops = totalStorageIops;
    this.metrics.resourceUsage.power = totalPower;
  }
  
/**
 * Initialize metrics
 */
private initializeMetrics(): DegradationMetrics {
  return {
    currentQualityLevel: ServiceQualityLevel.OPTIMAL,
    previousQualityLevel: ServiceQualityLevel.OPTIMAL,
    timeAtQualityLevel: {
      [ServiceQualityLevel.OPTIMAL]: 0,
      [ServiceQualityLevel.REDUCED]: 0,
      [ServiceQualityLevel.MINIMAL]: 0,
      [ServiceQualityLevel.CRITICAL]: 0,
      [ServiceQualityLevel.EMERGENCY]: 0
    },
    qualityLevelChanges: 0,
    featureToggles: {
      total: 0,
      enabled: 0,
      disabled: 0,
      autoToggled: 0,
      manuallyToggled: 0
    },
    resourceUsage: {
      cpu: 0,
      memory: 0,
      bandwidth: 0,
      storageIops: 0,
      power: 0
    },
    marineMetrics: {
      timeInRoughSeas: 0,
      timeInPowerConservation: 0,
      timeWithPoorConnectivity: 0,
      timeInEmergencyMode: 0
    }
  };
}

/**
 * Emit resilience event
 */
private emitEvent(
  eventType: ResilienceEvent['eventType'],
  component: string,
  details: Record<string, any>,
  severity: ResilienceEvent['severity']
): void {
  const event: ResilienceEvent = {
    timestamp: new Date(),
    eventType,
    component,
    details,
    severity,
    marineContext: {
      operationalContext: this.marineEnvironment?.powerStatus === 'critical' ? 
        OperationalContext.EMERGENCY : OperationalContext.SAILING,
      environmentalImpact: this.marineEnvironment?.seaState === 'very_rough',
      safetyImpact: false
    }
  };
  
  this.eventListeners.forEach(listener => {
    try {
      listener(event);
    } catch (error) {
      console.error('Error in degradation manager event listener:', error);
    }
  });
}

}

/**
 * Default degradation manager instance
 */
export const defaultDegradationManager = new DegradationManager();
