import 'dart:convert';
import 'dart:io';
import '../interfaces/i_window_manager.dart';

/// Hyprland window manager implementation
class HyprlandManager implements IWindowManager {
  @override
  String get managerType => 'Hyprland';

  @override
  Future<Map<String, dynamic>?> getCurrentWindow() async {
    try {
      final result = await Process.run('hyprctl', ['activewindow', '-j']);
      if (result.exitCode != 0) {
        return null;
      }

      final windowData = jsonDecode(result.stdout) as Map<String, dynamic>;
      
      return {
        'application': windowData['class'] as String? ?? 'unknown',
        'title': windowData['title'] as String? ?? '',
        'pid': windowData['pid'] as int? ?? -1,
        'workspace': windowData['workspace'] != null 
            ? (windowData['workspace'] as Map<String, dynamic>)['id'] as int? ?? -1
            : -1,
        'address': windowData['address'] as String? ?? '',
        'floating': windowData['floating'] as bool? ?? false,
        'fullscreen': windowData['fullscreen'] as bool? ?? false,
        'size': windowData['size'] != null 
            ? [
                (windowData['size'] as List<dynamic>)[0] as int,
                (windowData['size'] as List<dynamic>)[1] as int,
              ] 
            : [0, 0],
        'position': windowData['at'] != null
            ? [
                (windowData['at'] as List<dynamic>)[0] as int,
                (windowData['at'] as List<dynamic>)[1] as int,
              ]
            : [0, 0],
      };
    } catch (e) {
      print('Error getting current window from Hyprland: $e');
      return null;
    }
  }

  @override
  Future<String> getActiveApplication() async {
    final window = await getCurrentWindow();
    return window?['application'] as String? ?? 'unknown';
  }

  @override
  Future<String> getWindowTitle() async {
    final window = await getCurrentWindow();
    return window?['title'] as String? ?? '';
  }

  @override
  Future<Map<String, dynamic>?> getCurrentWorkspace() async {
    try {
      final result = await Process.run('hyprctl', ['activeworkspace', '-j']);
      if (result.exitCode != 0) {
        return null;
      }

      final workspaceData = jsonDecode(result.stdout) as Map<String, dynamic>;
      
      return {
        'id': workspaceData['id'] as int? ?? -1,
        'name': workspaceData['name'] as String? ?? '',
        'monitor': workspaceData['monitor'] as String? ?? '',
        'windows': workspaceData['windows'] as int? ?? 0,
        'hasfullscreen': workspaceData['hasfullscreen'] as bool? ?? false,
        'lastwindow': workspaceData['lastwindow'] as String? ?? '',
        'lastwindowtitle': workspaceData['lastwindowtitle'] as String? ?? '',
      };
    } catch (e) {
      print('Error getting current workspace from Hyprland: $e');
      return null;
    }
  }

  @override
  Future<bool> isAvailable() async {
    try {
      final result = await Process.run('hyprctl', ['version']);
      return result.exitCode == 0;
    } catch (e) {
      return false;
    }
  }

  @override
  Future<String?> getVersion() async {
    try {
      final result = await Process.run('hyprctl', ['version']);
      if (result.exitCode == 0) {
        final output = result.stdout as String;
        final lines = output.split('\n');
        if (lines.isNotEmpty) {
          return lines.first.trim();
        }
      }
      return null;
    } catch (e) {
      return null;
    }
  }

  /// Get all windows from Hyprland
  Future<List<Map<String, dynamic>>> getAllWindows() async {
    try {
      final result = await Process.run('hyprctl', ['clients', '-j']);
      if (result.exitCode != 0) {
        return [];
      }

      final clientsData = jsonDecode(result.stdout) as List<dynamic>;
      return clientsData.cast<Map<String, dynamic>>();
    } catch (e) {
      print('Error getting all windows from Hyprland: $e');
      return [];
    }
  }

  /// Get all workspaces from Hyprland
  Future<List<Map<String, dynamic>>> getAllWorkspaces() async {
    try {
      final result = await Process.run('hyprctl', ['workspaces', '-j']);
      if (result.exitCode != 0) {
        return [];
      }

      final workspacesData = jsonDecode(result.stdout) as List<dynamic>;
      return workspacesData.cast<Map<String, dynamic>>();
    } catch (e) {
      print('Error getting all workspaces from Hyprland: $e');
      return [];
    }
  }

  /// Get monitor information from Hyprland
  Future<List<Map<String, dynamic>>> getMonitors() async {
    try {
      final result = await Process.run('hyprctl', ['monitors', '-j']);
      if (result.exitCode != 0) {
        return [];
      }

      final monitorsData = jsonDecode(result.stdout) as List<dynamic>;
      return monitorsData.cast<Map<String, dynamic>>();
    } catch (e) {
      print('Error getting monitors from Hyprland: $e');
      return [];
    }
  }

  /// Execute a Hyprland dispatch command
  Future<bool> dispatch(String command, [List<String> args = const []]) async {
    try {
      final fullArgs = ['dispatch', command, ...args];
      final result = await Process.run('hyprctl', fullArgs);
      return result.exitCode == 0;
    } catch (e) {
      print('Error executing Hyprland dispatch: $e');
      return false;
    }
  }

  @override
  Future<Map<String, int>?> getCursorPosition() async {
    try {
      final result = await Process.run('hyprctl', ['cursorpos']);
      if (result.exitCode != 0) {
        return null;
      }

      final output = result.stdout as String;
      // Parse output format: "123, 456" (x, y coordinates)
      final coordinates = output.trim().split(', ');
      if (coordinates.length != 2) {
        print('Unexpected cursor position format: $output');
        return null;
      }

      final x = int.tryParse(coordinates[0]);
      final y = int.tryParse(coordinates[1]);
      
      if (x == null || y == null) {
        print('Failed to parse cursor coordinates: $output');
        return null;
      }

      return {'x': x, 'y': y};
    } catch (e) {
      print('Error getting cursor position from Hyprland: $e');
      return null;
    }
  }
}