import 'dart:io';
import '../interfaces/i_window_manager.dart';
import '../logging/logger.dart';

/// Manages cursor-positioned XP overlays by coordinating cursor tracking
/// and spawning Flutter overlay processes
class CursorOverlayManager {
  final IWindowManager _windowManager;
  final String _overlayAppPath;

  CursorOverlayManager({
    required IWindowManager windowManager,
    required String overlayAppPath,
  })  : _windowManager = windowManager,
        _overlayAppPath = overlayAppPath;

  /// Show XP number at current cursor position
  /// 
  /// [xpValue] - XP amount to display
  /// [duration] - How long to show the overlay (default 3 seconds)
  Future<void> showXPNumber(int xpValue, {Duration duration = const Duration(seconds: 3)}) async {
    try {
      // Get current cursor position
      final cursorPos = await _windowManager.getCursorPosition();
      if (cursorPos == null) {
        Logger.warn('Could not get cursor position, skipping XP overlay');
        return;
      }

      final x = cursorPos['x']!;
      final y = cursorPos['y']!;

      Logger.info('Showing XP overlay: +$xpValue at position ($x, $y)');

      // Spawn Flutter overlay process
      await _spawnOverlayProcess(x, y, xpValue, duration);
    } catch (e) {
      Logger.error('Failed to show XP overlay', e);
    }
  }

  /// Show XP number at specific position
  /// 
  /// [x] - X coordinate in pixels
  /// [y] - Y coordinate in pixels  
  /// [xpValue] - XP amount to display
  /// [duration] - How long to show the overlay
  Future<void> showXPNumberAt(int x, int y, int xpValue, {Duration duration = const Duration(seconds: 3)}) async {
    try {
      Logger.info('Showing XP overlay: +$xpValue at position ($x, $y)');
      await _spawnOverlayProcess(x, y, xpValue, duration);
    } catch (e) {
      Logger.error('Failed to show XP overlay at position', e);
    }
  }

  /// Test cursor position tracking
  /// 
  /// Returns current cursor coordinates or null if unavailable
  Future<Map<String, int>?> getCurrentCursorPosition() async {
    try {
      return await _windowManager.getCursorPosition();
    } catch (e) {
      Logger.error('Failed to get cursor position', e);
      return null;
    }
  }

  /// Spawn the Flutter overlay process
  Future<void> _spawnOverlayProcess(int x, int y, int xpValue, Duration duration) async {
    final durationSeconds = duration.inSeconds;
    
    // Check if overlay app exists
    if (!await File(_overlayAppPath).exists()) {
      Logger.error('Overlay app not found at: $_overlayAppPath');
      return;
    }

    try {
      // Spawn overlay process with arguments: x y xp_value duration_seconds
      final process = await Process.start(
        _overlayAppPath,
        [x.toString(), y.toString(), xpValue.toString(), durationSeconds.toString()],
        mode: ProcessStartMode.detached,
      );

      Logger.debug('Spawned overlay process with PID: ${process.pid}');
      
      // Don't wait for the process to complete - let it run independently
      process.exitCode.then((exitCode) {
        if (exitCode != 0) {
          Logger.warn('Overlay process exited with code: $exitCode');
        } else {
          Logger.debug('Overlay process completed successfully');
        }
      }).catchError((error) {
        Logger.error('Overlay process error', error);
      });
      
    } catch (e) {
      Logger.error('Failed to spawn overlay process', e);
    }
  }

  /// Test the overlay system by showing a test XP number
  Future<void> testOverlay({int testXP = 42}) async {
    Logger.info('Testing overlay system with XP value: $testXP');
    await showXPNumber(testXP, duration: const Duration(seconds: 5));
  }

  /// Check if the overlay system is available
  Future<bool> isAvailable() async {
    try {
      // Check if window manager supports cursor position
      final cursorPos = await _windowManager.getCursorPosition();
      final windowManagerAvailable = cursorPos != null;
      
      // Check if overlay app exists
      final overlayAppAvailable = await File(_overlayAppPath).exists();
      
      Logger.debug('Overlay system availability: windowManager=$windowManagerAvailable, overlayApp=$overlayAppAvailable');
      
      return windowManagerAvailable && overlayAppAvailable;
    } catch (e) {
      Logger.error('Error checking overlay availability', e);
      return false;
    }
  }
}