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
from app.domain.mass_machine_00104 import (
    Machine_00104,
    Machine_00104_ReadDTO,
    Machine_00104_WriteDTO,
    Repository,
    Service,
)
from app.lib.responses import ObjectListResponse, ObjectResponse

if TYPE_CHECKING:
    from sqlalchemy.ext.asyncio import AsyncSession


DETAIL_ROUTE = "/{machine_id:int}"


async def provides_service(db_session: AsyncSession, company_id: int) -> Service:
    """Constructs repository and service objects for the request."""
    from app.controllers.company import provides_service

    company_service = provides_service(db_session)
    company = await company_service.get(company_id)
    return Service(Repository(session=db_session, company=company))


async def get_company(db_session: AsyncSession, company_id: int) -> Company:
    from app.controllers.company import provides_service

    company_service = provides_service(db_session)
    return await company_service.get(company_id)


class MachineController_00104(Controller):
    dto = Machine_00104_WriteDTO
    return_dto = Machine_00104_ReadDTO
    path = "/company/{company_id:int}/machines-00104"
    dependencies = {
        "service": Provide(provides_service),
    }
    tags = ["Machines-00104"]

    @get()
    async def get_machines(
        self,
        service: Service,
        search: Optional[str] = None,
    ) -> ObjectListResponse[Machine_00104]:
        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_machine(
        self, service: Service, machine_id: int
    ) -> ObjectResponse[Machine_00104]:
        content = await service.get(machine_id)
        return ObjectResponse(content=content)
