"""Shared test fixtures for Flask client tests.

Creates a Flask test client and mocks the API client (requests to FastAPI server).
"""
import sys
from pathlib import Path
from unittest.mock import MagicMock, patch

import pytest

# Ensure the client package is importable
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

from app import create_app

# All blueprint modules that import api_client at module level.
# We must patch at the *use-site* (blueprint namespace) so the local name
# ``api_client`` in each module points to the mock, not the real singleton.
_API_CLIENT_PATCH_TARGETS = [
    "blueprints.auth.api_client",
    "blueprints.maker.api_client",
    "blueprints.measure.api_client",
    "blueprints.statistics.api_client",
]


@pytest.fixture
def flask_app():
    """Create a Flask application configured for testing."""
    app = create_app()
    app.config["TESTING"] = True
    app.config["WTF_CSRF_ENABLED"] = False
    app.config["SECRET_KEY"] = "test-secret-key"

    # Provide default template variables that are normally set inside
    # specific Jinja2 blocks and therefore not visible to sibling blocks.
    @app.context_processor
    def _inject_template_defaults():
        return {
            "versions": [],
            "current_version": None,
        }

    return app


@pytest.fixture
def client(flask_app):
    """Yield a Flask test client."""
    with flask_app.test_client() as test_client:
        yield test_client


@pytest.fixture
def logged_in_client(flask_app):
    """Yield a Flask test client with a logged-in session."""
    with flask_app.test_client() as test_client:
        with test_client.session_transaction() as sess:
            sess["api_key"] = "test-api-key-12345"
            sess["user"] = {
                "id": 1,
                "username": "testuser",
                "display_name": "Test User",
                "roles": ["Maker", "MeasurementTec", "Metrologist"],
                "is_admin": True,
                "language_pref": "en",
                "theme_pref": "light",
                "active": True,
            }
            sess["user_id"] = 1
            sess["language"] = "en"
            sess["theme"] = "light"
        yield test_client


@pytest.fixture
def mock_api_client():
    """Patch the api_client singleton used in blueprints.

    Patches every blueprint module that does
    ``from services.api_client import api_client`` so the local name
    in each module resolves to the same MagicMock instance.

    Yields the mocked APIClient instance so tests can configure responses:

        mock_api_client.get.return_value = {"items": [...], "total": 1}
        mock_api_client.post.return_value = {"user": {...}, "api_key": "..."}
    """
    mock = MagicMock()
    # Default: all methods return empty success dict
    mock.get.return_value = {}
    mock.post.return_value = {}
    mock.put.return_value = {}
    mock.delete.return_value = {}

    # Stack patches for every blueprint that imports api_client
    patchers = [patch(target, mock) for target in _API_CLIENT_PATCH_TARGETS]
    for p in patchers:
        p.start()

    yield mock

    for p in patchers:
        p.stop()
