from typing import TYPE_CHECKING, Optional

from litestar import Controller, get
from litestar.contrib.repository.filters import LimitOffset, SearchFilter
from litestar.di import Provide
from sqlalchemy.ext.asyncio import AsyncSession

from app.domain.company import (
    Company,
    CompanyReadDTO,
    CompanyWriteDTO,
    Repository,
    Service,
)
from app.lib.responses import ObjectListResponse, ObjectResponse

if TYPE_CHECKING:
    from sqlalchemy.ext.asyncio import AsyncSession


DETAIL_ROUTE = "/{company_id:int}"


def provides_service(db_session: AsyncSession) -> Service:
    """Constructs repository and service objects for the request."""
    return Service(Repository(session=db_session))


class CompanyController(Controller):
    dto = CompanyWriteDTO
    return_dto = CompanyReadDTO
    path = "/companies"
    dependencies = {
        "service": Provide(provides_service, sync_to_thread=False),
    }
    tags = ["Companies"]

    @get()
    async def get_companies(
        self, service: Service, search: Optional[str] = None
    ) -> ObjectListResponse[Company]:
        filters = [
            LimitOffset(limit=20, offset=0),
        ]

        if search is not None:
            filters.append(
                SearchFilter(
                    field_name="caption",
                    value=search,
                ),
            )

        content = await service.list(*filters)
        return ObjectListResponse(content=content)

    @get(DETAIL_ROUTE)
    async def get_company(
        self, service: Service, company_id: int
    ) -> ObjectResponse[Company]:
        content = await service.get(company_id)
        return ObjectResponse(content=content)
