import 'package:flutter_udid/flutter_udid.dart';
import 'package:kaer_with_panels/app/utils/kr_log_util.dart';
import 'package:kaer_with_panels/app/utils/kr_secure_storage.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'dart:io';
import 'dart:convert';
import 'package:crypto/crypto.dart';

/// 设备工具类
class KRDeviceUtil {
  static final KRDeviceUtil _instance = KRDeviceUtil._internal();
  
  /// 设备ID缓存
  String? _kr_cachedDeviceId;
  
  /// 存储键
  static const String _kr_deviceIdKey = 'kr_device_id';
  
  /// 存储实例
  final KRSecureStorage _kr_storage = KRSecureStorage();

  KRDeviceUtil._internal(); 

  factory KRDeviceUtil() => _instance;

  /// 获取设备ID
  /// 如果获取失败，返回空字符串
  Future<String> kr_getDeviceId() async {
 
    try {
      if (_kr_cachedDeviceId != null) {
        return _kr_cachedDeviceId!;
      }

      // 先从存储中获取
      final String? kr_savedDeviceId = await _kr_storage.kr_readData(key: _kr_deviceIdKey);
      if (kr_savedDeviceId != null) {
        _kr_cachedDeviceId = kr_savedDeviceId;
        return _kr_cachedDeviceId!;
      }

      // 根据不同平台获取设备ID
      if (Platform.isMacOS || Platform.isWindows ) {
        // 获取系统信息
        final PackageInfo kr_packageInfo = await PackageInfo.fromPlatform();
        final String kr_platform = Platform.operatingSystem;
        final String kr_version = Platform.operatingSystemVersion;
        final String kr_localHostname = Platform.localHostname;
        
        // 组合信息生成唯一ID
        final String kr_deviceInfo = '$kr_platform-$kr_version-$kr_localHostname-${kr_packageInfo.packageName}-${kr_packageInfo.buildNumber}';
        _kr_cachedDeviceId = md5.convert(utf8.encode(kr_deviceInfo)).toString();
      } else if (Platform.isIOS || Platform.isAndroid  )  {
       
        _kr_cachedDeviceId = await FlutterUdid.udid;
      } else {
        KRLogUtil.kr_e('不支持的平台: ${Platform.operatingSystem}', tag: 'DeviceUtil');
        return '';
      }

      // 保存到存储中
      if (_kr_cachedDeviceId != null) {
        await _kr_storage.kr_saveData(key: _kr_deviceIdKey, value: _kr_cachedDeviceId!);
      }

      KRLogUtil.kr_i('获取设备ID: $_kr_cachedDeviceId', tag: 'DeviceUtil');
      return _kr_cachedDeviceId ?? '';
    } catch (e) {
      KRLogUtil.kr_e('获取设备ID失败: $e', tag: 'DeviceUtil');
      return '';
    }
  }

  /// 清除缓存的设备ID
  void kr_clearDeviceId() {
    _kr_cachedDeviceId = null;
    _kr_storage.kr_deleteData(key: _kr_deviceIdKey);
  }

  /// 从桌面平台提取邀请码 (深度检测)
  /// 1. 检测执行路径 (支持重命名的 .app 或二进制)
  /// 2. (MacOS) 检测挂载源 (支持重命名的 DMG)
  /// 3. (MacOS) 检测来源元数据 (支持从下载链接中识别)
  Future<String> kr_getDesktopInviteCode() async {
    if (!Platform.isMacOS && !Platform.isWindows) return '';
    try {
      final String executablePath = Platform.resolvedExecutable;
      KRLogUtil.kr_i('🔍 [DEBUG] 桌面端开始深度解析邀请码, 当前路径: $executablePath', tag: 'DeviceUtil');

      // 策略 1: 直接匹配路径 (最快)
      String? code = _kr_extractCode(executablePath);
      if (code != null) return code;

      // 策略 1.5: (Windows 独有) 检测安装目录下的 channel.txt (支持 Inno Setup 方案)
      if (Platform.isWindows) {
        code = await _kr_getInviteCodeFromChannelFile(executablePath);
        if (code != null) {
          KRLogUtil.kr_i('🎯 从 channel.txt 获取到邀请码: $code', tag: 'DeviceUtil');
          return code;
        }
      }

      if (Platform.isMacOS) {
        // 策略 2: 如果在 /Volumes 下运行，尝试找 DMG 原文件名
        if (executablePath.contains('/Volumes/')) {
          code = await _kr_getInviteCodeFromHdiutil(executablePath);
          if (code != null) {
            KRLogUtil.kr_i('🎯 从 hdiutil (挂载源) 获取到邀请码: $code', tag: 'DeviceUtil');
            return code;
          }
        }

        // 策略 3: 检查文件的来源元数据 (kMDItemWhereFroms)
        code = await _kr_getInviteCodeFromMetadata(executablePath);
        if (code != null) {
          KRLogUtil.kr_i('🎯 从 mdls (文件元数据) 获取到邀请码: $code', tag: 'DeviceUtil');
          return code;
        }
      }

      // 策略 4: 在下载目录下寻找最近的带有 ic- 的程序 (MacOS/Windows 通用)
      code = await _kr_searchDownloadsForInviteCode();
      if (code != null) {
        KRLogUtil.kr_i('🎯 从下载目录搜索获取到邀请码: $code', tag: 'DeviceUtil');
        return code;
      }

      KRLogUtil.kr_i('⚠️ 深度检测完成，未发现有效的邀请码标识', tag: 'DeviceUtil');
    } catch (e) {
      KRLogUtil.kr_e('解析桌面邀请码异常: $e', tag: 'DeviceUtil');
    }
    return '';
  }

