import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart';
import '../core/client_core.dart';
import '../core/system_info.dart';
import '../core/mining_manager.dart';
import '../core/sustain_miner.dart';
import '../core/database.dart';
import '../core/mining_task_info.dart';
import '../services/config_service.dart';
import '../services/update_service.dart';
import '../models/client_status.dart';

/// 客户端状态管理 Provider
class ClientProvider with ChangeNotifier {
  final Logger _logger = Logger('ClientProvider');
  final ClientCore _clientCore = ClientCore();
  final SystemInfoService _systemInfo = SystemInfoService();
  final MiningManager _miningManager = MiningManager();
  final SustainMiner _sustainMiner = SustainMiner();
  final DatabaseService _database = DatabaseService();
  final ConfigService _configService = ConfigService();
  final UpdateService _updateService = UpdateService();

  Timer? _refreshTimer;
  ClientInfo? _clientInfo;
  bool _isInitialized = false;
  bool _isLoading = false;
  MiningTaskInfo? _currentMiningTask;

  // 服务器地址（从配置文件读取）
  String? _serverUrl;
  
  // 版本信息
  String? _remoteVersion;
  bool _hasUpdate = false;

  ClientProvider() {
    _initialize();
  }

  /// 初始化客户端
  Future<void> _initialize() async {
    _isLoading = true;
    notifyListeners();

    try {
      // 初始化数据库
      await _database.initialize();

      // 加载系统信息（先加载简单的文件读取，延迟执行 Process 调用）
      final version = await _systemInfo.getVersion();
      final auth = await _systemInfo.getAuth();
      
      // 检查权限
      final hasPermission = await _systemInfo.checkAdminPermission();
      if (!hasPermission) {
        _logger.warning('未检测到管理员权限');
      }

      // 加载挖矿配置
      final miningConfig = await _configService.parseMiningConfig();
      
      // 从配置文件读取服务器地址
      _serverUrl = miningConfig?.serverUrl ?? '18.183.240.108:2345';
      
      // 检查版本更新（如果有配置 update_url）
      if (miningConfig?.updateUrl != null) {
        _checkForUpdates(miningConfig!.updateUrl!, version);
      }

      // 获取机器码和GPU信息（延迟执行，避免启动时崩溃）
      // 只在启动时获取一次，如果失败就显示空列表
      String machineCode = '正在获取...';
      List<GPUInfo> gpus = [];
      
      try {
        // 延迟3秒后获取，避免启动时崩溃
        await Future.delayed(const Duration(seconds: 3));
        _logger.info('开始获取系统信息...');
        
        machineCode = await _systemInfo.getMachineCode();
        gpus = await _systemInfo.getGPUInfo();
        
        _logger.info('系统信息获取完成: MAC=$machineCode, GPUs=${gpus.length}');
      } catch (e) {
        _logger.warning('获取系统信息失败: $e');
        // 获取失败时使用默认值
        machineCode = '获取失败';
        gpus = [];
      }
      
      // 准备GPU信息（转换为服务器需要的格式）
      final gpusMap = <String, dynamic>{};
      for (var gpu in gpus) {
        gpusMap[gpu.index.toString()] = gpu.toJson();
      }

      // 获取支持的挖矿软件列表
      final miningSofts = _getMiningSofts(miningConfig);

      // 初始化客户端核心（先连接，但不发送身份认证）
      final initialized = await _clientCore.initialize(
        serverUrl: _serverUrl ?? '18.183.240.108:2345',
        auth: auth,
        machineCode: machineCode, // 此时可能还是"正在获取..."，需要等待真实值
        gpusInfo: gpusMap,
        miningSofts: miningSofts,
      );

      if (!initialized) {
        _logger.severe('客户端初始化失败');
        // 即使初始化失败，也创建 ClientInfo 以便显示基本信息
        _clientInfo = ClientInfo(
          version: version,
          auth: auth,
          gpus: gpus,
          machineCode: machineCode,
          status: ClientStatus.offline,
          miningInfo: null,
        );
        _isInitialized = true;
        _isLoading = false;
        notifyListeners();
        return;
      }

      // 设置回调
      _clientCore.onStatusChanged = _onStatusChanged;
      _clientCore.onMiningTaskChanged = _onMiningTaskChanged;
      
      // 等待机器码获取完成后，发送身份认证消息（使用 身份信息::硬盘身份码 格式）
      if (machineCode != '正在获取...' && machineCode != '获取失败') {
        // 更新客户端核心的机器码
        _clientCore.updateMachineCode(machineCode, gpusMap, miningSofts);
        // 发送身份认证消息
        _clientCore.sendMachineCode();
      }

      // 恢复未完成的挖矿任务
      final unfinishedTask = await _database.loadUnfinishedTask();
      if (unfinishedTask != null) {
        if (miningConfig != null) {
          await _miningManager.startMining(unfinishedTask, miningConfig);
          _currentMiningTask = unfinishedTask;
        }
      }

      // 加载持续挖矿配置并启动（恢复任务之后）
      if (miningConfig != null) {
        final loaded = await _sustainMiner.loadConfig(miningConfig);
        if (loaded && _currentMiningTask == null) {
          await _sustainMiner.start();
        }
      }

      // 更新客户端信息
      _clientInfo = ClientInfo(
        version: version,
        auth: auth,
        gpus: gpus.map((gpu) => GPUInfo(
          index: gpu.index,
          brand: gpu.brand,
          model: gpu.model,
          memory: gpu.memory,
        )).toList(),
        machineCode: machineCode,
        status: _getInitialStatus(),
        miningInfo: _getMiningInfo(),
      );

      _isInitialized = true;
      _startAutoRefresh();
    } catch (e, stackTrace) {
      _logger.severe('初始化失败: $e', e, stackTrace);
      // 即使初始化失败，也创建基本的 ClientInfo 以便显示错误信息
      try {
        final version = await _systemInfo.getVersion();
        final auth = await _systemInfo.getAuth();
        _clientInfo = ClientInfo(
          version: version,
          auth: auth,
          gpus: [],
          machineCode: '初始化失败',
          status: ClientStatus.offline,
          miningInfo: null,
        );
      } catch (e2) {
        _logger.severe('创建基本 ClientInfo 也失败: $e2');
        // 如果连基本信息都获取不到，至少创建一个空的信息对象
        _clientInfo = ClientInfo(
          version: '未知',
          auth: '未知',
          gpus: [],
          machineCode: '错误',
          status: ClientStatus.offline,
          miningInfo: null,
        );
      }
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 状态变化回调
  void _onStatusChanged(ClientStatus status) {
    if (_clientInfo != null) {
      // 判断当前状态：优先显示挖矿状态
      ClientStatus newStatus;
      if (_miningManager.isMining) {
        // 如果有租约任务，显示挖矿中；否则显示持续挖矿中
        newStatus = _currentMiningTask != null 
            ? ClientStatus.mining 
            : (_sustainMiner.isRunning ? ClientStatus.sustainingMining : ClientStatus.mining);
      } else {
        newStatus = status;
      }

      _clientInfo = ClientInfo(
        version: _clientInfo!.version,
        auth: _clientInfo!.auth,
        gpus: _clientInfo!.gpus,
        machineCode: _clientInfo!.machineCode,
        status: newStatus,
        miningInfo: _getMiningInfo(),
      );
      notifyListeners();
    }
  }

  /// 挖矿任务变化回调
  void _onMiningTaskChanged(MiningTaskInfo? task) async {
    final previousTask = _currentMiningTask;
    _currentMiningTask = task;

    if (task != null) {
      // 暂停持续挖矿
      await _sustainMiner.pause();

      // 启动挖矿
      final miningConfig = await _configService.parseMiningConfig();
      if (miningConfig != null) {
        await _miningManager.startMining(task, miningConfig);
        await _database.insertMiningTask(task);
      }
    } else {
      // 停止挖矿
      await _miningManager.stopMining();
      // 挖矿任务完成后，从日志中删除该任务
      if (previousTask != null) {
        await _database.finishMiningTask(previousTask);
      }
      
      // 恢复持续挖矿
      await _sustainMiner.resume();
    }

    // 更新状态
    _onStatusChanged(_clientCore.isConnected ? ClientStatus.online : ClientStatus.offline);
  }

  /// 开始自动刷新
  void _startAutoRefresh() {
    _refreshTimer?.cancel();
    _refreshTimer = Timer.periodic(const Duration(seconds: 5), (_) {
      refresh();
    });
  }

  /// 手动刷新（不重新获取GPU信息，只更新状态）
  Future<void> refresh() async {
    if (!_isInitialized || _clientInfo == null) return;

    try {
      // 只更新状态，不重新获取GPU信息（GPU信息只在启动时获取一次）
      ClientStatus status;
      if (_miningManager.isMining) {
        // 如果有租约任务，显示挖矿中；否则显示持续挖矿中
        status = _currentMiningTask != null 
            ? ClientStatus.mining 
            : (_sustainMiner.isRunning ? ClientStatus.sustainingMining : ClientStatus.mining);
      } else {
        status = _clientCore.isConnected ? ClientStatus.online : ClientStatus.offline;
      }

      _clientInfo = ClientInfo(
        version: _clientInfo!.version,
        auth: _clientInfo!.auth,
        gpus: _clientInfo!.gpus, // 使用已有的GPU信息，不重新获取
        machineCode: _clientInfo!.machineCode,
        status: status,
        miningInfo: _getMiningInfo(),
      );
      notifyListeners();
    } catch (e) {
      _logger.warning('刷新失败: $e');
    }
  }

  /// 获取初始状态
  ClientStatus _getInitialStatus() {
    if (_miningManager.isMining) {
      return _currentMiningTask != null 
          ? ClientStatus.mining 
          : (_sustainMiner.isRunning ? ClientStatus.sustainingMining : ClientStatus.mining);
    }
    return _clientCore.isConnected ? ClientStatus.online : ClientStatus.offline;
  }

  /// 获取挖矿信息（支持租约挖矿和持续挖矿）
  MiningInfo? _getMiningInfo() {
    if (_currentMiningTask != null) {
      // 租约挖矿任务
      return MiningInfo(
        coin: _currentMiningTask!.coin,
        algo: _currentMiningTask!.algo,
        pool: _currentMiningTask!.pool,
        poolUrl: _currentMiningTask!.poolUrl,
        walletAddress: _currentMiningTask!.walletAddress,
        workerId: _currentMiningTask!.workerId,
        pid: null,
        miner: _currentMiningTask!.miner,
        endTimestamp: _currentMiningTask!.endTimestamp,
      );
    } else if (_miningManager.isMining && _sustainMiner.isRunning) {
      // 持续挖矿任务
      final sustainTask = _miningManager.currentTask;
      if (sustainTask != null) {
        return MiningInfo(
          coin: sustainTask.coin,
          algo: sustainTask.algo,
          pool: sustainTask.pool,
          poolUrl: sustainTask.poolUrl,
          walletAddress: sustainTask.walletAddress,
          workerId: sustainTask.workerId,
          pid: null,
          miner: sustainTask.miner,
          endTimestamp: sustainTask.endTimestamp,
        );
      }
    }
    return null;
  }

  /// 重启客户端
  Future<void> restart() async {
    _clientCore.stop();
    await _miningManager.stopMining();
    await _sustainMiner.stop();
    
    _isInitialized = false;
    await _initialize();
  }

  /// 获取支持的挖矿软件列表（辅助方法）
  List<String> _getMiningSofts(MiningConfig? miningConfig) {
    final miningSofts = <String>[];
    if (miningConfig?.lolMinerPath != null && miningConfig!.lolMinerPath!.isNotEmpty) {
      miningSofts.add('lolminer');
    }
    if (miningConfig?.rigelPath != null && miningConfig!.rigelPath!.isNotEmpty) {
      miningSofts.add('rigel');
    }
    if (miningConfig?.bzMinerPath != null && miningConfig!.bzMinerPath!.isNotEmpty) {
      miningSofts.add('bzminer');
    }
    return miningSofts;
  }

  /// 获取日志流
  Stream<String> get logStream => _clientCore.logStream;

  ClientInfo? get clientInfo => _clientInfo;
  bool get isLoading => _isLoading;
  bool get isInitialized => _isInitialized;
  bool get hasUpdate => _hasUpdate;
  String? get remoteVersion => _remoteVersion;

  /// 检查版本更新
  Future<void> _checkForUpdates(String updateUrl, String localVersion) async {
    try {
      final remoteInfo = await _updateService.checkVersion(updateUrl);
      if (remoteInfo != null) {
        _remoteVersion = remoteInfo.version;
        _hasUpdate = _updateService.isNewerVersion(remoteInfo.version, localVersion);
        if (_hasUpdate) {
          _logger.info('发现新版本: $localVersion -> ${remoteInfo.version}');
        }
        notifyListeners();
      }
    } catch (e) {
      _logger.warning('检查更新失败: $e');
    }
  }

  /// 执行更新
  Future<bool> performUpdate() async {
    if (!_hasUpdate || _remoteVersion == null) {
      return false;
    }

    try {
      final miningConfig = await _configService.parseMiningConfig();
      if (miningConfig?.updateUrl == null) {
        _logger.warning('更新URL未配置');
        return false;
      }

      // 获取下载URL
      final remoteInfo = await _updateService.checkVersion(miningConfig!.updateUrl!);
      if (remoteInfo == null || remoteInfo.downloadUrl.isEmpty) {
        _logger.warning('无法获取下载URL');
        return false;
      }

      // 下载并更新
      final success = await _updateService.downloadAndUpdate(remoteInfo.downloadUrl);
      if (success) {
        _logger.info('更新下载完成，将在下次启动时应用');
      }
      return success;
    } catch (e) {
      _logger.severe('执行更新失败: $e');
      return false;
    }
  }

  @override
  void dispose() {
    _refreshTimer?.cancel();
    _clientCore.stop();
    _database.close();
    super.dispose();
  }
}
