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

/// Hyprland-specific activity detector that polls the active window
class HyprlandActivityDetector implements IActivityDetector {
  final StreamController<ActivityEvent> _activityController = StreamController<ActivityEvent>.broadcast();
  Timer? _pollTimer;
  String? _lastActiveWindow;
  String? _lastActiveWindowTitle;
  DateTime? _lastActivityTime;
  bool _isRunning = false;

  @override
  Stream<ActivityEvent> get activityStream => _activityController.stream;

  @override
  Future<void> start() async {
    if (_isRunning) return;

    _isRunning = true;
    _pollTimer = Timer.periodic(Duration(seconds: 5), (_) => _pollActivity());
    print('🔍 Started Hyprland activity detection...');
  }

  @override
  void stop() {
    _isRunning = false;
    _pollTimer?.cancel();
    _pollTimer = null;

    // Flush any remaining activity
    if (_lastActiveWindow != null && _lastActivityTime != null) {
      final duration = DateTime.now().difference(_lastActivityTime!).inSeconds;
      if (duration >= 10) {
        _emitActivityEvent(_lastActiveWindow!, _lastActiveWindowTitle ?? '', duration);
      }
    }

    _activityController.close();
    print('🛑 Stopped Hyprland activity detection');
  }

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

      final windowData = jsonDecode(result.stdout);
      final currentApp = windowData['class'] as String? ?? 'unknown';
      final currentWindowTitle = windowData['title'] as String? ?? '';
      final now = DateTime.now();

      // If this is a different activity from the last one, emit the previous activity
      if (_lastActiveWindow != null &&
          (_lastActiveWindow != currentApp || _lastActiveWindowTitle != currentWindowTitle)) {
        final duration = now.difference(_lastActivityTime ?? now).inSeconds;
        if (duration >= 10) {
          _emitActivityEvent(_lastActiveWindow!, _lastActiveWindowTitle ?? '', duration);
        }
      }

      // Update current activity
      _lastActiveWindow = currentApp;
      _lastActiveWindowTitle = currentWindowTitle;
      _lastActivityTime = now;
    } catch (e) {
      print('Error polling Hyprland activity: $e');
    }
  }

  void _emitActivityEvent(String application, String title, int durationSeconds) {
    final event = ActivityEvent(
      type: ActivityEventType.categorize(applicationId: application, applicationTitle: title),
      application: application,
      metadata: title,
      timestamp: DateTime.now(),
    );

    _activityController.add(event);
  }

  @override
  Future<ActivityEvent> getCurrentActivity() {
    return _activityController.stream.single;
  }
}
