"""Quickstart example as a test - proves the 10-line setup works."""

from __future__ import annotations

from collections.abc import AsyncGenerator

from fastapi import FastAPI
from httpx import ASGITransport, AsyncClient
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.pool import StaticPool
from sqlmodel import Field, SQLModel
from sqlmodel.ext.asyncio.session import AsyncSession

from auen import CrudRouterBuilder, derive_schemas


async def test_quickstart() -> None:
    """The minimal quickstart: model + engine + fluent builder."""

    class Item(SQLModel, table=True):
        id: int | None = Field(default=None, primary_key=True)
        title: str
        done: bool = False

    engine = create_async_engine(
        "sqlite+aiosqlite://",
        echo=False,
        connect_args={"check_same_thread": False},
        poolclass=StaticPool,
    )
    async with engine.begin() as conn:
        await conn.run_sync(SQLModel.metadata.create_all)

    async def get_session() -> AsyncGenerator[AsyncSession, None]:
        async with AsyncSession(engine) as session:
            yield session

    app = FastAPI()
    app.include_router(
        CrudRouterBuilder.for_model(Item, get_session)
        .with_schemas(derive_schemas(Item))
        .build()
    )

    transport = ASGITransport(app=app)
    async with AsyncClient(transport=transport, base_url="http://test") as client:
        # Create
        resp = await client.post("/items/", json={"title": "Buy milk", "done": False})
        assert resp.status_code == 201
        item = resp.json()
        assert item["title"] == "Buy milk"
        item_id = item["id"]

        # Read
        resp = await client.get(f"/items/{item_id}")
        assert resp.status_code == 200
        assert resp.json()["title"] == "Buy milk"

        # List
        resp = await client.get("/items/")
        assert resp.status_code == 200
        assert len(resp.json()) == 1

        # Update
        resp = await client.patch(f"/items/{item_id}", json={"done": True})
        assert resp.status_code == 200
        assert resp.json()["done"] is True
        assert resp.json()["title"] == "Buy milk"  # unchanged

        # Delete
        resp = await client.delete(f"/items/{item_id}")
        assert resp.status_code == 200

        # Verify gone
        resp = await client.get(f"/items/{item_id}")
        assert resp.status_code == 404

    await engine.dispose()
