from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]


def test_cache_service_reexports_cache_manager_state():
    from services import cache_manager, cache_service

    assert cache_service._SALES_DF_CACHE is cache_manager._SALES_DF_CACHE
    assert cache_service._SALES_PROCESSED_CACHE is cache_manager._SALES_PROCESSED_CACHE
    assert cache_service._SALES_OPTIONS_CACHE is cache_manager._SALES_OPTIONS_CACHE
    assert cache_service._SALES_ANALYSIS_RESULT_CACHE is cache_manager._SALES_ANALYSIS_RESULT_CACHE
    assert cache_service._DASHBOARD_DATA_CACHE is cache_manager._DASHBOARD_DATA_CACHE


def test_routes_share_sales_cache_manager_state():
    from services import cache_manager
    from routes import export_routes, import_routes, sales_routes

    sales_df_cache, sales_processed_cache, clear_for_table = import_routes._get_cache_refs()

    assert sales_routes._SALES_PROCESSED_CACHE is cache_manager._SALES_PROCESSED_CACHE
    assert export_routes._get_sales_cache() is cache_manager._SALES_PROCESSED_CACHE
    assert sales_df_cache is cache_manager._SALES_DF_CACHE
    assert sales_processed_cache is cache_manager._SALES_PROCESSED_CACHE
    assert clear_for_table is cache_manager.clear_sales_cache_for_table


def test_clear_sales_cache_for_table_removes_table_and_range_aliases():
    from services import cache_manager

    cache_manager.clear_sales_cache()
    cache_manager._SALES_DF_CACHE["realtime_sales_monthly"] = object()
    cache_manager._SALES_DF_CACHE["other_table"] = object()
    cache_manager._SALES_PROCESSED_CACHE.update({
        "realtime_sales_monthly": {"df": "base"},
        "realtime_sales_monthly_1m": {"df": "range"},
        "realtime_sales_monthly_custom_2026-01-01_2026-01-31": {"df": "custom"},
        "other_table": {"df": "other"},
    })

    cache_manager.clear_sales_cache_for_table("realtime_sales_monthly")

    assert "realtime_sales_monthly" not in cache_manager._SALES_DF_CACHE
    assert "other_table" in cache_manager._SALES_DF_CACHE
    assert "realtime_sales_monthly" not in cache_manager._SALES_PROCESSED_CACHE
    assert "realtime_sales_monthly_1m" not in cache_manager._SALES_PROCESSED_CACHE
    assert "realtime_sales_monthly_custom_2026-01-01_2026-01-31" not in cache_manager._SALES_PROCESSED_CACHE
    assert "other_table" in cache_manager._SALES_PROCESSED_CACHE


def test_set_sales_processed_cache_adds_timestamp_and_aliases():
    from services import cache_manager

    cache_manager.clear_sales_cache()
    entry = {"df": "data", "cols": {"date": "日期"}}

    cache_manager.set_sales_processed_cache(
        "realtime_sales_monthly_3m",
        entry,
        aliases=("realtime_sales_monthly",),
    )

    cached = cache_manager._SALES_PROCESSED_CACHE["realtime_sales_monthly_3m"]
    assert cached is entry
    assert cached["time"] > 0
    assert cache_manager._SALES_PROCESSED_CACHE["realtime_sales_monthly"] is entry


def test_dashboard_cache_clear_restores_expected_shape(tmp_path, monkeypatch):
    from services import cache_manager

    shared_cache = tmp_path / "dashboard_full_cache.pkl"
    stale_cache = tmp_path / "dashboard_full_cache_stale.pkl"
    shared_cache.write_bytes(b"stale")
    monkeypatch.setattr(cache_manager, "_DASHBOARD_SHARED_CACHE_FILE", shared_cache)
    monkeypatch.setattr(cache_manager, "_DASHBOARD_STALE_CACHE_FILE", stale_cache)

    cache_manager._DASHBOARD_DATA_CACHE["consolidated_data"] = ["stale"]
    cache_manager._DASHBOARD_DATA_CACHE["full_data"] = ["stale"]

    cache_manager.clear_dashboard_cache()

    assert cache_manager._DASHBOARD_DATA_CACHE == {
        "consolidated_data": None,
        "consolidated_timestamp": None,
        "today_start": None,
        "full_data": None,
        "full_timestamp": None,
    }
    assert not shared_cache.exists()
    assert stale_cache.exists()


def test_cache_dicts_are_only_defined_in_cache_manager():
    assignments = []
    for path in [ROOT / "app.py", *ROOT.glob("routes/*.py"), *ROOT.glob("services/*.py")]:
        text = path.read_text(encoding="utf-8")
        for marker in ("_SALES_DF_CACHE = {}", "_SALES_PROCESSED_CACHE = {}", "_DASHBOARD_DATA_CACHE = {"):
            if marker in text:
                assignments.append((path.relative_to(ROOT).as_posix(), marker))

    assert assignments == [
        ("services/cache_manager.py", "_SALES_DF_CACHE = {}"),
        ("services/cache_manager.py", "_SALES_PROCESSED_CACHE = {}"),
        ("services/cache_manager.py", "_DASHBOARD_DATA_CACHE = {"),
    ]
