import 'dart:async';
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import '../models/bp_reading.dart';

/// 欧姆龙蓝牙血压计 BLE 服务
class OmronBleService {
  static const bpServiceUuid = '00001810-0000-1000-8000-00805F9B34FB';
  static const bpMeasurementUuid = '00002A35-0000-1000-8000-00805F9B34FB';
  static const bpFeatureUuid = '00002A49-0000-1000-8000-00805F9B34FB';
  static const dateTimeUuid = '00002A08-0000-1000-8000-00805F9B34FB';
  static const intermediateCuffUuid = '00002A36-0000-1000-8000-00805F9B34FB';
  static const racpUuid = '00002A52-0000-1000-8000-00805F9B34FB';

  BluetoothDevice? _device;
  StreamSubscription<List<int>>? _measurementSub;
  StreamSubscription<BluetoothConnectionState>? _connStateSub;
  final _readingsController = StreamController<BpReading>.broadcast();
  final _connStateController = StreamController<bool>.broadcast();
  Stream<BpReading> get readings => _readingsController.stream;
  Stream<bool> get connectionState => _connStateController.stream;

  bool get isConnected => _device?.isConnected ?? false;

  /// 直接重连已知设备（通过MAC地址）
  Future<bool> reconnectByMac(String mac) async {
    debugPrint('[BLE] 直连设备: $mac');
    final bonded = await FlutterBluePlus.bondedDevices;
    BluetoothDevice? target;
    for (final d in bonded) {
      if (d.remoteId.toString() == mac) {
        target = d;
        break;
      }
    }
    if (target == null) {
      debugPrint('[BLE] 未在已配对设备中找到 $mac');
      return false;
    }
    try {
      await connect(target);
      return true;
    } catch (e) {
      debugPrint('[BLE] 直连失败: $e');
      return false;
    }
  }

  static bool isBpDevice(ScanResult r) {
    final name = [
      r.advertisementData.advName,
      r.device.platformName,
    ].where((n) => n.isNotEmpty).join(' ').toUpperCase();
    return name.contains('OMRON') ||
           name.contains('HEM') ||
           name.contains('BLESMART') ||
           name.contains('J735') ||
           name.contains('BPM') ||
           name.contains('BP');
  }

  /// 连接设备并订阅测量数据
  /// 设备连接后会自动发送存储的最后一次测量数据
  Future<void> connect(BluetoothDevice device) async {
    _device = device;
    debugPrint('[BLE] ═══ 连接: "${device.platformName}" ═══');

    _connStateSub = device.connectionState.listen((s) {
      debugPrint('[BLE] 连接状态: $s');
      _connStateController.add(s == BluetoothConnectionState.connected);
    });

    // 1. GATT连接
    await device.connect(autoConnect: false);
    debugPrint('[BLE] ① 已连接, MTU=${device.mtuNow}');
    try { await device.requestMtu(512); } catch (_) {}

    // 2. 发现服务
    final services = await device.discoverServices();
    debugPrint('[BLE] ② 发现${services.length}个服务');

    // 遍历所有服务/特征
    BluetoothService? bpSvc;
    BluetoothCharacteristic? measChar, racpChar;
    for (final s in services) {
      debugPrint('[BLE]   服务: ${s.uuid.str128}');
      for (final c in s.characteristics) {
        final p = <String>[];
        if (c.properties.read) p.add('R');
        if (c.properties.write) p.add('W');
        if (c.properties.notify) p.add('N');
        if (c.properties.indicate) p.add('I');
        debugPrint('[BLE]     ${c.uuid.str128} [$p]');
        for (final d in c.descriptors) {
          debugPrint('[BLE]       desc: ${d.uuid.str128}');
        }
      }
      if (s.uuid.str128.toUpperCase() == bpServiceUuid.toUpperCase()) bpSvc = s;
    }

    if (bpSvc == null) throw Exception('未找到血压服务0x1810');
    for (final c in bpSvc.characteristics) {
      final u = c.uuid.str128.toUpperCase();
      if (u == bpMeasurementUuid.toUpperCase()) measChar = c;
      if (u == racpUuid.toUpperCase()) racpChar = c;
    }
    if (measChar == null) throw Exception('未找到0x2A35');
    debugPrint('[BLE] ③ 0x2A35: indicate=${measChar.properties.indicate} read=${measChar.properties.read}');
    debugPrint('[BLE]    RACP: ${racpChar != null ? "有" : "无"}');

    // ★ 3. 先订阅数据流(在配置CCCD之前!)
    debugPrint('[BLE] ④ 订阅lastValueStream...');
    _measurementSub = measChar.lastValueStream.listen(
      (raw) {
        debugPrint('[BLE] ★★★ 收到数据! ${raw.length}字节 ★★★');
        debugPrint('[BLE] HEX: ${raw.map((b) => b.toRadixString(16).padLeft(2, '0')).join(' ')}');
        _parseReading(raw);
      },
      onError: (e) => debugPrint('[BLE] 流错误: $e'),
      cancelOnError: false,
    );

    // 4. 配置CCCD
    final isIndicate = measChar.properties.indicate;
    final cccdVal = isIndicate ? [0x02, 0x00] : [0x01, 0x00];
    debugPrint('[BLE] ⑤ 配置CCCD → ${isIndicate ? "Indicate" : "Notify"}...');
    var ok = false;
    for (final d in measChar.descriptors) {
      if (d.uuid.str128 == '00002902-0000-1000-8000-00805F9B34FB') {
        final before = await d.read();
        await d.write(cccdVal);
        final after = await d.read();
        ok = after.length >= 2 && after[0] == cccdVal[0] && after[1] == cccdVal[1];
        debugPrint('[BLE] ⑤ CCCD: $before → $after ${ok ? "OK" : "FAIL"}');
        break;
      }
    }
    if (!ok) {
      await measChar.setNotifyValue(true, forceIndications: isIndicate);
      debugPrint('[BLE] ⑤ 降级setNotifyValue, isNotifying=${measChar.isNotifying}');
    }

    // 5. 主动读取缓存数据(设备存储的最后一次测量)
    debugPrint('[BLE] ⑥ 主动读取0x2A35...');
    if (measChar.properties.read) {
      try {
        final data = await measChar.read();
        if (data.isNotEmpty) {
          debugPrint('[BLE] ⑥ 读到${data.length}字节 HEX=${data.map((b) => b.toRadixString(16).padLeft(2, '0')).join(' ')}');
          _parseReading(data);
        } else {
          debugPrint('[BLE] ⑥ 空数据');
        }
      } catch (e) {
        debugPrint('[BLE] ⑥ 读取失败: $e');
      }
    }

    // 6. RACP请求存储记录
    if (racpChar != null) {
      debugPrint('[BLE] ⑦ RACP请求存储记录...');
      try {
        await racpChar.write([0x01, 0x01]); // ReportStoredRecords, All
        debugPrint('[BLE] ⑦ RACP已发送');
      } catch (e) {
        debugPrint('[BLE] ⑦ RACP失败: $e');
      }
    }

    debugPrint('[BLE] ═══ 连接完成, 等待数据 ═══');
  }

