import 'dart:async';
import 'dart:convert';
import 'dart:io';
import '../models/activity_event.dart';

class ZoomDetector {
  Future<ZoomStatus> getZoomStatus() async {
    final hasZoomProcess = await _hasZoomProcess();
    if (!hasZoomProcess) return ZoomStatus.none;

    // Zoom is running, now determine engagement level
    final isActiveWindow = await _isZoomActiveWindow();
    final hasMediaActivity = await _hasMediaActivity();

    if (isActiveWindow && hasMediaActivity) {
      return ZoomStatus.activeMeeting;
    } else if (hasMediaActivity) {
      return ZoomStatus.backgroundMeeting;
    } else if (isActiveWindow) {
      return ZoomStatus.zoomFocused;
    } else {
      return ZoomStatus.zoomBackground;
    }
  }

  Future<bool> _hasZoomProcess() async {
    try {
      final result = await Process.run('pgrep', ['-f', 'zoom']);
      return result.exitCode == 0;
    } catch (e) {
      return false;
    }
  }

  Future<bool> _isZoomActiveWindow() async {
    try {
      final result = await Process.run('hyprctl', ['activewindow', '-j']);
      if (result.exitCode != 0) return false;

      final windowData = jsonDecode(result.stdout);
      final className = windowData['class'] as String? ?? '';
      return className.toLowerCase().contains('zoom');
    } catch (e) {
      return false;
    }
  }

  Future<bool> _hasMediaActivity() async {
    // Check both camera and microphone
    final cameraActive = await _isCameraInUse();
    final micActive = await _isMicrophoneInUse();
    return cameraActive || micActive;
  }

  Future<bool> _isCameraInUse() async {
    try {
      // Try lsof first, fallback to checking video device existence
      final lsofResult = await Process.run('lsof', [
        '/dev/video0',
      ]).timeout(Duration(seconds: 2), onTimeout: () => ProcessResult(0, 1, '', 'timeout'));
      if (lsofResult.exitCode == 0 && lsofResult.stdout.contains('zoom')) {
        return true;
      }
    } catch (e) {
      // lsof not available, try alternative detection
      print('Warning: lsof not available, using fallback camera detection');
    }

    // Fallback: check if video device is accessible (rough indicator)
    try {
      final videoDevice = File('/dev/video0');
      return videoDevice.existsSync();
    } catch (e) {
      return false;
    }
  }

  Future<bool> _isMicrophoneInUse() async {
    try {
      final result = await Process.run('pactl', ['list', 'source-outputs']);
      return result.stdout.toLowerCase().contains('zoom');
    } catch (e) {
      return false;
    }
  }
}
