from __future__ import annotations

import importlib
import sys
from datetime import date, timedelta
from pathlib import Path

import pytest

ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "scripts" / "health"))
sys.path.insert(0, str(ROOT / "tests"))

from dashboard_v5.read_api import APIError, dispatch_api  # noqa: E402
from fixtures.dashboard_v5_fixture import build_dashboard_v5_fixture  # noqa: E402


def fixture(tmp_path: Path) -> Path:
    database = tmp_path / "sprint6e4a.db"
    build_dashboard_v5_fixture(database)
    return database


def test_real_search_terms_calendar_and_exact_30_day_contract(tmp_path: Path):
    database = fixture(tmp_path)
    terms = (
        "Blutdruck", "systolisch", "diastolisch", "HRV", "Ruhepuls", "Schlaf",
        "Schritte", "Gewicht", "CRP", "Leukozyten", "Thrombozyten",
    )
    for term in terms:
        payload = dispatch_api(database, "/api/v1/metric-catalog", f"q={term}")
        assert payload["groups"]["metrics"], term

    today = date.today()
    start = today - timedelta(days=29)
    series = dispatch_api(
        database,
        "/api/v1/series",
        f"metric=apple.hrv&resolution=day&from={start.isoformat()}&to={today.isoformat()}",
    )
    assert series["coverage"]["expected_days"] == 30
    assert all(start.isoformat() <= point["date"] <= today.isoformat() for point in series["points"])

    for month_start in (date(today.year, today.month, 1), date(2026, 5, 1), date(2010, 2, 1)):
        following = (month_start.replace(day=28) + timedelta(days=4)).replace(day=1)
        month_end = following - timedelta(days=1)
        calendar = dispatch_api(
            database,
            "/api/v1/calendar",
            f"from={month_start.isoformat()}&to={month_end.isoformat()}",
        )
        assert len(calendar["days"]) == month_end.day


def test_range_and_record_queries_fail_closed(tmp_path: Path):
    database = fixture(tmp_path)
    for query in (
        "metric=apple.hrv&from=2026-05-01&from=2026-05-02&to=2026-05-30&resolution=day",
        "metric=apple.hrv&from=2026-05-01&resolution=day",
        "metric=apple.hrv&from=2026-05-30&to=2026-05-01&resolution=day",
    ):
        with pytest.raises(APIError):
            dispatch_api(database, "/api/v1/series", query)
    for route in (
        "/api/v1/record-summary", "/api/v1/record-labs", "/api/v1/medications",
        "/api/v1/appointments", "/api/v1/documents",
    ):
        assert isinstance(dispatch_api(database, route, ""), dict)


def test_render_profile_assets_and_single_explorer_contract(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
    database = fixture(tmp_path)
    module = importlib.import_module("health_dashboard_v5")
    standard = tmp_path / "standard.html"
    preview = tmp_path / "preview.html"

    monkeypatch.setattr(sys, "argv", ["health_dashboard_v5.py", "--db", str(database), "--output", str(standard)])
    assert module.main() == 0
    monkeypatch.setattr(sys, "argv", ["health_dashboard_v5.py", "--db", str(database), "--output", str(preview), "--health-record-6e"])
    assert module.main() == 0

    standard_html = standard.read_text(encoding="utf-8")
    preview_html = preview.read_text(encoding="utf-8")
    for asset in (
        "dashboard-v5-range.js", "dashboard-v5-api-explorer.js",
        "dashboard-v5-global-search.js", "dashboard-v5-day-controller.js", "dashboard-v5-record.js",
    ):
        assert asset not in standard_html
        assert preview_html.count(asset) == 1
    assert preview_html.count("data-explorer-shell='unified-echarts'") == 1
    assert "id='explorer-chart'" not in preview_html
    assert "id='metric-picker'" not in preview_html
    assert "Gesundheitswert suchen und hinzufügen" in preview_html
    assert "Lebensmittel-Zuordnungen" in preview_html
    assert "Validierte Aktionen werden lokal vorgemerkt und erst vom privaten Worker angewendet." in preview_html
    assert "Nur Anzeige – Bearbeitung folgt im Ernährungs-Sprint 6G" not in preview_html


def test_record_and_calendar_clients_do_not_dump_internal_objects():
    record = (ROOT / "scripts/health/assets/health-assets/dashboard-v5-record.js").read_text(encoding="utf-8")
    calendar = (ROOT / "scripts/health/assets/health-assets/dashboard-v5-day-controller.js").read_text(encoding="utf-8")
    assert "Object.values(item)" not in record
    assert "Akte ist derzeit nicht verfügbar" not in record
    assert "Technische Details" in record
    assert "Sicherer Fehlercode" not in record
    assert "JSON.stringify({ timezone" not in calendar
    assert "code.replace('has_', '')" not in calendar
    assert "Erneut versuchen" in calendar


def test_server_allowlists_only_local_new_assets(monkeypatch: pytest.MonkeyPatch, tmp_path: Path):
    monkeypatch.delenv("HEALTH_DASHBOARD_TEST_INSTANCE_ID", raising=False)
    monkeypatch.setenv("HEALTH_DASHBOARD_FILE", str(tmp_path / "v4.html"))
    module = importlib.import_module("health_dashboard_server")
    assert module.ASSET_ROUTES["/health-assets/dashboard-v5-range.js"][0] == "dashboard-v5-range.js"
    assert module.ASSET_ROUTES["/health-assets/dashboard-v5-global-search.js"][0] == "dashboard-v5-global-search.js"
