// lib/services/gnss_device_service.dart
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';

enum GnssConnectionType { none, btSerial, ble, phoneGps }

class GnssDevice {
  final String address;
  final String name;
  final GnssConnectionType type;
  final int? rssi;

  const GnssDevice({
    required this.address,
    required this.name,
    required this.type,
    this.rssi,
  });

  String get typeLabel => switch (type) {
        GnssConnectionType.btSerial => 'BT Serial',
        GnssConnectionType.ble => 'BLE',
        GnssConnectionType.phoneGps => 'Telefon GPS',
        GnssConnectionType.none => 'Kikapcsolva',
      };

  Map<String, dynamic> toJson() => {
        'address': address,
        'name': name,
        'type': type.name,
      };

  factory GnssDevice.fromJson(Map<String, dynamic> j) => GnssDevice(
        address: j['address'] as String,
        name: j['name'] as String,
        type: GnssConnectionType.values
            .byName(j['type'] as String? ?? 'btSerial'),
      );
}

class GnssDeviceService extends GetxService {
  static GnssDeviceService get to => Get.find();

  // Kiválasztott eszköz — minden controller innen olvassa
  final selectedDevice = Rxn<GnssDevice>();

  // Elérhető eszközök listái
  final pairedBtDevices = <GnssDevice>[].obs;
  final scannedBleDevices = <GnssDevice>[].obs;
  final isScanning = false.obs;

  @override
  Future<void> onInit() async {
    super.onInit();
    await _loadSelectedDevice();
    await loadPairedBtDevices();
  }

  // ── Perzisztencia ────────────────────────────────────────────────

  Future<void> _loadSelectedDevice() async {
    final prefs = await SharedPreferences.getInstance();
    final address = prefs.getString('gnss_address');
    final name = prefs.getString('gnss_name');
    final type = prefs.getString('gnss_type') ?? 'btSerial';

    if (address != null && name != null) {
      selectedDevice.value = GnssDevice(
        address: address,
        name: name,
        type: GnssConnectionType.values.byName(type),
      );
    }
  }

  Future<void> selectDevice(GnssDevice device) async {
    selectedDevice.value = device;
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('gnss_address', device.address);
    await prefs.setString('gnss_name', device.name);
    await prefs.setString('gnss_type', device.type.name);
  }

  Future<void> clearDevice() async {
    selectedDevice.value = null;
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove('gnss_address');
    await prefs.remove('gnss_name');
    await prefs.remove('gnss_type');
  }

  // ── BT Serial — párosított eszközök ─────────────────────────────

  Future<void> loadPairedBtDevices() async {
    try {
      final bonded = await FlutterBluetoothSerial.instance.getBondedDevices();
      pairedBtDevices.value = bonded
          .where((d) => d.address != null && d.name != null)
          .map((d) => GnssDevice(
                address: d.address,
                name: d.name ?? d.address,
                type: GnssConnectionType.btSerial,
              ))
          .toList();
    } catch (_) {}
  }

  // ── BLE — aktív keresés ──────────────────────────────────────────

  Future<void> startBleScan() async {
    if (isScanning.value) return;
    scannedBleDevices.clear();
    isScanning.value = true;

    try {
      await FlutterBluePlus.startScan(
        timeout: const Duration(seconds: 8),
      );

      FlutterBluePlus.scanResults.listen((results) {
        final devices = results
            .where((r) => r.device.platformName.isNotEmpty)
            .map((r) => GnssDevice(
                  address: r.device.remoteId.str,
                  name: r.device.platformName,
                  type: GnssConnectionType.ble,
                  rssi: r.rssi,
                ))
            .toList();
        scannedBleDevices.value = devices;
      });

      await Future.delayed(const Duration(seconds: 8));
    } finally {
      await FlutterBluePlus.stopScan();
      isScanning.value = false;
    }
  }

  void stopBleScan() {
    FlutterBluePlus.stopScan();
    isScanning.value = false;
  }
}
