from collections.abc import AsyncGenerator
from typing import Annotated

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession

from src.db.database import get_db
from src.schemas import (
    PatternDetailResponse,
    PatternListResponse,
    PatternResponse,
    PatternTutorialResponse,
)
from src.services import PatternService

router = APIRouter()


async def get_pattern_service(
    db: Annotated[AsyncSession, Depends(get_db)],
) -> AsyncGenerator[PatternService, None]:
    """Dependency for PatternService."""
    yield PatternService(db)


@router.get("", response_model=PatternListResponse)
async def list_patterns(
    service: Annotated[PatternService, Depends(get_pattern_service)],
) -> PatternListResponse:
    """List all patterns with question counts."""
    patterns_with_counts = await service.get_patterns()

    items = [
        PatternResponse(
            id=pattern.id,
            name=pattern.name,
            slug=pattern.slug,
            description=pattern.description,
            when_to_use=pattern.when_to_use,
            question_count=count,
        )
        for pattern, count in patterns_with_counts
    ]

    return PatternListResponse(items=items)


@router.get("/{slug}", response_model=PatternDetailResponse)
async def get_pattern(
    slug: str,
    service: Annotated[PatternService, Depends(get_pattern_service)],
) -> PatternDetailResponse:
    """Get a single pattern by slug with details."""
    result = await service.get_pattern_by_slug(slug)

    if not result:
        raise HTTPException(status_code=404, detail="Pattern not found")

    pattern, count = result
    return PatternDetailResponse(
        id=pattern.id,
        name=pattern.name,
        slug=pattern.slug,
        description=pattern.description,
        when_to_use=pattern.when_to_use,
        question_count=count,
    )


@router.get("/{slug}/tutorial", response_model=PatternTutorialResponse)
async def get_pattern_tutorial(
    slug: str,
    service: Annotated[PatternService, Depends(get_pattern_service)],
) -> PatternTutorialResponse:
    """Get full pattern tutorial with educational content and learning progression."""
    tutorial = await service.get_pattern_tutorial(slug)

    if not tutorial:
        raise HTTPException(status_code=404, detail="Pattern not found")

    return tutorial
