import math
import json
import os
from target_simulator.analysis.simulation_archive import SimulationArchive

try:
    from pyproj import Geod

    GEOD = Geod(ellps="WGS84")
except Exception:
    GEOD = None


def test_geopos_computation(tmp_path):
    # Create a minimal dummy scenario object expected by SimulationArchive
    D = type("D", (), {})()
    D.name = "geo_test"
    D.to_dict = lambda: {"dummy": True}

    sa = SimulationArchive(D)

    # Ownship at lat=45.0, lon=9.0, with local origin (0,0) ft
    ownship = {
        "timestamp": 100.0,
        "latitude": 45.0,
        "longitude": 9.0,
        "position_xy_ft": (0.0, 0.0),
    }
    sa.add_ownship_state(ownship)

    # Place a target 100 meters East and 200 meters North of ownship
    delta_east_m = 100.0
    delta_north_m = 200.0
    # Convert to feet used by the archive
    target_x_ft = delta_east_m / 0.3048
    target_y_ft = delta_north_m / 0.3048

    # Add a real state; timestamp close to ownship timestamp
    sa.add_real_state(1, 100.5, (target_x_ft, target_y_ft, 30.0))

    # The archive should have computed geopos for target id 1
    assert 1 in sa.recorded_geopos
    gps = sa.recorded_geopos[1]
    assert len(gps) >= 1
    sample = gps[-1]

    # Compute expected lat/lon using geodetic forward if available
    if GEOD is not None:
        dist = math.hypot(delta_east_m, delta_north_m)
        az_rad = math.atan2(delta_east_m, delta_north_m)
        az_deg = math.degrees(az_rad)
        lon2, lat2, _ = GEOD.fwd(
            ownship["longitude"], ownship["latitude"], az_deg, dist
        )
        # Compare within ~0.5 meter -> ~5e-6 degrees
        assert abs(sample["lat"] - lat2) < 5e-6
        assert abs(sample["lon"] - lon2) < 5e-6
    else:
        # Fallback check: lat/lon should be numbers and within reasonable bounds
        assert isinstance(sample["lat"], float)
        assert isinstance(sample["lon"], float)
