import 'dart:async';
import 'dart:io';
import 'package:logging/logging.dart';
// import 'package:ini/ini.dart';
import 'mining_manager.dart';
import 'mining_task_info.dart';
import '../utils/ini_utils.dart';
import '../utils/path_utils.dart';

/// 持续挖矿管理器
class SustainMiner {
  static final SustainMiner _instance = SustainMiner._internal();
  factory SustainMiner() => _instance;
  SustainMiner._internal();

  final Logger _logger = Logger('SustainMiner');
  final MiningManager _miningManager = MiningManager();

  SustainMiningConfig? _config;
  MiningConfig? _miningConfig;
  Timer? _monitorTimer;
  StreamSubscription<void>? _processExitSubscription;
  bool _isRunning = false;
  bool _isPaused = false;

  /// 加载配置
  Future<bool> loadConfig(MiningConfig miningConfig) async {
    try {
      _miningConfig = miningConfig;
      
      final configFile = File(PathUtils.binFile('mining.windows.conf'));
      if (!await configFile.exists()) {
        _logger.warning('配置文件不存在');
        return false;
      }

      final content = await configFile.readAsString();
      final config = parseIni(content);

      // ini 2.x: 使用 get(section, option)
      final enabledStr = (config.get('sustain', 'enabled') ?? '').toLowerCase();
      final enabled = enabledStr == 'true';

      if (!enabled) {
        _logger.info('持续挖矿未启用');
        return false;
      }

      _config = SustainMiningConfig(
        enabled: enabled,
        algo: _trimQuotes(config.get('sustain', 'algo') ?? ''),
        coin: _trimQuotes(config.get('sustain', 'coin') ?? ''),
        miner: _trimQuotes(config.get('sustain', 'miner') ?? ''),
        poolUrl: _trimQuotes(config.get('sustain', 'pool_url') ?? ''),
        wallet: _trimQuotes(config.get('sustain', 'wallet') ?? ''),
        workerId: _trimQuotes(config.get('sustain', 'worker_id') ?? ''),
        poolUser: _trimQuotes(config.get('sustain', 'pool_user') ?? ''),
        walletMining: (config.get('sustain', 'wallet_mining') ?? '').toLowerCase() == 'true',
      );

      // 验证配置
      if (_config!.algo.isEmpty ||
          _config!.coin.isEmpty ||
          _config!.miner.isEmpty ||
          _config!.poolUrl.isEmpty ||
          _config!.wallet.isEmpty ||
          _config!.workerId.isEmpty) {
        _logger.severe('持续挖矿配置不完整');
        return false;
      }

      // 验证挖矿软件路径
      final minerPath = _getMinerPath(_config!.miner);
      if (minerPath == null || minerPath.isEmpty) {
        _logger.severe('${_config!.miner} 路径未配置');
        return false;
      }

      _logger.info('持续挖矿配置加载成功: 算法=${_config!.algo}, 币种=${_config!.coin}, 挖矿软件=${_config!.miner}');
      return true;
    } catch (e) {
      _logger.severe('加载持续挖矿配置失败: $e');
      return false;
    }
  }

  /// 启动持续挖矿
  Future<void> start() async {
    if (_config == null || !_config!.enabled) {
      return;
    }

    if (_isRunning) {
      _logger.info('持续挖矿已在运行中');
      return;
    }

    if (_miningManager.isMining) {
      _logger.info('当前有挖矿任务，等待任务结束后启动持续挖矿');
      return;
    }

    _isRunning = true;
    _isPaused = false;

    _logger.info('启动持续挖矿...');
    await _startMining();
    _startProcessMonitor();
  }

  /// 停止持续挖矿
  Future<void> stop() async {
    _isRunning = false;
    _monitorTimer?.cancel();
    _monitorTimer = null;
    _processExitSubscription?.cancel();
    _processExitSubscription = null;

    if (_miningManager.isMining && _miningManager.currentTask == null) {
      // 只有持续挖矿任务在运行时才停止
      await _miningManager.stopMining();
    }

    _logger.info('持续挖矿已停止');
  }

  /// 暂停持续挖矿
  Future<void> pause() async {
    if (!_isRunning || _isPaused) {
      return;
    }

    _logger.info('暂停持续挖矿（有新任务）...');
    _isPaused = true;

    if (_miningManager.isMining && _miningManager.currentTask == null) {
      await _miningManager.stopMining();
    }
  }

  /// 恢复持续挖矿
  Future<void> resume() async {
    if (!_isRunning || !_isPaused) {
      return;
    }

    if (_miningManager.isMining) {
      _logger.info('当前有挖矿任务，等待任务结束后恢复持续挖矿');
      return;
    }

    _logger.info('恢复持续挖矿...');
    _isPaused = false;
    await _startMining();
    // 确保进程监控已启动
    if (_processExitSubscription == null) {
      _startProcessMonitor();
    }
  }

  /// 启动挖矿
  Future<void> _startMining() async {
    if (_config == null || _isPaused || _miningConfig == null) {
      return;
    }

    if (_miningManager.isMining) {
      return;
    }

    final task = MiningTaskInfo(
      coin: _config!.coin,
      algo: _config!.algo,
      pool: '',
      poolUrl: _config!.poolUrl,
      walletAddress: _config!.wallet,
      workerId: _config!.workerId,
      poolUser: _config!.poolUser,
      walletMining: _config!.walletMining,
      endTimestamp: DateTime.now().add(const Duration(days: 365)).millisecondsSinceEpoch ~/ 1000, // 持续挖矿设置很长的结束时间
      miner: _config!.miner,
    );

    await _miningManager.startMining(task, _miningConfig!);
  }

  /// 启动进程监控
  void _startProcessMonitor() {
    _processExitSubscription?.cancel();
    
    // 监听挖矿进程退出事件
    _processExitSubscription = _miningManager.processExitStream.listen((_) {
      // 检查是否是持续挖矿进程退出
      if (_isRunning && !_isPaused && !_miningManager.isMining && _miningManager.currentTask == null) {
        _logger.warning('持续挖矿进程意外退出，将在5秒后自动重启...');
        // 延迟5秒后重启，避免频繁重启
        Future.delayed(const Duration(seconds: 5), () {
          if (_isRunning && !_isPaused && !_miningManager.isMining) {
            _logger.info('自动重启持续挖矿...');
            _startMining();
          }
        });
      }
    });
  }

  String _trimQuotes(String value) {
    var v = value.trim();
    if (v.length >= 2) {
      final first = v[0];
      final last = v[v.length - 1];
      if ((first == '"' && last == '"') || (first == "'" && last == "'")) {
        v = v.substring(1, v.length - 1);
      }
    }
    return v;
  }

  String? _getMinerPath(String miner) {
    if (_miningConfig == null) return null;

    switch (miner.toLowerCase()) {
      case 'lolminer':
        return _miningConfig!.lolMinerPath;
      case 'rigel':
        return _miningConfig!.rigelPath;
      case 'bzminer':
        return _miningConfig!.bzMinerPath;
      default:
        return null;
    }
  }

  bool get isRunning => _isRunning;
  bool get isPaused => _isPaused;
}

class SustainMiningConfig {
  final bool enabled;
  final String algo;
  final String coin;
  final String miner;
  final String poolUrl;
  final String wallet;
  final String workerId;
  final String poolUser;
  final bool walletMining;

  SustainMiningConfig({
    required this.enabled,
    required this.algo,
    required this.coin,
    required this.miner,
    required this.poolUrl,
    required this.wallet,
    required this.workerId,
    required this.poolUser,
    required this.walletMining,
  });
}
