import 'dart:async';
import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
import 'performance_test.dart'; // Make sure this path is correct

/// Analyzes various device hardware and software aspects to generate a compatibility score.
/// This class provides a standardized output for the UI to consume easily.
class DeviceAnalyzer {
  final DeviceInfoPlugin _deviceInfo = DeviceInfoPlugin();

  /// Reads the total RAM from the system's meminfo file.
  /// Returns the value in Megabytes (MB).
  Future<double> _readTotalRamMB() async {
    try {
      final file = File('/proc/meminfo');
      if (!await file.exists()) return 0.0;
      final lines = await file.readAsLines();
      for (var line in lines) {
        if (line.startsWith('MemTotal')) {
          // Extracts the numeric value from the line.
          final kb = int.tryParse(RegExp(r'\d+').stringMatch(line) ?? '0') ?? 0;
          return kb / 1024.0; // Convert from Kilobytes to Megabytes
        }
      }
    } catch (e) {
      print('❌ Error reading total RAM: $e');
    }
    return 0.0;
  }

  /// Reads the current RAM usage percentage from the system's meminfo file.
  Future<double> _readUsedRamPercent() async {
    try {
      final file = File('/proc/meminfo');
      if (!await file.exists()) return 0.0;
      final lines = await file.readAsLines();
      int? total, available;
      for (var line in lines) {
        if (line.startsWith('MemTotal')) {
          total = int.tryParse(RegExp(r'\d+').stringMatch(line) ?? '');
        } else if (line.startsWith('MemAvailable')) {
          available = int.tryParse(RegExp(r'\d+').stringMatch(line) ?? '');
        }
      }
      if (total != null && available != null && total > 0) {
        final used = total - available;
        return (used / total) * 100.0;
      }
    } catch (e) {
      print('❌ Error reading used RAM: $e');
    }
    return 0.0;
  }

  /// The main analysis function that runs all checks.
  Future<Map<String, dynamic>> analyzeDevice() async {
    List<Map<String, dynamic>> details = [];

    if (!Platform.isAndroid) {
      return {
        'score': 0,
        'details': [
          {
            'label': 'النظام غير مدعوم',
            'status': false,
            'achieved_score': 0,
            'max_score': 100
          }
        ]
      };
    }

    final info = await _deviceInfo.androidInfo;
    final data = info.data;
    final features = List<String>.from(data['systemFeatures'] ?? []);

    // 1. Android Version (Max: 10 points)
    final version =
        int.tryParse(info.version.release?.split('.').first ?? '0') ?? 0;
    final int androidScore = version >= 9 ? 10 : 0;
    details.add({
      'label': 'إصدار أندرويد ${info.version.release}',
      'status': androidScore > 0,
      'achieved_score': androidScore,
      'max_score': 10,
    });

    // 2. Total RAM (Max: 10 points)
    final totalRam = await _readTotalRamMB();
    int ramScore;
    if (totalRam >= 8000) {
      ramScore = 10;
    } else if (totalRam >= 4000) {
      ramScore = 5;
    } else if (totalRam >= 3000) {
      ramScore = 3;
    } else {
      ramScore = 0;
    }
    details.add({
      'label': 'إجمالي الرام ${totalRam.toStringAsFixed(0)} ميجابايت',
      'status': ramScore >= 5,
      'achieved_score': ramScore,
      'max_score': 10,
    });

    // 3. CPU Cores (Max: 10 points)
    final cores = Platform.numberOfProcessors;
    int coreScore = cores >= 6 ? 10 : (cores >= 4 ? 5 : 0);
    details.add({
      'label': 'أنوية المعالج ($cores)',
      'status': coreScore >= 5,
      'achieved_score': coreScore,
      'max_score': 10,
    });

    // 4. Free Storage (Max: 5 points)
    final freeBytes = data['freeDiskSize'] ?? 0;
    final freeGB = freeBytes / (1024 * 1024 * 1024);
    int storeScore = freeGB >= 5 ? 5 : (freeGB >= 2 ? 3 : 0);
    details.add({
      'label': 'المساحة الحرة ${freeGB.toStringAsFixed(1)} جيجابايت',
      'status': storeScore >= 3,
      'achieved_score': storeScore,
      'max_score': 5,
    });

    // 5. GPS + Gyroscope Sensors (Max: 10 points)
    bool okSensors = features.contains('android.hardware.location.gps') &&
        features.contains('android.hardware.sensor.gyroscope');
    final int sensorScore = okSensors ? 10 : 0;
    details.add({
      'label': 'حساسات GPS و Gyroscope',
      'status': okSensors,
      'achieved_score': sensorScore,
      'max_score': 10,
    });

    // 6. Storage Write Speed (Max: 20 points)
    final writeSpeed = await PerformanceTester.testStorageWriteSpeed();
    int writeScore;
    if (writeSpeed >= 30) {
      writeScore = 20;
    } else if (writeSpeed >= 15) {
      writeScore = 15;
    } else if (writeSpeed >= 5) {
      writeScore = 10;
    } else {
      writeScore = 5;
    }
    details.add({
      'label': 'سرعة الكتابة (${writeSpeed.toStringAsFixed(1)} MB/s)',
      'status': writeScore >= 10,
      'achieved_score': writeScore,
      'max_score': 20,
    });

    // 7. CPU Compute Speed (Max: 20 points)
    final cpuTime = await PerformanceTester.testCPUSpeed();
    int cpuScore;
    if (cpuTime <= 1.0) {
      cpuScore = 20;
    } else if (cpuTime <= 2.5) {
      cpuScore = 15;
    } else if (cpuTime <= 4.0) {
      cpuScore = 10;
    } else {
      cpuScore = 5;
    }
    details.add({
      'label': 'سرعة المعالجة (${cpuTime.toStringAsFixed(2)} ثانية)',
      'status': cpuScore >= 10,
      'achieved_score': cpuScore,
      'max_score': 20,
    });

    // 8. Memory Pressure (Max: 15 points)
    final usedPercent = await _readUsedRamPercent();
    int memScore;
    if (usedPercent <= 60) {
      memScore = 15;
    } else if (usedPercent <= 80) {
      memScore = 10;
    } else if (usedPercent <= 90) {
      memScore = 5;
    } else {
      memScore = 0;
    }
    details.add({
      'label': 'استخدام الرام الحالي (${usedPercent.toStringAsFixed(0)}%)',
      'status': memScore >= 10,
      'achieved_score': memScore,
      'max_score': 15,
    });

    // Calculate the final total score by summing up the achieved scores.
    final totalScore = details.fold<int>(
        0, (sum, item) => sum + (item['achieved_score'] as int));

    return {
      'score': totalScore.clamp(0, 100),
      'details': details,
    };
  }
}
