"""Shared fixtures for end-to-end API tests.

Uses the real FastAPI app with a module-scoped TestClient to avoid
repeated lifespan startup/shutdown issues. Each test function gets
fresh, empty stores via the _clear_stores helper.
"""

import pytest

from wled_controller.config import get_config


# Resolve the API key from the real config (same key used in production tests)
_config = get_config()
API_KEY = next(iter(_config.auth.api_keys.values()), "")
AUTH_HEADERS = {"Authorization": f"Bearer {API_KEY}"}


@pytest.fixture(scope="session")
def _test_client():
    """Session-scoped TestClient to avoid lifespan re-entry issues.

    The app's lifespan (MQTT, automation engine, health monitoring, etc.)
    starts once for the entire e2e test session and shuts down after all
    tests complete.
    """
    from fastapi.testclient import TestClient
    from wled_controller.main import app

    with TestClient(app, raise_server_exceptions=False) as c:
        yield c


@pytest.fixture
def client(_test_client):
    """Per-test client with auth headers and clean stores.

    Clears all entity stores before each test so tests are independent.
    """
    _clear_stores()
    _test_client.headers["Authorization"] = f"Bearer {API_KEY}"
    yield _test_client
    # Clean up after test
    _clear_stores()


def _clear_stores():
    """Remove all entities from all stores for test isolation."""
    from wled_controller.api import dependencies as deps

    store_clearers = [
        (deps.get_device_store, "get_all_devices", "delete_device"),
        (deps.get_output_target_store, "get_all_targets", "delete_target"),
        (deps.get_color_strip_store, "get_all_sources", "delete_source"),
        (deps.get_value_source_store, "get_all", "delete"),
        (deps.get_sync_clock_store, "get_all", "delete"),
        (deps.get_automation_store, "get_all", "delete"),
        (deps.get_scene_preset_store, "get_all", "delete"),
    ]
    for getter, list_method, delete_method in store_clearers:
        try:
            store = getter()
            items = getattr(store, list_method)()
            for item in items:
                item_id = getattr(item, "id", getattr(item, "device_id", None))
                if item_id:
                    try:
                        getattr(store, delete_method)(item_id)
                    except Exception:
                        pass
        except RuntimeError:
            pass  # Store not initialized yet
