import typing
from .client import ProjectsClient, AsyncProjectsClient
from label_studio_sdk._extensions.pager_ext import SyncPagerExt, AsyncPagerExt, T
from label_studio_sdk.types.lse_project_response import LseProjectResponse
from label_studio_sdk.label_interface import LabelInterface
from .exports.client_ext import ExportsClientExt, AsyncExportsClientExt
from ..core.unchecked_base_model import construct_type
from ..core import RequestOptions


class ProjectExt(LseProjectResponse):

    def get_label_interface(self):
        return LabelInterface(self.label_config)


class ProjectsClientExt(ProjectsClient):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._exports_ext: typing.Optional[ExportsClientExt] = None

    @property
    def exports(self) -> ExportsClientExt:  # type: ignore[override]
        # Newer Fern-generated clients may expose `exports` as a read-only @property.
        # Avoid assigning to it; instead override it to return our extension client.
        if self._exports_ext is None:
            self._exports_ext = ExportsClientExt(client_wrapper=self._client_wrapper)
        return self._exports_ext

    def list(self, **kwargs) -> SyncPagerExt[T]:
        return SyncPagerExt.from_sync_pager(super().list(**kwargs))

    list.__doc__ = ProjectsClient.list.__doc__

    def get(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> ProjectExt:
        return typing.cast(
            ProjectExt,
            construct_type(
                type_=ProjectExt,  # type: ignore
                object_=super().get(id, request_options=request_options).model_dump(),
            ),
        )

    get.__doc__ = ProjectsClient.get.__doc__


class AsyncProjectsClientExt(AsyncProjectsClient):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._exports_ext: typing.Optional[AsyncExportsClientExt] = None

    @property
    def exports(self) -> AsyncExportsClientExt:  # type: ignore[override]
        if self._exports_ext is None:
            self._exports_ext = AsyncExportsClientExt(client_wrapper=self._client_wrapper)
        return self._exports_ext

    async def get(self, id: int, *, request_options: typing.Optional[RequestOptions] = None) -> ProjectExt:
        return typing.cast(
            ProjectExt,
            construct_type(
                type_=ProjectExt,  # type: ignore
                object_=(await super().get(id, request_options=request_options)).model_dump(),
            ),
        )

    get.__doc__ = AsyncProjectsClient.get.__doc__

    async def list(self, **kwargs):
        return await AsyncPagerExt.from_async_pager(await super().list(**kwargs))

    list.__doc__ = AsyncProjectsClient.list.__doc__
