from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
from sqlalchemy.orm import sessionmaker
from sqlalchemy import text, select
from app.models import Base, AppSettings
from app.config import get_settings


settings = get_settings()

# Convert sqlite:/// to sqlite+aiosqlite:/// for async support
db_url = settings.database_url.replace("sqlite://", "sqlite+aiosqlite://")

# Create async engine
engine = create_async_engine(db_url, echo=True)

# Create async session factory
async_session = async_sessionmaker(
    engine, class_=AsyncSession, expire_on_commit=False
)


async def init_db():
    """Initialize database tables."""
    async with engine.begin() as conn:
        # Check if migration is needed (users table doesn't exist)
        result = await conn.execute(text(
            "SELECT name FROM sqlite_master WHERE type='table' AND name='users'"
        ))
        needs_migration = result.fetchone() is None

        # Check if we have old schema (listening_sessions exists but no users table)
        result = await conn.execute(text(
            "SELECT name FROM sqlite_master WHERE type='table' AND name='listening_sessions'"
        ))
        has_old_schema = result.fetchone() is not None

        if needs_migration and has_old_schema:
            # Need to run migration
            print("Existing database detected without users table - migration required")
            print("Please run: python -m app.migrations.add_multi_user")
            print("Or delete absrecommend.db to start fresh")
            raise RuntimeError("Database migration required")

        # Create all tables (will skip existing ones)
        await conn.run_sync(Base.metadata.create_all)

    # Initialize default settings
    async with async_session() as session:
        # Check if settings already exist
        result = await session.execute(
            select(AppSettings).where(AppSettings.key == "allow_registration")
        )
        if not result.scalar_one_or_none():
            # Create default settings
            default_settings = [
                AppSettings(key="allow_registration", value="true"),
            ]
            session.add_all(default_settings)
            await session.commit()


async def get_db():
    """Dependency for getting database session."""
    async with async_session() as session:
        try:
            yield session
        finally:
            await session.close()
