"""
Test di integrazione per gli endpoint di autenticazione.
"""

import os
import pytest

os.environ.setdefault("ENCRYPTION_KEY", "b" * 64)
os.environ.setdefault("SECRET_KEY", "integration-test-secret-key-only-for-tests")
os.environ.setdefault("DATABASE_URL", "sqlite+aiosqlite:///./test_integration.db")
os.environ.setdefault("DATABASE_URL_SYNC", "sqlite:///./test_integration.db")


class TestLoginEndpoint:
    @pytest.mark.asyncio
    async def test_login_success(self, client, admin_user):
        response = await client.post(
            "/api/v1/auth/login",
            json={
                "email": "admin@test.com",
                "password": "AdminPass1!",
            },
        )
        assert response.status_code == 200
        data = response.json()
        assert "access_token" in data
        assert "refresh_token" in data
        assert data["token_type"] == "bearer"
        assert data["expires_in"] > 0

    @pytest.mark.asyncio
    async def test_login_wrong_password_returns_401(self, client, admin_user):
        response = await client.post(
            "/api/v1/auth/login",
            json={
                "email": "admin@test.com",
                "password": "WrongPassword1!",
            },
        )
        assert response.status_code == 401

    @pytest.mark.asyncio
    async def test_login_nonexistent_user_returns_401(self, client):
        response = await client.post(
            "/api/v1/auth/login",
            json={
                "email": "nobody@example.com",
                "password": "Password1!",
            },
        )
        assert response.status_code == 401

    @pytest.mark.asyncio
    async def test_login_missing_fields_returns_422(self, client):
        response = await client.post(
            "/api/v1/auth/login",
            json={"email": "test@test.com"},  # manca password
        )
        assert response.status_code == 422

    @pytest.mark.asyncio
    async def test_login_invalid_email_returns_422(self, client):
        response = await client.post(
            "/api/v1/auth/login",
            json={"email": "not-an-email", "password": "Password1!"},
        )
        assert response.status_code == 422


class TestMeEndpoint:
    @pytest.mark.asyncio
    async def test_me_returns_current_user(self, client, admin_token, admin_user):
        response = await client.get(
            "/api/v1/auth/me",
            headers={"Authorization": f"Bearer {admin_token}"},
        )
        assert response.status_code == 200
        data = response.json()
        assert data["email"] == "admin@test.com"
        assert data["role"] == "admin"

    @pytest.mark.asyncio
    async def test_me_without_token_returns_403(self, client):
        response = await client.get("/api/v1/auth/me")
        assert response.status_code == 403

    @pytest.mark.asyncio
    async def test_me_with_invalid_token_returns_401(self, client):
        response = await client.get(
            "/api/v1/auth/me",
            headers={"Authorization": "Bearer invalid.token.here"},
        )
        assert response.status_code == 401


class TestHealthEndpoint:
    @pytest.mark.asyncio
    async def test_health_returns_ok(self, client):
        response = await client.get("/health")
        assert response.status_code == 200
        data = response.json()
        assert data["status"] == "ok"


class TestRefreshEndpoint:
    @pytest.mark.asyncio
    async def test_refresh_with_invalid_token_returns_401(self, client):
        response = await client.post(
            "/api/v1/auth/refresh",
            json={"refresh_token": "invalid.token.here"},
        )
        assert response.status_code == 401


class TestTOTPEndpoints:
    @pytest.mark.asyncio
    async def test_totp_setup_returns_qr(self, client, admin_token):
        response = await client.post(
            "/api/v1/auth/totp/setup",
            headers={"Authorization": f"Bearer {admin_token}"},
        )
        assert response.status_code == 200
        data = response.json()
        assert "secret" in data
        assert "qr_uri" in data
        assert "qr_image_base64" in data
        assert data["qr_uri"].startswith("otpauth://totp/")

    @pytest.mark.asyncio
    async def test_totp_verify_wrong_code_returns_400(self, client, admin_token):
        # Prima setup
        await client.post(
            "/api/v1/auth/totp/setup",
            headers={"Authorization": f"Bearer {admin_token}"},
        )
        # Poi verify con codice errato
        response = await client.post(
            "/api/v1/auth/totp/verify",
            headers={"Authorization": f"Bearer {admin_token}"},
            json={"totp_code": "000000"},
        )
        assert response.status_code == 400
