from collections.abc import AsyncIterator
from typing import Final, Optional

from typing_extensions import Unpack

from ncae_sdk._async.endpoint import AsyncEndpoint
from ncae_sdk._resource import ResourceId
from ncae_sdk._util import map_async
from ncae_sdk.resources._schema import (
    ServiceManagementPhase,
    ServiceManagementPhaseCreate,
    ServiceManagementPhaseCreateModel,
    ServiceManagementPhaseFilter,
    ServiceManagementPhaseFilterModel,
    ServiceManagementPhaseUpdate,
    ServiceManagementPhaseUpdateModel,
)


class AsyncServiceManagementPhaseEndpoint(AsyncEndpoint):
    BASE_PATH: Final[str] = "automation/v1/phase/service-management-phase"

    async def list(self, **filters: Unpack[ServiceManagementPhaseFilter]) -> AsyncIterator[ServiceManagementPhase]:
        results = self._list(self.BASE_PATH, ServiceManagementPhaseFilterModel, filters)
        return map_async(ServiceManagementPhase.parse_api, results)

    async def find(self, **filters: Unpack[ServiceManagementPhaseFilter]) -> Optional[ServiceManagementPhase]:
        result = await self._get_by_filters(self.BASE_PATH, ServiceManagementPhaseFilterModel, filters)
        return ServiceManagementPhase.parse_api(result) if result else None

    async def get(self, rid: ResourceId) -> Optional[ServiceManagementPhase]:
        result = await self._get_by_id(self.BASE_PATH, rid)
        return ServiceManagementPhase.parse_api(result) if result else None

    async def create(self, **payload: Unpack[ServiceManagementPhaseCreate]) -> ServiceManagementPhase:
        result = await self._create(self.BASE_PATH, ServiceManagementPhaseCreateModel, payload)
        return ServiceManagementPhase.parse_api(result)

    async def update(
        self, rid: ResourceId, /, **payload: Unpack[ServiceManagementPhaseUpdate]
    ) -> ServiceManagementPhase:
        result = await self._update(self.BASE_PATH, rid, ServiceManagementPhaseUpdateModel, payload)
        return ServiceManagementPhase.parse_api(result)

    async def delete(self, rid: ResourceId) -> bool:
        return await self._delete(self.BASE_PATH, rid)
