import 'dart:io';
import 'package:logging/logging.dart';
import '../models/client_status.dart';
import '../utils/path_utils.dart';

/// 系统信息获取服务
class SystemInfoService {
  static final SystemInfoService _instance = SystemInfoService._internal();
  factory SystemInfoService() => _instance;
  SystemInfoService._internal();

  final Logger _logger = Logger('SystemInfoService');

  /// 获取机器码（使用硬盘序列号）
  Future<String> getMachineCode() async {
    try {
      if (Platform.isWindows) {
        // 延迟执行，避免启动时崩溃
        await Future.delayed(const Duration(seconds: 3));
        
        // 使用 wmic 获取硬盘序列号
        try {
          final result = await Process.run(
            'wmic',
            ['diskdrive', 'get', 'serialnumber'],
            runInShell: true,
          );
          
          if (result.exitCode == 0) {
            final output = result.stdout.toString();
            final lines = output.split('\n');
            
            // 查找序列号（跳过标题行）
            for (final line in lines) {
              final trimmed = line.trim();
              if (trimmed.isNotEmpty && 
                  !trimmed.toLowerCase().contains('serialnumber') &&
                  trimmed != '') {
                // 提取序列号（去除空格）
                final serial = trimmed.replaceAll(RegExp(r'\s+'), '');
                if (serial.isNotEmpty) {
                  _logger.info('获取到硬盘序列号: $serial');
                  return serial;
                }
              }
            }
          }
          
          _logger.warning('wmic 命令执行成功但未找到有效序列号');
        } catch (e) {
          _logger.warning('使用 wmic 获取硬盘序列号失败: $e');
        }
        
        // 备用方案：使用环境变量生成标识符
        final computerName = Platform.environment['COMPUTERNAME'] ?? 'UNKNOWN';
        final userName = Platform.environment['USERNAME'] ?? 'UNKNOWN';
        final userProfile = Platform.environment['USERPROFILE'] ?? '';
        
        final identifier = '${computerName}_${userName}_${userProfile.hashCode.abs()}';
        _logger.info('使用备用标识符作为机器码: $identifier');
        return identifier;
      }
      
      // 非 Windows 系统
      _logger.warning('无法获取机器码，使用临时标识');
      return 'UNKNOWN_${DateTime.now().millisecondsSinceEpoch}';
    } catch (e) {
      _logger.severe('获取机器码失败: $e');
      // 不抛出异常，返回临时标识
      return 'ERROR_${DateTime.now().millisecondsSinceEpoch}';
    }
  }

  /// 获取GPU信息（仅在启动时调用一次）
  Future<List<GPUInfo>> getGPUInfo() async {
    try {
      // 使用 nvidia-smi 获取GPU信息
      final result = await Process.run(
        'nvidia-smi',
        ['--query-gpu=index,name,memory.total', '--format=csv,noheader,nounits'],
        runInShell: true,
      ).timeout(
        const Duration(seconds: 10),
        onTimeout: () {
          _logger.warning('nvidia-smi 执行超时');
          return ProcessResult(0, -1, '', 'timeout');
        },
      );

      if (result.exitCode != 0) {
        _logger.warning('nvidia-smi 执行失败: exitCode=${result.exitCode}, stderr=${result.stderr}');
        return [];
      }

      final output = result.stdout.toString().trim();
      if (output.isEmpty) {
        _logger.info('nvidia-smi 返回空输出，未检测到GPU');
        return [];
      }

      final lines = output.split('\n');
      final gpus = <GPUInfo>[];

      for (final line in lines) {
        if (line.trim().isEmpty) continue;
        
        final parts = line.split(', ');
        if (parts.length >= 3) {
          try {
            final index = int.parse(parts[0].trim());
            final model = parts[1].trim();
            final memoryStr = parts[2].trim();
            final memory = double.tryParse(memoryStr) ?? 0;

            gpus.add(GPUInfo(
              index: index,
              brand: 'NVIDIA',
              model: model,
              memory: memory,
            ));
            
            _logger.info('检测到GPU: 索引=$index, 型号=$model, 显存=${memory}MB');
          } catch (e) {
            _logger.warning('解析GPU信息失败: $line, 错误: $e');
          }
        }
      }

      if (gpus.isEmpty) {
        _logger.info('未检测到GPU');
      } else {
        _logger.info('成功获取 ${gpus.length} 个GPU信息');
      }
      return gpus;
    } catch (e) {
      _logger.warning('获取GPU信息失败: $e');
      // 不抛出异常，返回空列表，UI会显示"未检测到GPU"
      return [];
    }
  }

  /// 读取版本号（从根目录 bin/version 文件）
  Future<String> getVersion() async {
    try {
      final versionPath = PathUtils.binFile('version');
      final file = File(versionPath);
      if (await file.exists()) {
        final content = await file.readAsString();
        return content.trim();
      } else {
        _logger.warning('版本文件不存在: $versionPath');
      }
    } catch (e) {
      _logger.warning('读取版本号失败: $e');
    }
    return '未知版本';
  }

  /// 读取身份信息（从根目录 bin/auth 文件）
  Future<String> getAuth() async {
    try {
      final authPath = PathUtils.binFile('auth');
      final file = File(authPath);
      if (await file.exists()) {
        final content = await file.readAsString();
        return content.trim();
      } else {
        _logger.warning('身份文件不存在: $authPath');
      }
    } catch (e) {
      _logger.warning('读取身份信息失败: $e');
    }
    return '未配置';
  }

  /// 检查管理员权限（Windows）
  Future<bool> checkAdminPermission() async {
    if (!Platform.isWindows) {
      return true;
    }

    try {
      // 由于 Process.run 会导致崩溃，这里使用环境变量判断
      // 如果存在管理员相关的环境变量，可能具有管理员权限
      // 这是一个简化的判断，可能不准确，但不会崩溃
      final userProfile = Platform.environment['USERPROFILE'];
      if (userProfile != null && userProfile.contains('Administrator')) {
        return true;
      }
      // 默认返回 false，表示可能没有管理员权限
      _logger.info('无法准确检测管理员权限（避免 Process.run 崩溃），返回 false');
      return false;
    } catch (e) {
      _logger.warning('检查管理员权限失败: $e');
      return false;
    }
  }
}
