#!/usr/bin/env python3
"""
Distance calculation utilities using Haversine formula
"""

import math
from typing import Optional


def haversine_distance(
    lat1: float, lon1: float, lat2: float, lon2: float
) -> Optional[float]:
    """
    Calculate the great circle distance between two points on Earth using Haversine formula.
    
    Args:
        lat1: Latitude of first point in degrees
        lon1: Longitude of first point in degrees
        lat2: Latitude of second point in degrees
        lon2: Longitude of second point in degrees
    
    Returns:
        Distance in meters, or None if calculation fails
    """
    try:
        # Validate inputs
        if not all(isinstance(x, (int, float)) for x in [lat1, lon1, lat2, lon2]):
            return None
        
        # Check if coordinates are valid
        if not (-90 <= lat1 <= 90) or not (-90 <= lat2 <= 90):
            return None
        if not (-180 <= lon1 <= 180) or not (-180 <= lon2 <= 180):
            return None

        # Earth's radius in meters
        R = 6371000

        # Convert degrees to radians
        phi1 = math.radians(lat1)
        phi2 = math.radians(lat2)
        delta_phi = math.radians(lat2 - lat1)
        delta_lambda = math.radians(lon2 - lon1)

        # Haversine formula
        a = (
            math.sin(delta_phi / 2) ** 2
            + math.cos(phi1) * math.cos(phi2) * math.sin(delta_lambda / 2) ** 2
        )
        c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))

        # Distance in meters
        distance = R * c

        return distance

    except (ValueError, TypeError, OverflowError):
        return None

