# ================================================================
# services/auth/tests/conftest.py
# ================================================================
"""
Simple pytest configuration for auth service with mock database
"""

import pytest
import pytest_asyncio
import uuid
from typing import AsyncGenerator
from unittest.mock import AsyncMock, Mock
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker
from sqlalchemy.pool import StaticPool
from fastapi.testclient import TestClient

# Test database URL - using in-memory SQLite for simplicity
TEST_DATABASE_URL = "sqlite+aiosqlite:///:memory:"

# Create test engine
test_engine = create_async_engine(
    TEST_DATABASE_URL,
    connect_args={"check_same_thread": False},
    poolclass=StaticPool,
    echo=False
)

# Create async session maker
TestingSessionLocal = async_sessionmaker(
    test_engine,
    class_=AsyncSession,
    expire_on_commit=False
)

@pytest_asyncio.fixture
async def mock_db() -> AsyncGenerator[AsyncMock, None]:
    """Create a mock database session for testing"""
    mock_session = AsyncMock(spec=AsyncSession)
    
    # Configure common mock behaviors
    mock_session.commit = AsyncMock()
    mock_session.rollback = AsyncMock()
    mock_session.close = AsyncMock()
    mock_session.refresh = AsyncMock()
    mock_session.add = Mock()
    mock_session.execute = AsyncMock()
    mock_session.scalar = AsyncMock()
    mock_session.scalars = AsyncMock()
    
    yield mock_session

@pytest_asyncio.fixture
async def real_test_db() -> AsyncGenerator[AsyncSession, None]:
    """Create a real test database session (in-memory SQLite)"""
    # Import here to avoid circular imports
    from app.core.database import Base
    
    async with test_engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)
    
    async with TestingSessionLocal() as session:
        yield session
    
    async with test_engine.begin() as conn:
        await conn.run_sync(Base.metadata.drop_all)

@pytest.fixture
def mock_redis():
    """Create a mock Redis client"""
    mock_redis = AsyncMock()
    mock_redis.get = AsyncMock(return_value=None)
    mock_redis.set = AsyncMock(return_value=True)
    mock_redis.setex = AsyncMock(return_value=True)  # Add setex method
    mock_redis.delete = AsyncMock(return_value=1)
    mock_redis.incr = AsyncMock(return_value=1)
    mock_redis.expire = AsyncMock(return_value=True)
    return mock_redis

@pytest.fixture
def test_client():
    """Create a test client for the FastAPI app"""
    from app.main import app
    return TestClient(app)

@pytest.fixture
def test_tenant_id():
    """Generate a test tenant ID"""
    return uuid.uuid4()

@pytest.fixture
def test_user_data():
    """Generate test user data"""
    unique_id = uuid.uuid4().hex[:8]
    return {
        "email": f"test_{unique_id}@bakery.es",
        "password": "TestPassword123!",
        "full_name": f"Test User {unique_id}",
        "tenant_id": uuid.uuid4()
    }

@pytest.fixture
def test_user_create_data():
    """Generate user creation data for database"""
    return {
        "id": uuid.uuid4(),
        "email": "test@bakery.es",
        "full_name": "Test User",
        "hashed_password": "$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewDtmRhckC.wSqDa",  # "password123"
        "is_active": True,
        "tenant_id": uuid.uuid4(),
        "created_at": "2024-01-01T00:00:00",
        "updated_at": "2024-01-01T00:00:00"
    }

@pytest.fixture
def mock_user():
    """Create a mock user object"""
    mock_user = Mock()
    mock_user.id = uuid.uuid4()
    mock_user.email = "test@bakery.es"
    mock_user.full_name = "Test User"
    mock_user.is_active = True
    mock_user.is_verified = False
    mock_user.tenant_id = uuid.uuid4()
    mock_user.hashed_password = "$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewDtmRhckC.wSqDa"
    mock_user.created_at = "2024-01-01T00:00:00"
    mock_user.updated_at = "2024-01-01T00:00:00"
    return mock_user

@pytest.fixture
def mock_tokens():
    """Create mock JWT tokens"""
    return {
        "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ",
        "refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ",
        "token_type": "bearer"
    }

@pytest.fixture
def auth_headers(mock_tokens):
    """Create authorization headers for testing"""
    return {"Authorization": f"Bearer {mock_tokens['access_token']}"}

def generate_random_user_data(prefix="test"):
    """Generate unique user data for testing"""
    unique_id = uuid.uuid4().hex[:8]
    return {
        "email": f"{prefix}_{unique_id}@bakery.es",
        "password": f"TestPassword{unique_id}!",
        "full_name": f"Test User {unique_id}"
    }

# Pytest configuration
def pytest_configure(config):
    """Configure pytest markers"""
    config.addinivalue_line("markers", "unit: Unit tests")
    config.addinivalue_line("markers", "integration: Integration tests") 
    config.addinivalue_line("markers", "api: API endpoint tests")
    config.addinivalue_line("markers", "security: Security-related tests")
    config.addinivalue_line("markers", "slow: Slow-running tests")

# Mock environment variables for testing
@pytest.fixture(autouse=True)
def mock_env_vars(monkeypatch):
    """Mock environment variables for testing"""
    monkeypatch.setenv("JWT_SECRET_KEY", "test-secret-key-for-testing")
    monkeypatch.setenv("JWT_ACCESS_TOKEN_EXPIRE_MINUTES", "30")
    monkeypatch.setenv("JWT_REFRESH_TOKEN_EXPIRE_DAYS", "7")
    monkeypatch.setenv("MAX_LOGIN_ATTEMPTS", "5")
    monkeypatch.setenv("LOCKOUT_DURATION_MINUTES", "30")
    monkeypatch.setenv("DATABASE_URL", TEST_DATABASE_URL)
    monkeypatch.setenv("REDIS_URL", "redis://localhost:6379/1")
    monkeypatch.setenv("RABBITMQ_URL", "amqp://guest:guest@localhost:5672/")