"""Integration tests for the auth routes.

Uses FastAPI TestClient with a mocked user store.
Does not require a running PostgreSQL.
"""

import pytest
from fastapi.testclient import TestClient
from unittest.mock import MagicMock, patch

from app.infrastructure.auth.user_store import UserRecord


@pytest.fixture
def client():
    """Return a TestClient with a mocked user store."""
    mock_store = MagicMock()
    alice = UserRecord(id="uuid-1", username="alice", hashed_pw="hashed", role="admin", is_active=True)
    mock_store.authenticate.side_effect = lambda u, p: alice if (u == "alice" and p == "correct") else None

    with patch("app.shared.bootstrap.get_user_store", return_value=mock_store):
        # Import after patch so the mock is active when routes import bootstrap.
        from app.api.main import app
        with TestClient(app, raise_server_exceptions=False) as c:
            yield c


def test_login_returns_token_for_valid_credentials(client):
    """POST /auth/token must return an access_token for valid credentials."""
    resp = client.post("/api/v1/auth/token", data={"username": "alice", "password": "correct"})
    assert resp.status_code == 200
    body = resp.json()
    assert "access_token" in body
    assert body["token_type"] == "bearer"


def test_login_returns_401_for_wrong_password(client):
    """POST /auth/token must return 401 for wrong password."""
    resp = client.post("/api/v1/auth/token", data={"username": "alice", "password": "wrong"})
    assert resp.status_code == 401


def test_me_returns_user_when_authenticated(client):
    """GET /auth/me must return user identity when a valid token is provided."""
    login_resp = client.post("/api/v1/auth/token", data={"username": "alice", "password": "correct"})
    assert login_resp.status_code == 200, login_resp.text
    token = login_resp.json()["access_token"]

    me_resp = client.get("/api/v1/auth/me", headers={"Authorization": f"Bearer {token}"})
    assert me_resp.status_code == 200
    assert me_resp.json()["username"] == "alice"
    assert me_resp.json()["role"] == "admin"


def test_me_returns_401_without_token(client):
    """GET /auth/me must return 401 when no token is provided."""
    resp = client.get("/api/v1/auth/me")
    assert resp.status_code == 401
