import 'dart:async';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'auth_provider.dart';
import 'data_providers.dart';
import '../models/bp_reading.dart';
import '../services/omron_ble_service.dart';

/// BLE 服务单例
final omronBleServiceProvider = Provider<OmronBleService>((ref) {
  return OmronBleService();
});

/// 设备绑定状态
class DeviceBindState {
  final bool isBound;
  final String? mac;
  final String? name;
  final String? lastSync;
  final bool isConnected;
  final BpReading? lastReading;

  const DeviceBindState({
    this.isBound = false,
    this.mac,
    this.name,
    this.lastSync,
    this.isConnected = false,
    this.lastReading,
  });

  DeviceBindState copyWith({
    bool? isBound,
    String? mac,
    String? name,
    String? lastSync,
    bool? isConnected,
    BpReading? lastReading,
  }) => DeviceBindState(
    isBound: isBound ?? this.isBound,
    mac: mac ?? this.mac,
    name: name ?? this.name,
    lastSync: lastSync ?? this.lastSync,
    isConnected: isConnected ?? this.isConnected,
    lastReading: lastReading ?? this.lastReading,
  );
}

class DeviceBindNotifier extends Notifier<DeviceBindState> {
  StreamSubscription? _connSub;

  @override
  DeviceBindState build() {
    _loadBinding();
    _listenConnection();
    return const DeviceBindState();
  }

  void _listenConnection() {
    _connSub?.cancel();
    _connSub = ref.read(omronBleServiceProvider).connectionState.listen((connected) {
      if (state.isConnected != connected) {
        state = state.copyWith(isConnected: connected);
      }
      if (!connected && state.isBound) {
        // 设备断开，但保持绑定信息（下次可以重连）
      }
    });
  }

  Future<void> _loadBinding() async {
    final db = ref.read(localDbProvider);
    final mac = await db.read('bp_device_mac');
    final name = await db.read('bp_device_name');
    final lastSync = await db.read('bp_last_sync');
    if (mac != null && mac.isNotEmpty) {
      state = state.copyWith(isBound: true, mac: mac, name: name, lastSync: lastSync);
    }
  }

  Future<void> bind(String mac, String name) async {
    final db = ref.read(localDbProvider);
    await db.write('bp_device_mac', mac);
    await db.write('bp_device_name', name);
    state = state.copyWith(isBound: true, mac: mac, name: name);
  }

  Future<void> unbind() async {
    final db = ref.read(localDbProvider);
    await db.delete('bp_device_mac');
    await db.delete('bp_device_name');
    await db.delete('bp_last_sync');
    state = const DeviceBindState();
  }

  void setConnected(bool connected) {
    state = state.copyWith(isConnected: connected);
  }

  Future<void> onReading(BpReading reading) async {
    final db = ref.read(localDbProvider);
    final lastSync = '${reading.timestamp.month}/${reading.timestamp.day} ${reading.timestamp.hour}:${reading.timestamp.minute.toString().padLeft(2, '0')}';
    await db.write('bp_last_sync', lastSync);
    state = state.copyWith(lastSync: lastSync, lastReading: reading);
    ref.invalidate(latestHealthProvider);
  }
}

final omronDeviceProvider = NotifierProvider<DeviceBindNotifier, DeviceBindState>(DeviceBindNotifier.new);
