import '../interfaces/i_window_manager.dart';
import '../window_managers/hyprland_manager.dart';
import '../window_managers/sway_manager.dart';
import '../detectors/window_manager_detector.dart';

/// Factory for creating appropriate window manager implementations
class WindowManagerFactory {
  /// Create a window manager based on the detected window manager
  static IWindowManager? create([WindowManager? windowManager]) {
    windowManager ??= WindowManagerDetector.instance.detect();

    return switch (windowManager) {
      WindowManager.hyprland => HyprlandManager(),
      WindowManager.sway => SwayManager(),
      WindowManager.unknown => null, // No window manager available
    };
  }

  /// Create a window manager for a specific type (useful for testing)
  static IWindowManager? createForWindowManager(WindowManager windowManager) {
    return create(windowManager);
  }

  /// Get information about available window manager implementations
  static Map<String, dynamic> getAvailableImplementations() {
    return {
      'hyprland': {
        'class': 'HyprlandManager',
        'description': 'Uses hyprctl commands for window management',
        'commands': ['hyprctl activewindow', 'hyprctl workspaces', 'hyprctl clients'],
        'requirements': ['hyprctl'],
      },
      'sway': {
        'class': 'SwayManager', 
        'description': 'Uses swaymsg commands for window management',
        'commands': ['swaymsg -t get_tree', 'swaymsg -t get_workspaces'],
        'requirements': ['swaymsg'],
      },
    };
  }

  /// Check if window management is supported for the given window manager
  static bool isSupported(WindowManager windowManager) {
    return windowManager != WindowManager.unknown;
  }

  /// 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 _validateSwayRequirements(),
      WindowManager.unknown => false,
    };
  }

  static Future<bool> _validateHyprlandRequirements() async {
    try {
      final manager = HyprlandManager();
      return await manager.isAvailable();
    } catch (e) {
      return false;
    }
  }

  static Future<bool> _validateSwayRequirements() async {
    try {
      final manager = SwayManager();
      return await manager.isAvailable();
    } catch (e) {
      return false;
    }
  }

  /// Get version information for available window managers
  static Future<Map<String, String?>> getVersions() async {
    final versions = <String, String?>{};

    try {
      final hyprland = HyprlandManager();
      versions['hyprland'] = await hyprland.getVersion();
    } catch (e) {
      versions['hyprland'] = null;
    }

    try {
      final sway = SwayManager();
      versions['sway'] = await sway.getVersion();
    } catch (e) {
      versions['sway'] = null;
    }

    return versions;
  }
}