enum Wgs84CoordinateFormat {
  decimalDegrees,
  degreesDecimalMinutes,
  degreesMinutesSeconds
}

extension Wgs84CoordinateFormatLabel on Wgs84CoordinateFormat {
  String get label {
    switch (this) {
      case Wgs84CoordinateFormat.decimalDegrees:
        return 'Tizedes fok';
      case Wgs84CoordinateFormat.degreesDecimalMinutes:
        return 'Fok + tizedes perc';
      case Wgs84CoordinateFormat.degreesMinutesSeconds:
        return 'Fok - perc - másodperc';
    }
  }

  String get shortLabel {
    switch (this) {
      case Wgs84CoordinateFormat.decimalDegrees:
        return 'DD';
      case Wgs84CoordinateFormat.degreesDecimalMinutes:
        return 'DM';
      case Wgs84CoordinateFormat.degreesMinutesSeconds:
        return 'DMS';
    }
  }
}

class Wgs84CoordinateFormatter {
  static String formatLatitude(
    double? value,
    Wgs84CoordinateFormat format,
  ) {
    return _format(
      value: value,
      format: format,
      positiveHemisphere: 'N',
      negativeHemisphere: 'S',
    );
  }

  static String formatLongitude(
    double? value,
    Wgs84CoordinateFormat format,
  ) {
    return _format(
      value: value,
      format: format,
      positiveHemisphere: 'E',
      negativeHemisphere: 'W',
    );
  }

  static String _format({
    required double? value,
    required Wgs84CoordinateFormat format,
    required String positiveHemisphere,
    required String negativeHemisphere,
  }) {
    if (value == null || value.isNaN || value.isInfinite) {
      return '-';
    }

    final hemisphere = value >= 0 ? positiveHemisphere : negativeHemisphere;
    final absValue = value.abs();

    switch (format) {
      case Wgs84CoordinateFormat.decimalDegrees:
        return '${absValue.toStringAsFixed(8)}° $hemisphere';

      case Wgs84CoordinateFormat.degreesDecimalMinutes:
        final deg = absValue.floor();
        final minutes = (absValue - deg) * 60.0;

        return '$deg° ${minutes.toStringAsFixed(5)}′ $hemisphere';

      case Wgs84CoordinateFormat.degreesMinutesSeconds:
        final deg = absValue.floor();
        final fullMinutes = (absValue - deg) * 60.0;
        final min = fullMinutes.floor();
        final sec = (fullMinutes - min) * 60.0;

        return '$deg° $min′ ${sec.toStringAsFixed(3)}″ $hemisphere';
    }
  }
}
