"""Coverage for the daily-prep hardening pass.

Targets the two prep-quality defects observed via the fable MCP on
2026-05-19 (conversation #291):

  1. Fabricated weather ("partly cloudy with a high of 68°F and a 15%
     chance of rain") emitted with an empty weather section.
  2. Self-contradictory overdue phrasing ("still on the list, not
     currently due, 88 days ago"; "1 days ago").

All targets are pure sync functions — no DB / LLM needed.
"""
import datetime

from fabledassistant.services.journal_prep import (
    _prose_fabricated_weather,
    _render_sections_for_prompt,
    _render_task_line,
)

TODAY = datetime.date(2026, 5, 19)


# ── Overdue phrasing ────────────────────────────────────────────────────────


def test_overdue_line_singular_day():
    line = _render_task_line(
        {"title": "Change my oil", "due_date": "2026-05-18", "days_overdue": 1},
        include_due=False, include_overdue=True,
    )
    assert "1 day overdue" in line
    assert "1 days" not in line  # the old ungrammatical form is gone


def test_overdue_line_plural_days_no_contradiction():
    line = _render_task_line(
        {"title": "Research X", "due_date": "2026-02-20", "days_overdue": 88},
        include_due=False, include_overdue=True,
    )
    assert "88 days overdue" in line
    assert "was due 2026-02-20" in line
    assert "days ago" not in line  # replaced by unambiguous "overdue"


def test_overdue_section_header_is_unambiguous():
    out = _render_sections_for_prompt({
        "tasks_overdue": [
            {"title": "Research X", "due_date": "2026-02-20", "days_overdue": 88},
        ],
    })
    assert "past their due date, still open" in out
    # The phrase that the model parroted into the self-contradiction is gone.
    assert "not currently due" not in out


# ── Weather absent-marker ───────────────────────────────────────────────────


def test_empty_weather_emits_explicit_none_marker():
    out = _render_sections_for_prompt({
        "tasks_overdue": [
            {"title": "Change my oil", "due_date": "2026-05-18", "days_overdue": 1},
        ],
        "weather": [],
    })
    assert "WEATHER: none available" in out
    assert "Do NOT mention weather" in out


def test_present_weather_renders_data_not_marker():
    out = _render_sections_for_prompt({
        "tasks_due_today": [{"title": "Ship it"}],
        "weather": [{
            "location_label": "Home",
            "forecast_json": {"daily": {
                "temperature_2m_max": [70],
                "temperature_2m_min": [52],
                "precipitation_probability_max": [10],
            }},
        }],
    })
    assert "WEATHER:" in out
    assert "none available" not in out
    assert "high 70°" in out


def test_quiet_day_returns_fabrication_forbidding_text():
    out = _render_sections_for_prompt({})
    assert "quiet day" in out
    assert "Do not invent weather" in out


# ── Fabricated-weather guard ────────────────────────────────────────────────


def test_guard_flags_the_real_observed_hallucination():
    prose = (
        "You have two overdue tasks. The weather today is partly cloudy "
        "with a high of 68°F and a 15% chance of rain. What's on your mind?"
    )
    assert _prose_fabricated_weather(prose, {"weather": []}) is True


def test_guard_flags_bare_temperature_glyph():
    assert _prose_fabricated_weather("Expect around 72° later.", {"weather": []}) is True


def test_guard_passes_clean_prose():
    prose = "Two tasks are overdue and nothing is due today. What's on your mind?"
    assert _prose_fabricated_weather(prose, {"weather": []}) is False


def test_guard_no_false_positive_on_rain_in_task_title():
    # Bare "rain" must NOT trip the guard — only "chance of rain" etc. does.
    prose = "Don't forget to buy rain boots and finish the training module."
    assert _prose_fabricated_weather(prose, {"weather": []}) is False


def test_guard_allows_weather_when_data_present():
    prose = "Home is 70°F with a 10% chance of rain."
    sections = {"weather": [{"location_label": "Home"}]}
    assert _prose_fabricated_weather(prose, sections) is False
