import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:sqlite3/sqlite3.dart';
import 'package:xp_nix/src/monitors/productivity_monitor.dart';
import 'package:xp_nix/src/config/config_manager.dart';
import 'package:xp_nix/src/logging/logger.dart';
import 'package:xp_nix/src/web/dashboard_server.dart';
import 'package:xp_nix/src/database/database_manager.dart';
import 'package:xp_nix/src/providers/system_time_provider.dart';
import 'package:xp_nix/src/build/dashboard_builder.dart';
// Window manager detection and factories
import 'package:xp_nix/src/detectors/window_manager_detector.dart';
import 'package:xp_nix/src/factories/idle_monitor_factory.dart';
import 'package:xp_nix/src/factories/activity_detector_factory.dart';
import 'package:xp_nix/src/factories/desktop_enhancer_factory.dart';
// Interfaces
import 'package:xp_nix/src/interfaces/i_idle_monitor.dart';
import 'package:xp_nix/src/interfaces/i_activity_detector.dart';
import 'package:xp_nix/src/interfaces/i_desktop_enhancer.dart';

late final Database _db;
late final IIdleMonitor _idleMonitor;
late final SystemTimeProvider _timeProvider;
late final IDesktopEnhancer _desktopEnhancer;
late final IActivityDetector? _activityDetector;
late final ProductivityMonitor _monitor;
late final DashboardServer _dashboardServer;

// Enhanced main function with interactive commands and one-shot mode
void main(List<String> args) async {
  // Parse command line arguments
  String dbPath = 'productivity_tracker.db';
  int port = 8080;

  for (int i = 0; i < args.length; i++) {
    switch (args[i]) {
      case '--db':
        if (i + 1 < args.length) {
          dbPath = args[i + 1];
          i++; // Skip next argument as it's the db path
        } else {
          print('Error: --db flag requires a database path');
          exit(1);
        }
        break;
      case '--port':
        if (i + 1 < args.length) {
          port = int.tryParse(args[i + 1]) ?? 8080;
          i++; // Skip next argument as it's the port number
        } else {
          print('Error: --port flag requires a port number');
          exit(1);
        }
        break;
      case '--help':
      case '-h':
        print('''
XP Nix Server - Productivity Tracking with Gamification

A productivity tracking system that works with both Hyprland and Sway window managers.
Automatically detects your environment and adapts functionality accordingly.

Usage: dart xp_nix.dart [options]

Options:
  --db PATH     Database file path (default: productivity_tracker.db)
  --port PORT   Server port (default: 8080)
  --help, -h    Show this help message

Supported Window Managers:
  • Hyprland: Full visual effects, idle monitoring, activity detection
  • Sway: Activity detection, idle monitoring (no visual effects)
  • Detection: Automatic via environment variables

Examples:
  dart xp_nix.dart
  dart xp_nix.dart --db test_data.db --port 8081

Requirements:
  • Hyprland: hypridle, hyprctl
  • Sway: swayidle, swaymsg
        ''');
        exit(0);
    }
  }

  print('🗄️  Using database: $dbPath');
  print('🌐 Starting server on port: $port');

  // Initialize logging system
  await Logger.instance.initialize(level: LogLevel.info, logDirectory: 'logs', maxFileSizeMB: 10, maxFiles: 5);

  // Initialize configuration manager
  await ConfigManager.instance.initialize();

  // Detect window manager and display information
  final windowManager = WindowManagerDetector.instance.detect();
  final detectionInfo = WindowManagerDetector.instance.getDetectionInfo();
  
  print('🖼️  Detected window manager: ${windowManager.toString()}');
  print('   Detection method: ${detectionInfo['detection_method']}');
  
  // Log additional environment info
  Logger.info('Window manager detection: $detectionInfo');

  _db = sqlite3.open(dbPath);

  // Create window manager-specific dependencies using factories
  try {
    _idleMonitor = IdleMonitorFactory.create(windowManager);
    _desktopEnhancer = DesktopEnhancerFactory.create(windowManager);
    _activityDetector = ActivityDetectorFactory.create(windowManager);
    _timeProvider = SystemTimeProvider();

    // Validate requirements for the detected window manager
    final idleSupported = await IdleMonitorFactory.validateRequirements(windowManager);
    final activitySupported = await ActivityDetectorFactory.validateRequirements(windowManager);
    final enhancerSupported = await DesktopEnhancerFactory.validateRequirements(windowManager);
    
    print('💡 Component availability:');
    print('   Idle monitoring: ${idleSupported ? '✅' : '❌'}');
    print('   Activity detection: ${activitySupported ? '✅' : '❌'}');
    print('   Visual enhancements: ${enhancerSupported ? '✅' : '❌'}');
    
    if (!idleSupported) {
      print('   ⚠️  Idle monitoring may not work properly');
    }
    if (!activitySupported) {
      print('   ⚠️  Activity detection will fall back to legacy polling');
    }
    if (!enhancerSupported) {
      print('   ⚠️  Visual enhancements may be limited');
    }

  } catch (e) {
    print('❌ Error creating window manager components: $e');
    print('   Falling back to legacy mode...');
    
    // Fallback to original Hyprland implementations (import at top of file)
    // Note: This requires adding imports back if needed
    Logger.error('Component creation failed, falling back to legacy mode: $e');
    exit(1); // For now, exit on component creation failure
  }

  // Create monitor with dependency injection
  _monitor = ProductivityMonitor(
    db: _db,
    idleMonitor: _idleMonitor,
    timeProvider: _timeProvider,
    desktopEnhancer: _desktopEnhancer,
    activityDetector: _activityDetector, // May be null for fallback to legacy polling
  );

  _dashboardServer = DashboardServer.withDatabase(DatabaseManager(_db));

  ProcessSignal.sigint.watch().listen((_) async {
    Logger.info('Shutting down XP Nix...');
    print('\nShutting down...');
    _quit();
  });

  // Start the dashboard server
  try {
    await _dashboardServer.start(port);
    Logger.info('Dashboard available at: ${_dashboardServer.dashboardUrl}');
    print('🌐 Dashboard available at: ${_dashboardServer.dashboardUrl}');
  } catch (e) {
    Logger.error('Failed to start dashboard server: $e');
    print('⚠️  Dashboard server failed to start: $e');
    _quit();
  }

  _monitor.start();
  _monitor.printDetailedStats();

  // Add command listener for manual controls
  stdin.transform(utf8.decoder).transform(LineSplitter()).listen((line) {
    final parts = line.trim().split(' ');
    final command = parts[0].toLowerCase();

    switch (command) {
      case 'stats':
        _monitor.printDetailedStats();
        break;
      case 'test':
        if (parts.length > 1) {
          final levelOrCommand = parts[1].toLowerCase();
          if (levelOrCommand == 'overlay') {
            _testOverlay(parts.length > 2 ? int.tryParse(parts[2]) : null);
          } else {
            final level = int.tryParse(levelOrCommand) ?? 1;
            _monitor.testTheme(level);
          }
        } else {
          print('Usage: test [level|overlay] - Specify a level number or "overlay" to test XP overlay');
        }
        break;
      case 'restore':
        _monitor.restoreDesktop();
        break;
      case 'refresh':
        _monitor.refreshConfig();
        break;
      case 'build':
        _handleBuildCommand();
        break;
      case 'help':
        print('''
Available commands:
- stats: Show current productivity stats
- test [level]: Test theme for specific level
- test overlay [value]: Test XP overlay at cursor position
- restore: Restore desktop backup
- refresh: Refresh base config from current system config
- build: Build Flutter dashboard and copy to static files
- help: Show this help
        ''');
        break;
    }
  });

  print('💡 Type "help" for available commands');

  // Keep running and show stats periodically
  while (true) {
    await Future.delayed(Duration(seconds: 1));

    if (DateTime.now().second == 0 && DateTime.now().minute % 10 == 0) {
      _monitor.printDetailedStats();
    }
  }
}

