# tests/fixtures/admin_platform_fixtures.py
"""
Admin platform assignment test fixtures.

Provides fixtures for testing super admin and platform admin functionality.
"""

import uuid

import pytest

from app.modules.tenancy.models import AdminPlatform, Platform, User


@pytest.fixture
def test_platform(db):
    """Create a test platform."""
    unique_id = str(uuid.uuid4())[:8]
    platform = Platform(
        code=f"test_{unique_id}",
        name=f"Test Platform {unique_id}",
        description="A test platform for unit tests",
        path_prefix=f"test{unique_id}",
        is_active=True,
        is_public=True,
        default_language="en",
        supported_languages=["en", "fr", "de"],
    )
    db.add(platform)
    db.commit()
    db.refresh(platform)
    return platform


@pytest.fixture
def another_platform(db):
    """Create another test platform."""
    unique_id = str(uuid.uuid4())[:8]
    platform = Platform(
        code=f"another_{unique_id}",
        name=f"Another Platform {unique_id}",
        description="Another test platform",
        path_prefix=f"another{unique_id}",
        is_active=True,
        is_public=True,
        default_language="fr",
        supported_languages=["fr", "en"],
    )
    db.add(platform)
    db.commit()
    db.refresh(platform)
    return platform


@pytest.fixture
def test_admin_platform_assignment(db, test_platform_admin, test_platform, test_super_admin):
    """Create an admin platform assignment."""
    assignment = AdminPlatform(
        user_id=test_platform_admin.id,
        platform_id=test_platform.id,
        is_active=True,
        assigned_by_user_id=test_super_admin.id,
    )
    db.add(assignment)
    db.commit()
    db.refresh(assignment)
    return assignment


@pytest.fixture
def platform_admin_with_platform(db, auth_manager, test_platform, test_super_admin):
    """Create a platform admin with an assigned platform."""
    unique_id = str(uuid.uuid4())[:8]
    hashed_password = auth_manager.hash_password("platformadminpass123")

    # Create platform admin
    admin = User(
        email=f"padmin_{unique_id}@example.com",
        username=f"padmin_{unique_id}",
        hashed_password=hashed_password,
        role="platform_admin",
        is_active=True,
        is_email_verified=True,
    )
    db.add(admin)
    db.flush()

    # Assign to platform
    assignment = AdminPlatform(
        user_id=admin.id,
        platform_id=test_platform.id,
        is_active=True,
        assigned_by_user_id=test_super_admin.id,
    )
    db.add(assignment)
    db.commit()
    db.refresh(admin)

    return admin


@pytest.fixture
def platform_admin_with_platform_headers(client, platform_admin_with_platform, test_platform):
    """Get authentication headers for platform admin with platform context."""
    # First login
    response = client.post(
        "/api/v1/admin/auth/login",
        json={
            "email_or_username": platform_admin_with_platform.username,
            "password": "platformadminpass123",
        },
    )
    assert response.status_code == 200, f"Platform admin login failed: {response.text}"
    token = response.json()["access_token"]

    # Select platform
    response = client.post(
        "/api/v1/admin/auth/select-platform",
        params={"platform_id": test_platform.id},
        headers={"Authorization": f"Bearer {token}"},
    )
    assert response.status_code == 200, f"Platform selection failed: {response.text}"
    token = response.json()["access_token"]

    return {"Authorization": f"Bearer {token}"}


@pytest.fixture
def platform_factory(db):
    """Factory fixture for creating platforms."""
    def _create_platform(**kwargs):
        unique_id = str(uuid.uuid4())[:8]
        defaults = {
            "code": f"factory_{unique_id}",
            "name": f"Factory Platform {unique_id}",
            "path_prefix": f"factory{unique_id}",
            "is_active": True,
            "is_public": True,
            "default_language": "en",
            "supported_languages": ["en"],
        }
        defaults.update(kwargs)
        platform = Platform(**defaults)
        db.add(platform)
        db.commit()
        db.refresh(platform)
        return platform
    return _create_platform
