from uuid import UUID

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

from src.apps.sections.schemas.requests import CreateSectionRequest, UpdateSectionRequest
from src.apps.sections.schemas.responses import SectionResponse
from src.apps.sections.services.section_service import SectionService
from src.core.constants import UserRole
from src.core.dependencies import require_roles
from src.core.exceptions import NotFoundError
from src.core.schemas.response import paginated, success
from src.database.session import get_db

router = APIRouter(prefix="/sections", tags=["Sections"])


@router.get("", response_model=dict)
async def list_sections(
    skip: int = Query(0, ge=0),
    limit: int = Query(50, ge=1, le=200),
    current_user=Depends(
        require_roles(
            UserRole.ADMINISTRATOR,
            UserRole.MANAGER,
            UserRole.STAFF,
            UserRole.VIEW_ONLY,
        )
    ),
    db: AsyncSession = Depends(get_db),
):
    """List all sections for the current tenant."""
    service = SectionService(db)
    sections, total = await service.list_sections(
        tenant_id=current_user.tenant_id,
        skip=skip,
        limit=limit,
    )
    return paginated(
        items=[SectionResponse.model_validate(s).model_dump() for s in sections],
        total=total,
        page=(skip // limit) + 1 if limit else 1,
        page_size=limit,
    )


@router.post("", response_model=dict, status_code=201)
async def create_section(
    body: CreateSectionRequest,
    current_user=Depends(
        require_roles(UserRole.ADMINISTRATOR, UserRole.MANAGER)
    ),
    db: AsyncSession = Depends(get_db),
):
    """Create a new section."""
    service = SectionService(db)
    section = await service.create(
        tenant_id=current_user.tenant_id,
        data=body.model_dump(),
    )
    return success(
        data=SectionResponse.model_validate(section).model_dump(),
        message="Section created",
    )


@router.get("/{section_id}", response_model=dict)
async def get_section(
    section_id: UUID,
    current_user=Depends(
        require_roles(
            UserRole.ADMINISTRATOR,
            UserRole.MANAGER,
            UserRole.STAFF,
            UserRole.VIEW_ONLY,
        )
    ),
    db: AsyncSession = Depends(get_db),
):
    """Get a single section by ID."""
    service = SectionService(db)
    section = await service.get_by_id(section_id, current_user.tenant_id)
    if not section:
        raise NotFoundError("Section not found")
    return success(data=SectionResponse.model_validate(section).model_dump())


@router.patch("/{section_id}", response_model=dict)
async def update_section(
    section_id: UUID,
    body: UpdateSectionRequest,
    current_user=Depends(
        require_roles(UserRole.ADMINISTRATOR, UserRole.MANAGER)
    ),
    db: AsyncSession = Depends(get_db),
):
    """Update a section."""
    service = SectionService(db)
    section = await service.update(
        section_id=section_id,
        tenant_id=current_user.tenant_id,
        data=body.model_dump(exclude_none=True),
    )
    return success(
        data=SectionResponse.model_validate(section).model_dump(),
        message="Section updated",
    )


@router.delete("/{section_id}", status_code=204)
async def delete_section(
    section_id: UUID,
    current_user=Depends(require_roles(UserRole.ADMINISTRATOR)),
    db: AsyncSession = Depends(get_db),
):
    """Delete a section (Administrator only)."""
    service = SectionService(db)
    await service.delete(section_id, current_user.tenant_id)