  Future<void> disconnect() async {
    _connStateSub?.cancel();
    _connStateSub = null;
    _measurementSub?.cancel();
    _measurementSub = null;
    await _device?.disconnect();
    _device = null;
    debugPrint('[BLE] 已断开');
  }

  void dispose() {
    disconnect();
    _readingsController.close();
    _connStateController.close();
  }

  // ── 解析 BLE 测量数据 ──

  void _parseReading(List<int> raw) {
    debugPrint('[BLE] 解析: flags=0x${raw[0].toRadixString(16)}, len=${raw.length}');
    if (raw.length < 7) { debugPrint('[BLE] 太短,跳过'); return; }

    final flags = raw[0];
    final isKpa = (flags & 0x01) != 0;
    final hasTs = (flags & 0x02) != 0;
    final hasPulse = (flags & 0x04) != 0;
    final hasUid = (flags & 0x08) != 0;
    final hasStatus = (flags & 0x10) != 0;

    int sys = _decodeSFloat(raw[1] | (raw[2] << 8)).round();
    int dia = _decodeSFloat(raw[3] | (raw[4] << 8)).round();
    if (isKpa) { sys = (sys * 7.50062).round(); dia = (dia * 7.50062).round(); }

    int off = 7;
    DateTime ts = DateTime.now();
    if (hasTs && raw.length >= off + 7) {
      ts = DateTime(raw[off] | (raw[off + 1] << 8), raw[off + 2], raw[off + 3],
          raw[off + 4], raw[off + 5], raw[off + 6]);
      off += 7;
    }

    int? pulse;
    if (hasPulse && raw.length >= off + 2) {
      pulse = _decodeSFloat(raw[off] | (raw[off + 1] << 8)).round();
      off += 2;
    }

    String? uid;
    if (hasUid && raw.length > off) { uid = raw[off].toString(); off++; }

    bool bm = false, ir = false;
    if (hasStatus && raw.length >= off + 2) {
      int s = raw[off] | (raw[off + 1] << 8);
      bm = (s & 0x0001) != 0;
      ir = (s & 0x0800) != 0;
    }

    final r = BpReading(systolic: sys, diastolic: dia, pulse: pulse, timestamp: ts,
      userId: uid, isKpa: isKpa, hasBodyMovement: bm, hasIrregularPulse: ir);
    debugPrint('[BLE] ★ $sys/$dia mmHg, pulse=$pulse ★');
    _readingsController.add(r);
  }

  static double _decodeSFloat(int raw) {
    int m = raw & 0x0FFF;
    if (m & 0x0800 != 0) m |= 0xFFFFF000;
    int e = (raw >> 12) & 0x0F;
    if (e & 0x08 != 0) e |= 0xFFFFFFF0;
    return (m * pow(10, e)).toDouble();
  }
}
