use aerocontext_core::{GeoPoint, NavDataCycle, NavDataSnapshot, NavPoint, NavPointKind};
use chrono::NaiveDate;

use super::*;

fn snapshot() -> NavDataSnapshot {
    let effective = NaiveDate::from_ymd_opt(2026, 5, 21).unwrap();
    NavDataSnapshot::new(
        NavDataCycle::faa_nasr(effective).unwrap(),
        vec![
            NavPoint::new(
                "KSFO",
                NavPointKind::Airport,
                GeoPoint {
                    lat: 37.61881,
                    lon: -122.37542,
                },
            )
            .with_name(Some("San Francisco International".to_owned())),
            NavPoint::new(
                "OAK",
                NavPointKind::Navaid,
                GeoPoint {
                    lat: 37.72595,
                    lon: -122.22361,
                },
            ),
        ],
    )
}

#[test]
fn resolves_case_insensitively_and_trimmed() {
    let report = resolve_in_snapshot(&snapshot(), "  ksfo ").unwrap();
    assert!(report.found);
    assert_eq!(report.ident, "KSFO");
    assert_eq!(report.kind.as_deref(), Some("airport"));
    assert_eq!(report.lat, Some(37.61881));
    assert_eq!(report.lon, Some(-122.37542));
    assert_eq!(report.name.as_deref(), Some("San Francisco International"));
    assert_eq!(report.cycle, "2026-05-21..2026-06-18");
    assert!(report.note.is_none());
}

#[test]
fn resolves_unnamed_navaid() {
    let report = resolve_in_snapshot(&snapshot(), "oak").unwrap();
    assert!(report.found);
    assert_eq!(report.kind.as_deref(), Some("navaid"));
    assert!(report.name.is_none());
}

#[test]
fn reports_a_clear_not_found() {
    let report = resolve_in_snapshot(&snapshot(), "ZZZZ").unwrap();
    assert!(!report.found);
    assert_eq!(report.ident, "ZZZZ");
    assert!(report.kind.is_none());
    assert!(report.lat.is_none());
    assert!(report.lon.is_none());
    let note = report.note.unwrap();
    assert!(note.contains("ZZZZ"));
    assert!(note.contains("2026-05-21..2026-06-18"));
}

#[test]
fn rejects_blank_ident() {
    let error = resolve_in_snapshot(&snapshot(), "   ").unwrap_err();
    assert!(matches!(error, ToolError::InvalidParam { .. }));
}

#[test]
fn labels_source_named_kinds_verbatim() {
    assert_eq!(
        kind_label(&NavPointKind::Other("balloonport".to_owned())),
        "balloonport"
    );
}
