import 'dart:io';
import 'package:xp_nix/src/config/hyprland_config_parser.dart';

import '../interfaces/i_desktop_enhancer.dart';

class HyprlandEnhancer implements IDesktopEnhancer {
  String _currentTheme = 'default';
  final String _configPath = '/home/nate/.config/hypr/hyprland.conf';
  final String _backupPath = '/home/nate/.config/hypr/hyprland.conf.backup';
  String? _cachedBaseConfig;

  // Parse the current system config and extract base configuration
  Future<String> _getBaseConfig() async {
    if (_cachedBaseConfig != null) {
      return _cachedBaseConfig!;
    }

    try {
      final parsedConfig = await HyprlandConfigParser.parseConfigFile(_configPath);
      _cachedBaseConfig = parsedConfig.baseConfig;
      return _cachedBaseConfig!;
    } catch (e) {
      print('Warning: Could not read system config, $e\nAborting.');
      rethrow;
    }
  }

  @override
  Future<void> celebrateLevelUp(int level) async {
    print('🎉 Celebrating level up to $level!');
    await applyThemeForLevel(level);

    // Send celebration notification
    try {
      await Process.run('notify-send', [
        '🎉 LEVEL UP!',
        'Welcome to Level $level!\nYour desktop has been enhanced!',
        '--urgency=normal',
        '--expire-time=5000',
      ]);
    } catch (e) {
      print('Could not send level up notification: $e');
    }
  }

  @override
  Future<void> applyThemeForLevel(int level) async {
    String theme = 'default';

    if (level >= 25) {
      theme = 'legendary';
    } else if (level >= 15) {
      theme = 'master';
    } else if (level >= 10) {
      theme = 'advanced';
    } else if (level >= 5) {
      theme = 'intermediate';
    }

    _currentTheme = theme;
    print('🎨 Applied theme: $theme for level $level');

    // Apply visual enhancements based on level
    await _applyVisualEffects(level);
  }

  Future<void> _applyVisualEffects(int level) async {
    try {
      // Create backup if it doesn't exist
      await _createBackupIfNeeded();

      // Generate config for this level
      final config = await _generateConfigForLevel(level);

      // Try to apply via hyprctl first (for dynamic changes)
      await _applyDynamicChanges(level);

      // Write the full config file
      await _writeConfig(config);

      // Reload Hyprland to apply changes
      await _reloadHyprland();

      print('✅ Successfully applied level $level configuration');
    } catch (e) {
      print('❌ Could not apply visual effects: $e');
    }
  }

  Future<void> _createBackupIfNeeded() async {
    final backupFile = File(_backupPath);
    if (!backupFile.existsSync()) {
      final configFile = File(_configPath);
      if (configFile.existsSync()) {
        await configFile.copy(_backupPath);
        print('📋 Created backup at $_backupPath');
      }
    }
  }

  Future<String> _generateConfigForLevel(int level) async {
    final baseConfig = await _getBaseConfig();
    final decorationConfig = _getDecorationConfig(level);
    final generalConfig = _getGeneralConfig(level);
    final animationConfig = _getAnimationConfig(level);

    return baseConfig + decorationConfig + generalConfig + animationConfig;
  }

  String _getDecorationConfig(int level) {
    if (level >= 25) {
      // Legendary - Maximum effects
      return '''
decoration {
  blur {
    enabled=true
    passes=3
    size=15
    brightness=1.1
    contrast=1.2
    noise=0.02
    vibrancy=0.3
    vibrancy_darkness=0.2
  }
  
  shadow {
    enabled=true
    range=20
    render_power=4
    color=rgba(7e5fddaa)
    offset=0 0
  }
  
  dim_inactive=true
  dim_strength=0.15
  inactive_opacity=0.85
  active_opacity=1.0
  rounding=20
  
  drop_shadow=true
}
''';
    } else if (level >= 15) {
      // Master - Advanced effects
      return '''
decoration {
  blur {
    enabled=true
    passes=2
    size=12
    brightness=1.05
    contrast=1.1
    noise=0.01
    vibrancy=0.2
  }
  
  shadow {
    enabled=true
    range=15
    render_power=3
    color=rgba(7e5fdd88)
    offset=0 0
  }
  
  dim_inactive=true
  dim_strength=0.12
  inactive_opacity=0.88
  active_opacity=1.0
  rounding=16
  
  drop_shadow=true
}
''';
    } else if (level >= 10) {
      // Advanced - Enhanced blur and shadows
      return '''
decoration {
  blur {
    enabled=true
    passes=2
    size=10
    brightness=1.0
    contrast=1.05
  }
  
  shadow {
    enabled=true
    range=10
    render_power=2
    color=rgba(7e5fdd66)
  }
  
  dim_inactive=true
  dim_strength=0.10
  inactive_opacity=0.90
  rounding=12
}
''';
    } else if (level >= 5) {
      // Intermediate - Basic blur
      return '''
decoration {
  blur {
    enabled=true
    passes=1
    size=8
  }
  
  shadow {
    enabled=false
  }
  
  dim_inactive=true
  dim_strength=0.08
  inactive_opacity=0.92
  rounding=8
}
''';
    } else {
      // Default - Minimal effects
      return '''
decoration {
  blur {
    enabled=false
  }
  
  shadow {
    enabled=false
  }
  
  dim_inactive=false
  inactive_opacity=1.0
  rounding=4
}
''';
    }
  }

