// =============================================================================
//  nmea2000_consumer.h -- NMEA 2000 backbone consumer
// =============================================================================
//
//  Sprint 1: PGN 127250 (Heading) + 127251 (ROT).
//  Sprint 5: PGN 129026 (COG/SOG) + 129284 (Navigation Data / XTE).
//
//  All snapshots are updated from the NMEA 2000 task (Core 0) and
//  read from the PID outer-loop task (Core 1) via a portMUX spinlock.
// =============================================================================

#pragma once

#include <cstdint>
#include <cmath>

namespace arautopilot::protocols::nmea2000 {

// ---------------------------------------------------------------------------
//  PGN 127250 / 127251 -- heading + ROT
// ---------------------------------------------------------------------------

struct HeadingSnapshot {
    float    heading_deg;       ///< 0..360, magnetic or true per is_true flag
    bool     is_true;           ///< true = true north reference
    float    rate_of_turn_dps;  ///< signed deg/s; positive = turning to stbd
    uint32_t heading_age_ms;    ///< millis() at last 127250 update
    uint32_t rot_age_ms;        ///< millis() at last 127251 update
    bool     heading_valid;     ///< fresh (<5 s)
    bool     rot_valid;         ///< fresh (<5 s)
};

// ---------------------------------------------------------------------------
//  PGN 129026 -- Course Over Ground (true) + Speed Over Ground
// ---------------------------------------------------------------------------

struct CogSogSnapshot {
    float    cog_deg;      ///< 0..360, degrees true; NAN until first message
    float    sog_kn;       ///< knots; NAN until first message
    uint32_t age_ms;       ///< millis() at last update
    bool     valid;        ///< fresh (<5 s) and non-NaN
};

// ---------------------------------------------------------------------------
//  PGN 129284 -- Navigation Data (XTE + waypoint)
// ---------------------------------------------------------------------------

struct NavDataSnapshot {
    float    xte_m;        ///< cross-track error, metres; +stbd / -port; NAN if unknown
    float    dtw_m;        ///< distance to waypoint, metres; NAN if unknown
    char     wp_name[16];  ///< null-terminated waypoint name (truncated at 15 chars)
    uint32_t age_ms;       ///< millis() at last update
    bool     valid;        ///< fresh (<5 s) and non-NaN
};

// ---------------------------------------------------------------------------
//  PGN 127237 -- Heading Track Control (incoming command from concentrador)
// ---------------------------------------------------------------------------

enum class HtcMode : uint8_t {
    STANDBY      = 0,  ///< Autopilot off / manual steering
    HEADING_HOLD = 1,  ///< Hold commanded heading
    TRACK        = 2,  ///< Track to waypoint (NMEA route)
    UNKNOWN      = 0xFF,
};

struct HeadingControlSnapshot {
    float    commanded_heading_deg;  ///< 0..360 (NAN if not set)
    HtcMode  mode;                   ///< desired autopilot mode
    uint8_t  source_addr;            ///< NMEA2000 source address of sender
    uint32_t age_ms;                 ///< millis() at last 127237 update
    bool     valid;                  ///< fresh (<3 s) and parsed correctly
};

// ---------------------------------------------------------------------------
//  Public API
// ---------------------------------------------------------------------------

/// Initialise the NMEA2000 stack with our PGN handlers.
void nmea2000_consumer_init();

/// Spawn the FreeRTOS task that pumps NMEA2000.ParseMessages() forever.
void nmea2000_consumer_start_task();

/// Thread-safe read of the latest heading + ROT snapshot.
HeadingSnapshot nmea2000_latest();

/// Thread-safe read of the latest COG/SOG snapshot (PGN 129026).
CogSogSnapshot  nmea2000_cog_sog();

/// Thread-safe read of the latest navigation data snapshot (PGN 129284).
NavDataSnapshot nmea2000_nav_data();

/// True if heading age or ROT age exceeds 5 s.
bool nmea2000_is_stale();

/// True if COG/SOG age exceeds 5 s or data was never received.
bool nmea2000_cog_is_stale();

/// Thread-safe read of the latest Heading Track Control command (PGN 127237).
/// Returns the last command received from an external concentrador.
HeadingControlSnapshot nmea2000_htc();

/// True if no PGN 127237 has been received in the last 3 s.
bool nmea2000_htc_is_stale();

}  // namespace arautopilot::protocols::nmea2000
