import 'package:nmea/nmea.dart';

class Gngga extends TalkerSentence {
  static const String id = "GxGGA";
  Gngga({required super.raw});

  @override
  bool get valid => super.valid && fields.length >= 15;

  String get utcOfPositionFix => _field(1);
  int get gpsQualityIndicator => _parseInt(_field(6), fallback: 0);
  String get latitudeDirection => _field(3).toUpperCase();
  double get latitude => _parseLatitude(_field(2), latitudeDirection) ?? 0.0;
  String get longitudeDirection => _field(5).toUpperCase();
  double get longitude => _parseLongitude(_field(4), longitudeDirection) ?? 0.0;
  int get numberOfSvsInUse => _parseInt(_field(7), fallback: 0);
  double get hdop => _parseDouble(_field(8), fallback: 0.0);
  double get altitudeAboveMeanSeaLevel =>
      _parseDouble(_field(9), fallback: 0.0);
  double get geoidSeparation => _parseDouble(_field(11), fallback: 0.0);

  String _field(int index) {
    if (index < 0 || index >= fields.length) return '';

    return fields[index].trim();
  }

  int _parseInt(String value, {required int fallback}) {
    return int.tryParse(value) ?? fallback;
  }

  double _parseDouble(String value, {required double fallback}) {
    return double.tryParse(value) ?? fallback;
  }

  double? _parseLatitude(String value, String direction) {
    if (value.length < 4) return null; // ddmm.mmmm
    final deg = double.tryParse(value.substring(0, 2));
    final min = double.tryParse(value.substring(2));
    if (deg == null || min == null) return null;

    final result = deg + (min / 60.0);
    return direction == 'S' ? -result : result;
  }

  double? _parseLongitude(String value, String direction) {
    if (value.length < 5) return null; // dddmm.mmmm
    final deg = double.tryParse(value.substring(0, 3));
    final min = double.tryParse(value.substring(3));
    if (deg == null || min == null) return null;

    final result = deg + (min / 60.0);
    return direction == 'W' ? -result : result;
  }
}
