#ifndef NTP_TIMESYNC_H
#define NTP_TIMESYNC_H

// ============================================================================
// ntp_timesync.h — Wall-clock sync over WiFi (SNTP), for units with no GPS
//
// WHY THIS EXISTS
// ---------------
// resolve_detection_ts() (c2_wifi_bridge.cpp) resolves a detection's UTC in
// this order:
//     1. evt.timestamp_utc, if it already looks like a real epoch
//     2. timesync_now_utc_ms()   -- mesh_timesync, fed by MSG_TYPE_TIME_SYNC
//     3. gps_get_utc_epoch()     -- requires a GPS module
//     4. evt.timestamp_utc as-is -- millis()/1000, i.e. SECONDS SINCE BOOT
//
// A Heltec V3 has no GNSS header, and nothing in this firmware ever *emits*
// MSG_TYPE_TIME_SYNC (0x19) -- mesh_timesync only ever receives it. So on a
// V3, steps 2 and 3 both fail and a detection posted DIRECTLY to C2 carries
// boot-seconds. The server's dayKey() maps that to 1970, filing the detection
// under a day index the "recent" query never scans: it ingests successfully,
// returns 200, and is invisible on the map forever.
//
// This module closes that gap. The LoRa peer-relay path never needed it --
// there the *relaying* unit (which has GPS) restamps the peer's event on the
// way out -- but a V3 talking straight to C2 over WiFi has no such helper.
//
// HOW IT WORKS
// ------------
// Once WiFi is up, start SNTP, wait for a plausible epoch, then synthesize the
// exact 12-byte MSG_TYPE_TIME_SYNC packet mesh_timesync already parses and
// feed it through timesync_handle_packet() TIMESYNC_MIN_PACKETS times. That
// deliberately reuses the existing, tested offset/IIR machinery rather than
// adding a second parallel clock: after this, timesync_is_synced() is true and
// every existing caller (resolve_detection_ts, the health post, the detection
// build site in main.cpp) picks up real UTC with no changes.
//
// SAFETY ON GPS-EQUIPPED UNITS
// ----------------------------
// Harmless on a V4. If the mesh already synced the unit, this is a no-op. If
// SNTP never resolves (no internet, captive portal), nothing is ever fed and
// behavior is byte-identical to before -- GPS still serves as the clock via
// step 3. It only ever ADDS a source that was previously absent.
// ============================================================================

// Drive the SNTP state machine — call every loop() cycle. No-op once a clock
// has been established (by this module or by the mesh) and while WiFi is down.
void ntp_timesync_tick();

// True once this module has successfully fed a real epoch into mesh_timesync.
// Distinct from timesync_is_synced(), which is also true when the mesh was the
// source — this reports specifically whether NTP is what supplied the clock.
bool ntp_timesync_have_synced();

// Last epoch (seconds) obtained from SNTP, or 0 if never resolved. Exposed for
// REPORT_STATUS so a field unit can be asked "do you actually know what time
// it is, and where did that come from?" without a debugger.
unsigned long ntp_timesync_last_epoch();

#endif // NTP_TIMESYNC_H
