"""
Test configuration and fixtures for INDELIS API.
"""
import asyncio
import sys
import pytest

# Windows: psycopg3 requires SelectorEventLoop, not ProactorEventLoop
if sys.platform == "win32":
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
import pytest_asyncio
from httpx import AsyncClient, ASGITransport
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession

from src.main import app
from src.database.base import Base
from src.database.session import get_db
from src.core.config import settings

# Use a separate test database
TEST_DATABASE_URL = settings.DATABASE_URL.replace("/indelis", "/indelis_test")
if not TEST_DATABASE_URL.startswith("postgresql+psycopg://"):
    TEST_DATABASE_URL = "postgresql+psycopg://" + TEST_DATABASE_URL.split("://", 1)[-1]

test_engine = create_async_engine(TEST_DATABASE_URL, echo=False)
TestSessionLocal = async_sessionmaker(
    test_engine, class_=AsyncSession, expire_on_commit=False
)


@pytest.fixture(scope="session")
def event_loop():
    loop = asyncio.new_event_loop()
    yield loop
    loop.close()


@pytest_asyncio.fixture(scope="function")
async def db_session():
    async with TestSessionLocal() as session:
        yield session
        await session.rollback()


@pytest_asyncio.fixture(scope="function")
async def client(db_session: AsyncSession):
    async def override_get_db():
        yield db_session

    app.dependency_overrides[get_db] = override_get_db
    async with AsyncClient(
        transport=ASGITransport(app=app), base_url="http://test"
    ) as ac:
        yield ac
    app.dependency_overrides.clear()


@pytest_asyncio.fixture
async def test_account(db_session: AsyncSession):
    """Create a test tenant account."""
    from src.apps.tenants.models.account import Account
    account = Account(
        organization_name="Test Cemetery",
        subdomain="testcemetery",
        contact_email="admin@testcemetery.com",
        plan="starter",
        status="active",
    )
    db_session.add(account)
    await db_session.flush()
    return account


@pytest_asyncio.fixture
async def test_admin_user(db_session: AsyncSession, test_account):
    """Create a test administrator user."""
    from src.apps.auth.models.user import User
    from src.core.security import hash_password
    user = User(
        tenant_id=test_account.id,
        email="admin@testcemetery.com",
        password_hash=hash_password("TestPassword123"),
        first_name="Admin",
        last_name="User",
        role="administrator",
        status="active",
    )
    db_session.add(user)
    await db_session.flush()
    return user


@pytest_asyncio.fixture
async def admin_token(test_admin_user, test_account):
    """Get JWT access token for admin user."""
    from src.core.security import create_access_token, build_token_payload
    payload = build_token_payload(test_admin_user, test_account)
    return create_access_token(payload)


@pytest_asyncio.fixture
async def auth_headers(admin_token: str):
    return {"Authorization": f"Bearer {admin_token}"}
