import 'dart:io';

import '../interfaces/i_idle_monitor.dart';
import '../detectors/idle_monitor.dart';
import '../detectors/sway_idle_monitor.dart';
import '../detectors/window_manager_detector.dart';
import '../testing/mock_idle_monitor.dart';

/// Factory for creating appropriate idle monitor implementations based on the window manager
class IdleMonitorFactory {
  /// Create an idle monitor based on the detected window manager
  static IIdleMonitor create([WindowManager? windowManager]) {
    windowManager ??= WindowManagerDetector.instance.detect();

    return switch (windowManager) {
      WindowManager.hyprland => IdleMonitor(), // Existing Hyprland implementation
      WindowManager.sway => SwayIdleMonitor(), // New Sway implementation
      WindowManager.unknown => _createFallbackMonitor(),
    };
  }

  /// Create a mock idle monitor for testing
  static IIdleMonitor createMock() {
    return MockIdleMonitor();
  }

  /// Create an idle monitor for a specific window manager (useful for testing)
  static IIdleMonitor createForWindowManager(WindowManager windowManager) {
    return create(windowManager);
  }

  /// Create a fallback idle monitor when window manager is unknown
  static IIdleMonitor _createFallbackMonitor() {
    print('⚠️  Unknown window manager detected, attempting Hyprland idle monitor as fallback');
    print('   If this fails, consider running in a supported environment (Hyprland or Sway)');

    // Try Hyprland first as fallback
    return IdleMonitor();
  }

  /// Get information about available idle monitor implementations
  static Map<String, dynamic> getAvailableImplementations() {
    return {
      'hyprland': {
        'class': 'IdleMonitor',
        'description': 'Uses hypridle for idle detection',
        'requirements': ['hypridle'],
      },
      'sway': {
        'class': 'SwayIdleMonitor',
        'description': 'Uses swayidle for idle detection',
        'requirements': ['swayidle'],
      },
      'mock': {'class': 'MockIdleMonitor', 'description': 'Controllable mock for testing', 'requirements': []},
    };
  }

  /// Check if idle monitoring is supported for the given window manager
  static bool isSupported(WindowManager windowManager) {
    return WindowManagerDetector.instance.supportsIdleMonitoring(windowManager);
  }

  /// Validate that required tools are available for the window manager
  static Future<bool> validateRequirements(WindowManager windowManager) async {
    return switch (windowManager) {
      WindowManager.hyprland => await _validateHyprlandRequirements(),
      WindowManager.sway => await SwayIdleMonitor.isAvailable(),
      WindowManager.unknown => false,
    };
  }

  static Future<bool> _validateHyprlandRequirements() async {
    try {
      final result = await Process.run('which', ['hypridle']);
      return result.exitCode == 0;
    } catch (e) {
      return false;
    }
  }
}