  /// (MacOS/Windows) 在下载目录下搜寻最近的、符合命名规范的安装包
  Future<String?> _kr_searchDownloadsForInviteCode() async {
    try {
      // 适配不同平台的家目录环境变量
      final String home = Platform.environment['HOME'] ?? 
                          Platform.environment['USERPROFILE'] ?? '';
      if (home.isEmpty) return null;
      
      final Directory downloads = Directory('${home}${Platform.pathSeparator}Downloads');
      if (!await downloads.exists()) return null;

      final List<FileSystemEntity> files = await downloads.list().toList();
      String? bestMatch;
      DateTime? latestDate;

      for (var file in files) {
        if (file is File && file.path.contains('ic-') && (file.path.endsWith('.dmg') || file.path.endsWith('.exe'))) {
           // 提取代码
           final code = _kr_extractCode(file.path);
           if (code != null) {
             final stat = await file.stat();
             if (latestDate == null || stat.modified.isAfter(latestDate)) {
               latestDate = stat.modified;
               bestMatch = code;
             }
           }
        }
      }
      return bestMatch;
    } catch (_) {}
    return null;
  }

  /// (Windows) 从安装目录下的 channel.txt 中读取邀请码 (针对 Inno Setup 方案)
  Future<String?> _kr_getInviteCodeFromChannelFile(String execPath) async {
    try {
      final File exeFile = File(execPath);
      final String dirPath = exeFile.parent.path;
      final File channelFile = File('$dirPath${Platform.pathSeparator}channel.txt');
      
      if (await channelFile.exists()) {
        final String content = await channelFile.readAsString();
        final String channel = content.trim();
        if (channel.isNotEmpty) {
          // 兼容两种格式：纯邀请码 或 带 ic- 标识的邀请码
          if (channel.contains('ic-')) {
            return _kr_extractCode(channel);
          }
          return channel; // 如果 Inno Setup 已经截取好了纯 code，直接返回
        }
      }
    } catch (e) {
      KRLogUtil.kr_e('读取 Windows channel.txt 失败: $e', tag: 'DeviceUtil');
    }
    return null;
  }

  /// 正则提取 ic-模式
  String? _kr_extractCode(String source) {
    final RegExp regExp = RegExp(r'ic-([A-Za-z0-9-_]+)');
    final Match? match = regExp.firstMatch(source);
    if (match != null && match.groupCount >= 1) {
      final String code = match.group(1) ?? '';
      KRLogUtil.kr_i('✅ [DEBUG] 成功匹配到邀请码: $code (源: $source)', tag: 'DeviceUtil');
      return code;
    }
    return null;
  }

  /// (MacOS) 通过 hdiutil 查找挂载卷对应的原始 DMG 路径
  Future<String?> _kr_getInviteCodeFromHdiutil(String execPath) async {
    try {
      final ProcessResult result = await Process.run('hdiutil', ['info']);
      if (result.exitCode == 0) {
        final String output = result.stdout.toString();
        // 寻找每个条目包含的 image-path 和 实际挂载路径
        final List<String> segments = output.split('================================================');
        for (var segment in segments) {
          if (!segment.contains('image-path')) continue;
          
          String? imagePath;
          String? mountPoint;
          
          final List<String> lines = segment.split('\n');
          for (var line in lines) {
            final String trimmedLine = line.trim();
            if (trimmedLine.isEmpty) continue;

            if (trimmedLine.contains('image-path')) {
              final int colonIndex = trimmedLine.indexOf(':');
              if (colonIndex != -1) {
                imagePath = trimmedLine.substring(colonIndex + 1).trim();
              }
            } 
            // 匹配类似: /dev/disk8s1  7C3457EF...  /Volumes/HiFastVPN Installation
            // 或者是正常的 mount-point 键值对
            else if (trimmedLine.contains('/Volumes/')) {
              if (trimmedLine.contains('mount-point')) {
                 final int colonIndex = trimmedLine.indexOf(':');
                 if (colonIndex != -1) {
                   mountPoint = trimmedLine.substring(colonIndex + 1).trim();
                 }
              } else if (trimmedLine.startsWith('/dev/')) {
                 // 提取路径：通常在最后一个制表符或空格序列之后
                 final int volumesIndex = trimmedLine.indexOf('/Volumes/');
                 if (volumesIndex != -1) {
                   mountPoint = trimmedLine.substring(volumesIndex).trim();
                 }
              }
            }
          }
          
          if (imagePath != null && mountPoint != null) {
            final normalizedMount = mountPoint.endsWith('/') ? mountPoint.substring(0, mountPoint.length - 1) : mountPoint;
            if (execPath.startsWith(normalizedMount)) {
              KRLogUtil.kr_i('🎯 [DEBUG] 成功匹配到挂载源: $imagePath', tag: 'DeviceUtil');
              return _kr_extractCode(imagePath);
            }
          }
        }
      }
    } catch (e) {
      KRLogUtil.kr_e('❌ [DEBUG] hdiutil 追溯异常: $e', tag: 'DeviceUtil');
    }
    return null;
  }

  /// (MacOS) 通过 mdls 检查文件的来源下载链接
  Future<String?> _kr_getInviteCodeFromMetadata(String execPath) async {
    try {
      // 提取 .app 的路径
      final int appIndex = execPath.indexOf('.app');
      final String targetPath = appIndex != -1 
          ? execPath.substring(0, appIndex + 4) 
          : execPath;

      final ProcessResult result = await Process.run('mdls', ['-name', 'kMDItemWhereFroms', targetPath]);
      if (result.exitCode == 0) {
        return _kr_extractCode(result.stdout.toString());
      }
    } catch (_) {}
    return null;
  }
}