from typing import IO, Any, cast
from uuid import UUID

from pydantic import BaseModel

from ..models import (
    BrokerCreating,
    BrokerCredentials,
    BrokerDeleting,
    BrokerDetail,
    BrokerReading,
    BrokerSummary,
    BrokerUpdating,
)
from .base import ModelClient


class Broker(
    ModelClient[
        BrokerCreating,
        BrokerReading,
        BrokerUpdating,
        BrokerDeleting,
        BrokerSummary,
        BrokerDetail,
    ]
):
    Creating = BrokerCreating
    Reading = BrokerReading
    Updating = BrokerUpdating
    Deleting = BrokerDeleting
    Summary = BrokerSummary
    Detail = BrokerDetail

    class Token(BaseModel):
        token: str

    def create(self, data: BrokerCreating | None = None, **kwargs: Any) -> BrokerDetail:
        data = data if data else BrokerCreating(**kwargs)
        res = self.request(
            "POST",
            endpoint="create",
            data=data,
            return_model=BrokerDetail,
        )
        assert isinstance(res, BrokerDetail)
        return res

    async def create_async(
        self, data: BrokerCreating | None = None, **kwargs: Any
    ) -> BrokerDetail:
        data = data if data else BrokerCreating(**kwargs)
        res = await self.request_async(
            "POST",
            endpoint="create",
            data=data,
            return_model=BrokerDetail,
        )
        assert isinstance(res, BrokerDetail)
        return res

    def credentials(self, broker_id: UUID) -> BrokerCredentials:
        res = self.request(
            "POST",
            endpoint="credentials/read",
            data=BrokerReading(id=broker_id),
            return_model=BrokerCredentials,
        )
        assert isinstance(res, BrokerCredentials)
        return res

    def download_gcloud_files(self) -> IO[bytes]:
        res = self.request("POST", endpoint="files/gcloud/read", stream=True)
        return cast(IO[bytes], res)
