import 'dart:async';

import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../../../core/database/database_service.dart';
import '../models/serial_config.dart';
import '../services/auto_serial_connect.dart';
import '../services/device_message_service.dart';
import '../services/json_protocol.dart';
import '../services/runner_interface.dart';
import '../services/serial_port_service.dart';
import '../services/serial_runner.dart';

/// 串口服务单例
final serialPortServiceProvider = Provider<SerialPortService>((ref) {
  final service = SerialPortService();
  ref.onDispose(service.dispose);
  return service;
});

/// 串口连接状态（响应式）
///
/// 直接 `ref.watch(serialPortServiceProvider).state` 不会触发 UI 重建，
/// 因为 [SerialPortService] 内部 `_state` 的变化不会冒泡到 Provider 层。
/// 这里把状态抽出为独立的 StateNotifierProvider，让状态栏等 UI 能即时
/// 反映连接/断开事件，避免出现"标题栏显示已连接、实际下发失败"的错觉。
class SerialConnectionStateNotifier
    extends StateNotifier<SerialConnectionState> {
  SerialConnectionStateNotifier(this._service) : super(_service.state) {
    _sub = _service.connectionStateChanges.listen((s) => state = s);
  }

  final SerialPortService _service;
  late final StreamSubscription<SerialConnectionState> _sub;

  @override
  void dispose() {
    _sub.cancel();
    super.dispose();
  }
}

final serialConnectionStateProvider = StateNotifierProvider<
    SerialConnectionStateNotifier, SerialConnectionState>((ref) {
  final service = ref.watch(serialPortServiceProvider);
  return SerialConnectionStateNotifier(service);
});

/// 启动自动连接服务
///
/// 通过 [main] 中的 ProviderContainer 在 runApp 之前触发一次，
/// 服务内部立即尝试连接第一个 USB 串口设备，失败时按 3s 间隔重试。
final autoSerialConnectProvider = Provider<AutoSerialConnect>((ref) {
  final service = ref.watch(serialPortServiceProvider);
  final auto = AutoSerialConnect(service);
  auto.start();
  ref.onDispose(auto.dispose);
  return auto;
});

/// JSON 协议编解码器（可在调试/真机协议不一致时整体替换）
final jsonProtocolProvider = Provider<JsonProtocolService>((ref) {
  return JsonProtocolService();
});

/// 设备消息分发服务
///
/// 集中处理 JSON 消息的发送与订阅；下游 Provider 各自订阅感兴趣的类型。
final deviceMessageServiceProvider =
    Provider<DeviceMessageService>((ref) {
  final serial = ref.watch(serialPortServiceProvider);
  final protocol = ref.watch(jsonProtocolProvider);
  final service = DeviceMessageService(serial: serial, protocol: protocol);
  ref.onDispose(service.dispose);
  return service;
});

/// 当前串口配置（设置页修改后通过 notifier 写入并持久化）
class SerialConfigNotifier extends StateNotifier<SerialConfig> {
  final SettingsConfigRepository _repo;

  SerialConfigNotifier(this._repo) : super(SerialConfig.defaults) {
    _load();
  }

  Future<void> _load() async {
    state = await _repo.read();
  }

  /// 修改并持久化
  Future<void> update(SerialConfig Function(SerialConfig) mutator) async {
    final next = mutator(state);
    state = next;
    await _repo.write(next);
  }

  /// 重置为默认值
  Future<void> reset() => update((_) => SerialConfig.defaults);
}

/// 串口配置仓库：把 [SerialConfig] 以 JSON 形式存到 settings 表
class SettingsConfigRepository {
  static const _key = 'serial_config';
  final DatabaseService _db = DatabaseService.instance;

  Future<SerialConfig> read() async {
    final raw = await _db.readSetting(_key);
    return SerialConfig.fromJsonString(raw);
  }

  Future<void> write(SerialConfig config) async {
    await _db.writeSetting(_key, config.toJsonString());
  }
}

final serialConfigProvider =
    StateNotifierProvider<SerialConfigNotifier, SerialConfig>((ref) {
  return SerialConfigNotifier(SettingsConfigRepository());
});

/// 运行器实例（基于 JSON 协议与设备消息服务）
final runnerProvider = Provider<Runner>((ref) {
  final msgService = ref.watch(deviceMessageServiceProvider);
  return JsonSerialRunner(messageService: msgService);
});
