import 'dart:async';
import 'location_source.dart';

/// BLE GNSS vevőből érkező helymeghatározási forrás.
///
/// A meglévő Bluetooth + NMEA parsing logikát köti be a
/// [LocationSource] interfészbe, így a TrackingController
/// forrásváltás nélkül tud működni.
///
/// TEENDŐK a BLE verzió elkészültével:
///  1. Injektáld a BluetoothConnection referenciát (vagy egy
///     stream-et a NMEA mondatokból).
///  2. Parsold a GNGGA mondatokat (ugyanaz a [Gngga] osztály
///     ami a MapSurveyController-ben is megvan).
///  3. Alkalmazd a geoid-korrekciót [GeoidGrid] segítségével.
///  4. Töltsd fel a [SourcePosition]-t a korrekt mezőkkel.
class BleGnssSource implements LocationSource {
  @override
  String get displayName => 'BLE GNSS';

  // TODO: Stream<String> nmeaStream — a BLE controller adja
  final Stream<String>? nmeaStream;

  StreamController<SourcePosition>? _controller;
  StreamSubscription? _sub;

  BleGnssSource({this.nmeaStream});

  @override
  bool get isAvailable => _sub != null;

  @override
  Stream<SourcePosition> get positionStream {
    _controller = StreamController<SourcePosition>.broadcast();

    if (nmeaStream == null) {
      _controller!.addError(Exception(
        'BLE GNSS forrás nincs bekötve. '
        'Adj meg egy nmeaStream-et a konstruktorban.',
      ));
      return _controller!.stream;
    }

    _sub = nmeaStream!.listen((line) {
      if (!line.startsWith('\$GNGGA')) return;

      // TODO: Gngga parser + GeoidGrid korreckció beépítése
      // Példa váz:
      //
      // final sentence = nmeaDecoder.decode(line);
      // if (sentence is! Gngga || !sentence.valid) return;
      // final ellipsoidal =
      //     sentence.altitudeAboveMeanSeaLevel + sentence.geoidSeparation;
      // final eovZ = geoidGrid.toEovHeight(
      //     sentence.latitude, sentence.longitude,
      //     sentence.altitudeAboveMeanSeaLevel, sentence.geoidSeparation);
      //
      // _controller?.add(SourcePosition(
      //   latitude: sentence.latitude,
      //   longitude: sentence.longitude,
      //   altitude: eovZ ?? ellipsoidal,
      //   accuracy: null,   // GNGST-ből lehetne
      //   timestamp: DateTime.now(),
      //   source: displayName,
      // ));
    });

    return _controller!.stream;
  }

  @override
  Future<void> dispose() async {
    await _sub?.cancel();
    await _controller?.close();
  }
}
