"""Orbital elements type for Keplerian orbit representation.

Classical Keplerian orbital elements define an orbit's shape, orientation, and
position at a reference epoch. This module provides the OrbitalElements NamedTuple
that serves as the primary orbit definition type throughout the orbit module.

The six classical orbital elements are:
    - Semi-major axis (a): Size of the orbit
    - Eccentricity (e): Shape of the orbit (0 = circular, 0 < e < 1 = elliptical)
    - Inclination (i): Tilt of the orbit plane relative to the equator
    - RAAN (Omega): Orientation of the ascending node
    - Argument of periapsis (omega): Orientation of periapsis within the orbit
    - Mean anomaly (M): Position along the orbit at epoch

References:
    - Vallado, D. "Fundamentals of Astrodynamics and Applications", 4th ed.
    - Bate, Mueller, White "Fundamentals of Astrodynamics"
"""

from __future__ import annotations

from typing import NamedTuple


class OrbitalElements(NamedTuple):
    """Keplerian orbital elements defining an orbit.

    All angular quantities are in radians. The epoch specifies when the
    mean anomaly value applies.

    Attributes:
        semi_major_axis_m: Semi-major axis in meters. Defines the size of the
            orbit. For elliptical orbits, this is half the longest diameter.
        eccentricity: Orbital eccentricity (dimensionless). Defines the shape:
            0 = circular, 0 < e < 1 = elliptical, e = 1 = parabolic, e > 1 = hyperbolic.
        inclination_rad: Inclination in radians [0, pi]. Angle between the orbit
            plane and the equatorial plane. 0 = equatorial prograde, pi/2 = polar,
            pi = equatorial retrograde.
        raan_rad: Right Ascension of the Ascending Node in radians [0, 2*pi).
            Angle from the vernal equinox to the ascending node (where the orbit
            crosses the equator going north). Also called Longitude of Ascending Node.
        arg_periapsis_rad: Argument of periapsis in radians [0, 2*pi). Angle from
            the ascending node to the periapsis (closest approach point), measured
            in the orbit plane.
        mean_anomaly_rad: Mean anomaly at epoch in radians [0, 2*pi). Indicates
            position along the orbit at the reference time. Mean anomaly increases
            uniformly with time at rate n = sqrt(mu/a^3).
        epoch_unix_s: Reference epoch as Unix timestamp (seconds since 1970-01-01
            00:00:00 UTC). The mean_anomaly_rad value applies at this time.

    Example:
        >>> # ISS-like orbit
        >>> elements = OrbitalElements(
        ...     semi_major_axis_m=6_778_000,  # ~400 km altitude
        ...     eccentricity=0.0001,
        ...     inclination_rad=0.9006,  # 51.6 degrees
        ...     raan_rad=0.0,
        ...     arg_periapsis_rad=0.0,
        ...     mean_anomaly_rad=0.0,
        ...     epoch_unix_s=1704067200.0,  # 2024-01-01 00:00:00 UTC
        ... )
    """

    semi_major_axis_m: float
    eccentricity: float
    inclination_rad: float
    raan_rad: float
    arg_periapsis_rad: float
    mean_anomaly_rad: float
    epoch_unix_s: float
