from __future__ import annotations

from datetime import UTC, datetime

from jarvis_finance.quality.freshness import assess_freshness


def test_market_freshness_counts_trading_sessions_not_weekend_calendar_days():
    result = assess_freshness(
        available=True,
        as_of="2026-07-30",
        now=datetime(2026, 8, 2, tzinfo=UTC),
        source_kind="market",
    )

    assert result.status == "fresh"
    assert result.expected_as_of == "2026-07-31"
    assert result.reason_code == "within_market_session_lag"


def test_market_freshness_uses_six_holidays():
    result = assess_freshness(
        available=True,
        as_of="2026-04-02",
        now=datetime(2026, 4, 6, tzinfo=UTC),
        source_kind="market",
    )

    assert result.status == "fresh"
    assert result.expected_as_of == "2026-04-02"


def test_crypto_freshness_remains_24_7_and_does_not_ignore_weekends():
    result = assess_freshness(
        available=True,
        as_of="2026-07-30T00:00:00Z",
        now=datetime(2026, 8, 2, tzinfo=UTC),
        source_kind="crypto_24_7",
    )

    assert result.status == "stale"
    assert result.reason_code == "crypto_update_overdue"


def test_bank_and_managed_portfolio_follow_canonical_update_rhythms():
    bank = assess_freshness(
        available=True,
        as_of="2026-07-27",
        now=datetime(2026, 8, 2, tzinfo=UTC),
        source_kind="bank_balance",
    )
    managed = assess_freshness(
        available=True,
        as_of="2026-07-27",
        now=datetime(2026, 8, 2, tzinfo=UTC),
        source_kind="managed_portfolio",
    )

    assert bank.status == "fresh"
    assert bank.reason_code == "within_bank_update_rhythm"
    assert managed.status == "fresh"
    assert managed.reason_code == "within_managed_update_rhythm"


def test_missing_value_and_missing_business_date_are_distinct():
    unavailable = assess_freshness(
        available=False,
        as_of=None,
        now=datetime(2026, 8, 2, tzinfo=UTC),
        source_kind="bank_balance",
    )
    unknown = assess_freshness(
        available=True,
        as_of=None,
        now=datetime(2026, 8, 2, tzinfo=UTC),
        source_kind="bank_balance",
    )

    assert unavailable.status == "unavailable"
    assert unavailable.reason_code == "value_unavailable"
    assert unknown.status == "unknown"
    assert unknown.reason_code == "business_date_missing"
