"""Test configuration and fixtures."""

import os

import pytest
from sqlalchemy import create_engine, text
from sqlalchemy.orm import Session

from packages.core.storage.models import Base


def pytest_configure():
    os.environ.setdefault("DATABASE_URL", "sqlite+pysqlite:///:memory:")


# ── Integration test fixtures (real PostgreSQL) ──────────────────────


def _get_test_db_url() -> str:
    """Return the test database URL from env or fallback."""
    return os.environ.get(
        "TEST_DATABASE_URL",
        "postgresql+psycopg://tipsharks:tipsharks@localhost:5432/tipsharks_test",
    )


@pytest.fixture(scope="session")
def db_engine():
    """Create the test PostgreSQL engine and all tables once per session.

    Tables are created at session start and dropped at session end.
    """
    test_url = _get_test_db_url()
    engine = create_engine(test_url, pool_pre_ping=True)
    Base.metadata.create_all(engine)
    yield engine

    # Drop materialized views first (created by migrations, not tracked in metadata)
    with engine.connect() as conn:
        conn.execute(text("DROP MATERIALIZED VIEW IF EXISTS latest_ratings CASCADE"))
        conn.commit()
    Base.metadata.drop_all(engine)
    engine.dispose()


@pytest.fixture
def db_session(db_engine):
    """Yield a database session rolled back after each test.

    Each test gets a clean transaction that is rolled back on teardown,
    providing isolation between tests.
    """
    connection = db_engine.connect()
    transaction = connection.begin()
    session = Session(bind=connection)

    yield session

    session.close()
    transaction.rollback()
    connection.close()
