# src/chitai/controllers/library.py

# Standard library
from typing import Annotated

# Third-party libraries
from litestar import Controller, post, get, patch, delete
from litestar.params import Dependency
from litestar.exceptions import HTTPException
from advanced_alchemy.extensions.litestar.providers import create_service_dependencies
from advanced_alchemy.service.pagination import OffsetPagination
from advanced_alchemy.service import FilterTypeT

# Local imports
from chitai.database import models as m
from chitai.services import LibraryService
from chitai.schemas.library import LibraryCreate, LibraryRead
from chitai.services.utils import DirectoryDoesNotExist


class LibraryController(Controller):
    """Controller for managing library operations."""

    path = "/libraries"
    dependencies = create_service_dependencies(
        LibraryService,
        key="library_service",
        filters={"id_filter": int, "pagination_type": "limit_offset"},
    )

    @post()
    async def create_library(
        self, library_service: LibraryService, data: LibraryCreate
    ) -> LibraryRead:
        """
        Create a new library.

        Creates a new library entry in the system using the provided data. If the library is read-only
        the target root path must exist.

        Request Body:
            data: Data used to create the new library.

        Injected Dependencies:
            library_service: The service used to manage library creation and persistence.

        Returns:
            The created library.
        """
        try:
            library = await library_service.create(data)
            return library_service.to_schema(library, schema_type=LibraryRead)
        except DirectoryDoesNotExist as exc:
            raise HTTPException(status_code=400, detail=str(exc))

    @get()
    async def list_libraries(
        self,
        library_service: LibraryService,
        filters: Annotated[list[FilterTypeT], Dependency(skip_validation=True)],
    ) -> OffsetPagination[LibraryRead]:
        """
        List all libraries.

        Retrieves a paginated list of all libraries, optionally filtered by parameters.

        Query Parameters:
            filters: Filtering by ID and pagination parameters.

        Injected Dependencies:
            library_service: The service used to query and return library data.
        """
        results, total = await library_service.list_and_count(*filters, load=[m.Library.books])
        return library_service.to_schema(
            results, total, filters, schema_type=LibraryRead
        )
