// lib/services/gnss/bt_serial_gnss_connection.dart
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
import 'package:geolocator/geolocator.dart';
import 'package:get/get.dart';
import 'gnss_connection.dart';
import 'gnss_device_service.dart';
import 'dart:convert';

class BtSerialGnssConnection implements GnssConnection {
  @override
  GnssConnectionType get type => GnssConnectionType.btSerial;

  BluetoothConnection? _connection;
  String _messageBuffer = '';
  String _lineBuffer = '';

  final _nmeaController = StreamController<String>.broadcast();
  final _stateController = StreamController<GnssConnectionState>.broadcast();

  @override
  Stream<String> get nmeaLines => _nmeaController.stream;

  @override
  Stream<GnssConnectionState> get connectionState => _stateController.stream;

  @override
  Future<void> connect(String address) async {
    _stateController.add(GnssConnectionState.connecting);
    try {
      _connection = await BluetoothConnection.toAddress(address);
      _stateController.add(GnssConnectionState.connected);
      _connection!.input!.listen(
        _onData,
        onDone: () {
          _stateController.add(GnssConnectionState.disconnected);
        },
      );
    } catch (e) {
      _stateController.add(GnssConnectionState.error);
      rethrow;
    }
  }

  @override
  Future<void> disconnect() async {
    await _connection?.close();
    _connection = null;
    _stateController.add(GnssConnectionState.disconnected);
  }

  // A meglévő _onDataReceived logika változatlanul
  void _onData(Uint8List data) {
    _lineBuffer += utf8.decode(data, allowMalformed: true);

    final lines = const LineSplitter().convert(_lineBuffer);

    for (int i = 0; i < lines.length - 1; i++) {
      final sentence = lines[i].trim();
      if (sentence.isNotEmpty) {
        _nmeaController.add(sentence);
      }
    }

    if (_lineBuffer.endsWith('\n')) {
      if (lines.isNotEmpty && lines.last.trim().isNotEmpty) {
        _nmeaController.add(lines.last.trim());
      }
      _lineBuffer = '';
    } else {
      _lineBuffer = lines.isNotEmpty ? lines.last : _lineBuffer;
    }
  }

  @override
  void dispose() {
    _connection?.close();
    _nmeaController.close();
    _stateController.close();
  }

  void sendData(Uint8List data) {
    _connection?.output.add(data);
  }

  @override
  Stream<Position> get positionStream => const Stream.empty();
}
