from __future__ import annotations

import logging

from sqlalchemy import inspect
from sqlalchemy import text
from sqlalchemy.engine import Connection
from sqlalchemy.ext.asyncio import AsyncEngine
from sqlmodel import SQLModel
from sqlmodel import select
from sqlmodel.ext.asyncio.session import AsyncSession

from ..models import Job
from ..models import JobStatus
from .runtime import get_engine

logger = logging.getLogger(__name__)


async def get_next_queued_job(*, session: AsyncSession) -> Job | None:
    """Get the next queued job, if any."""
    result = await session.exec(
        select(Job)
        .where(Job.status == JobStatus.QUEUED)
        .order_by(Job.created_at)  # pyright: ignore[reportArgumentType]
        .limit(1)
    )  # fmt: skip
    return result.first()


async def create_all(*, engine: AsyncEngine | None = None) -> None:
    """Create all tables on the selected engine."""
    # Import models so SQLModel metadata is fully registered before bootstrap.
    from transcription import models as _models  # noqa: F401

    active_engine = engine or get_engine()
    async with active_engine.begin() as connection:
        await connection.run_sync(SQLModel.metadata.create_all)
        await connection.run_sync(_ensure_sqlite_compat_columns)
    logger.debug("Database schema bootstrap complete for database_url=%s", active_engine.url)


def _ensure_sqlite_compat_columns(connection: Connection) -> None:
    """Apply lightweight dev/test SQLite compatibility column patches.

    This keeps local bootstrap resilient when models evolve but no full
    migration tooling is in place yet.
    """
    if connection.engine.url.get_backend_name() != "sqlite":
        return

    inspector = inspect(connection)
    table_names = set(inspector.get_table_names())
    if "job" not in table_names:
        return

    columns = {column["name"] for column in inspector.get_columns("job")}
    if "retry_count" not in columns:
        connection.execute(text("ALTER TABLE job ADD COLUMN retry_count INTEGER NOT NULL DEFAULT 0"))
        logger.warning("Applied SQLite compatibility schema patch table=job column=retry_count default=0")
