import 'dart:async';

import 'package:usb_serial/usb_serial.dart';

import '../models/serial_config.dart';
import 'device_log.dart';
import 'serial_port_service.dart';

/// 启动自动连接服务
///
/// App 启动时调用 [start]，自动连接第一个可用的 USB 串口设备：
/// - 固定 115200 波特率 / 8 数据位 / 1 停止位 / 默认其它
/// - 连接失败时每 3 秒重试一次
/// - 连接成功后停止重试；连接断开后重新进入重试循环
class AutoSerialConnect {
  /// 重试间隔
  static const Duration retryInterval = Duration(seconds: 3);

  /// 自动连接使用的固定参数
  static const SerialConfig autoConfig = SerialConfig(
    baudRate: 115200,
    dataBits: 8,
    stopBits: 1,
  );

  final SerialPortService _service;
  Timer? _retryTimer;
  StreamSubscription<SerialConnectionState>? _stateSub;
  bool _disposed = false;

  AutoSerialConnect(this._service);

  /// 启动自动连接：立即尝试一次，失败则按 [retryInterval] 周期重试
  void start() {
    if (_stateSub != null) return;
    _stateSub = _service.connectionStateChanges.listen(_onStateChange);
    unawaited(_tryConnect());
  }

  void _onStateChange(SerialConnectionState s) {
    if (_disposed) return;
    switch (s) {
      case SerialConnectionState.connected:
        // 连接成功：停止重试
        _cancelRetry();
      case SerialConnectionState.disconnected:
      case SerialConnectionState.error:
        // 设备断开或出错：进入重试
        _scheduleRetry();
      case SerialConnectionState.connecting:
        // 正在连接中，忽略
        break;
    }
  }

  Future<void> _tryConnect() async {
    if (_disposed) return;
    if (_service.isConnected ||
        _service.state == SerialConnectionState.connecting) {
      return;
    }

    final List<UsbDevice> devices;
    try {
      devices = await _service.listDevices();
    } catch (e) {
      DeviceLog.warn('列出 USB 设备失败: $e，${retryInterval.inSeconds}s 后重试');
      _scheduleRetry();
      return;
    }

    if (devices.isEmpty) {
      DeviceLog.info('未检测到 USB 串口设备，${retryInterval.inSeconds}s 后重试');
      _scheduleRetry();
      return;
    }

    final device = devices.first;
    final ok = await _service.connect(device, autoConfig);
    if (!ok) {
      DeviceLog.warn('串口自动连接失败: '
          '${_service.lastError ?? "未知错误"}，${retryInterval.inSeconds}s 后重试');
      _scheduleRetry();
    }
  }

  void _scheduleRetry() {
    if (_disposed) return;
    if (_retryTimer != null) return;
    _retryTimer = Timer(retryInterval, () {
      _retryTimer = null;
      unawaited(_tryConnect());
    });
  }

  void _cancelRetry() {
    _retryTimer?.cancel();
    _retryTimer = null;
  }

  /// 释放资源
  Future<void> dispose() async {
    if (_disposed) return;
    _disposed = true;
    _cancelRetry();
    await _stateSub?.cancel();
    _stateSub = null;
  }
}