  String _getGeneralConfig(int level) {
    if (level >= 25) {
      // Legendary - Animated borders
      return '''
general {
  border_size=4
  col.active_border=rgba(7e5fddff) rgba(ff5100ff) rgba(00ff88ff) 45deg
  col.inactive_border=rgba(595959aa)
  gaps_in=4
  gaps_out=8
  resize_on_border=true
  extend_border_grab_area=15
}
''';
    } else if (level >= 15) {
      // Master - Gradient borders
      return '''
general {
  border_size=3
  col.active_border=rgba(7e5fddff) rgba(ff5100ff) 60deg
  col.inactive_border=rgba(59595988)
  gaps_in=3
  gaps_out=6
  resize_on_border=true
}
''';
    } else if (level >= 10) {
      // Advanced - Colored borders
      return '''
general {
  border_size=3
  col.active_border=rgba(7e5fddff)
  col.inactive_border=rgba(59595966)
  gaps_in=3
  gaps_out=5
}
''';
    } else if (level >= 5) {
      // Intermediate - Thin borders
      return '''
general {
  border_size=2
  col.active_border=rgba(7e5fddcc)
  col.inactive_border=rgba(59595944)
  gaps_in=2
  gaps_out=4
}
''';
    } else {
      // Default - Minimal borders
      return '''
general {
  border_size=1
  col.active_border=rgba(7e5fddaa)
  col.inactive_border=rgba(59595922)
  gaps_in=1
  gaps_out=2
}
''';
    }
  }

  String _getAnimationConfig(int level) {
    if (level >= 25) {
      // Legendary - Full animations
      return '''
animation=windows, 1, 8, easeout, slide
animation=windowsOut, 1, 8, easeout, slide
animation=border, 1, 10, easeout
animation=borderangle, 1, 8, easeout
animation=fade, 1, 7, easeout
animation=workspaces, 1, 6, easeout, slide
animation=specialWorkspace, 1, 6, easeout, slidevert
''';
    } else if (level >= 15) {
      // Master - Enhanced animations
      return '''
animation=windows, 1, 6, easeout, slide
animation=windowsOut, 1, 6, easeout, slide
animation=border, 1, 8, easeout
animation=fade, 1, 5, easeout
animation=workspaces, 1, 4, easeout, slide
''';
    } else if (level >= 10) {
      // Advanced - Smooth animations
      return '''
animation=windows, 1, 4, easeout
animation=windowsOut, 1, 4, easeout
animation=fade, 1, 4, easeout
animation=workspaces, 1, 3, easeout
''';
    } else if (level >= 5) {
      // Intermediate - Basic animations
      return '''
animation=windows, 1, 3, easeout
animation=fade, 1, 3, easeout
animation=workspaces, 1, 2, easeout
''';
    } else {
      // Default - Minimal animations
      return '''
animation=workspaces, 1, 1, easeout
''';
    }
  }

  Future<void> _applyDynamicChanges(int level) async {
    try {
      // Apply some changes via hyprctl for immediate effect
      if (level >= 10) {
        await Process.run('hyprctl', ['keyword', 'decoration:blur:enabled', 'true']);
        await Process.run('hyprctl', [
          'keyword',
          'decoration:blur:passes',
          level >= 25
              ? '3'
              : level >= 15
              ? '2'
              : '1',
        ]);
      } else {
        await Process.run('hyprctl', ['keyword', 'decoration:blur:enabled', 'false']);
      }

      if (level >= 15) {
        await Process.run('hyprctl', ['keyword', 'decoration:shadow:enabled', 'true']);
      } else {
        await Process.run('hyprctl', ['keyword', 'decoration:shadow:enabled', 'false']);
      }

      // Set border size
      final borderSize =
          level >= 25
              ? '4'
              : level >= 10
              ? '3'
              : level >= 5
              ? '2'
              : '1';
      await Process.run('hyprctl', ['keyword', 'general:border_size', borderSize]);

      // Set rounding
      final rounding =
          level >= 25
              ? '20'
              : level >= 15
              ? '16'
              : level >= 10
              ? '12'
              : level >= 5
              ? '8'
              : '4';
      await Process.run('hyprctl', ['keyword', 'decoration:rounding', rounding]);
    } catch (e) {
      print('Warning: Could not apply some dynamic changes: $e');
    }
  }

  Future<void> _writeConfig(String config) async {
    final configFile = File(_configPath);
    await configFile.writeAsString(config);
    print('📝 Updated configuration file');
  }

  Future<void> _reloadHyprland() async {
    try {
      await Process.run('hyprctl', ['reload']);
      print('🔄 Reloaded Hyprland configuration');
    } catch (e) {
      print('Warning: Could not reload Hyprland: $e');
    }
  }

  @override
  String getCurrentThemeInfo() {
    return 'Theme: $_currentTheme';
  }

  // Refresh the cached base config from the current system config
  @override
  Future<void> refreshBaseConfig() async {
    _cachedBaseConfig = null; // Clear cache
    try {
      final baseConfig = await _getBaseConfig();
      print('🔄 Refreshed base config from system (${baseConfig.split('\n').length} lines)');
    } catch (e) {
      print('❌ Could not refresh base config: $e');
    }
  }

  @override
  Future<void> restoreBackup() async {
    try {
      final backupFile = File(_backupPath);
      if (backupFile.existsSync()) {
        await backupFile.copy(_configPath);
        await _reloadHyprland();
        print('🔧 Restored desktop from backup');
        _currentTheme = 'default';
        // Clear cached config since we restored from backup
        _cachedBaseConfig = null;
      } else {
        print('❌ No backup found at $_backupPath');
      }
    } catch (e) {
      print('❌ Could not restore backup: $e');
    }
  }
}