/// Handles the build command to rebuild the Flutter dashboard
void _handleBuildCommand() async {
  print('🚀 Starting dashboard build process...');

  // Check if Flutter is available
  if (!await DashboardBuilder.checkFlutterAvailable()) {
    print('❌ Flutter is not available in the system PATH');
    print('   Please ensure Flutter is installed and available in your PATH');
    return;
  }

  // Build the dashboard
  final success = await DashboardBuilder.buildDashboard();

  if (success) {
    print('🎉 Dashboard build completed successfully!');
    print('   The server is now serving the updated Flutter dashboard');
  } else {
    print('❌ Dashboard build failed. Check the logs for more details.');
  }
}

/// Test the XP overlay with an optional XP value
Future<void> _testOverlay(int? xpValue) async {
  print('🧪 Testing XP overlay system...');
  final windowManager = WindowManagerDetector.instance.detect();
  
  if (windowManager == WindowManager.unknown) {
    print('❌ No supported window manager detected');
    return;
  }
  
  final overlayManager = _monitor.cursorOverlayManager;
  if (overlayManager == null) {
    print('❌ Overlay manager not initialized');
    return;
  }
  
  final available = await overlayManager.isAvailable();
  if (!available) {
    print('❌ Overlay system is not available. Check logs for details.');
    return;
  }
  
  print('✅ Overlay system is available, showing test overlay...');
  await overlayManager.testOverlay(testXP: xpValue ?? 42);
}

Future<void> _quit() async {
  _monitor.stop();
  await _dashboardServer.stop();
  await Logger.instance.dispose();
  _db.dispose();
  exit(0);
}
