from __future__ import annotations

from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, Literal, TypeVar, cast

from attrs import define as _attrs_define
from attrs import field as _attrs_field

from ..types import UNSET, Unset

if TYPE_CHECKING:
    from ..models.audio_url import AudioUrl
    from ..models.binary_content import BinaryContent
    from ..models.cache_point import CachePoint
    from ..models.document_url import DocumentUrl
    from ..models.image_url import ImageUrl
    from ..models.retry_prompt_part import RetryPromptPart
    from ..models.tool_return_part import ToolReturnPart
    from ..models.video_url import VideoUrl


T = TypeVar("T", bound="FunctionToolResultEvent")


@_attrs_define
class FunctionToolResultEvent:
    """
    Attributes:
        result (RetryPromptPart | ToolReturnPart):
        content (list[AudioUrl | BinaryContent | CachePoint | DocumentUrl | ImageUrl | str | VideoUrl] | None | str |
            Unset):
        event_kind (Literal['function_tool_result'] | Unset):  Default: 'function_tool_result'.
    """

    result: RetryPromptPart | ToolReturnPart
    content: (
        list[AudioUrl | BinaryContent | CachePoint | DocumentUrl | ImageUrl | str | VideoUrl] | None | str | Unset
    ) = UNSET
    event_kind: Literal["function_tool_result"] | Unset = "function_tool_result"
    additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)

    def to_dict(self) -> dict[str, Any]:
        from ..models.audio_url import AudioUrl
        from ..models.binary_content import BinaryContent
        from ..models.cache_point import CachePoint
        from ..models.document_url import DocumentUrl
        from ..models.image_url import ImageUrl
        from ..models.tool_return_part import ToolReturnPart
        from ..models.video_url import VideoUrl

        result: dict[str, Any]
        if isinstance(self.result, ToolReturnPart):
            result = self.result.to_dict()
        else:
            result = self.result.to_dict()

        content: list[dict[str, Any] | str] | None | str | Unset
        if isinstance(self.content, Unset):
            content = UNSET
        elif isinstance(self.content, list):
            content = []
            for content_type_1_item_data in self.content:
                content_type_1_item: dict[str, Any] | str
                if isinstance(content_type_1_item_data, ImageUrl):
                    content_type_1_item = content_type_1_item_data.to_dict()
                elif isinstance(content_type_1_item_data, AudioUrl):
                    content_type_1_item = content_type_1_item_data.to_dict()
                elif isinstance(content_type_1_item_data, DocumentUrl):
                    content_type_1_item = content_type_1_item_data.to_dict()
                elif isinstance(content_type_1_item_data, VideoUrl):
                    content_type_1_item = content_type_1_item_data.to_dict()
                elif isinstance(content_type_1_item_data, BinaryContent):
                    content_type_1_item = content_type_1_item_data.to_dict()
                elif isinstance(content_type_1_item_data, CachePoint):
                    content_type_1_item = content_type_1_item_data.to_dict()
                else:
                    content_type_1_item = content_type_1_item_data
                content.append(content_type_1_item)

        else:
            content = self.content

        event_kind = self.event_kind

        field_dict: dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update(
            {
                "result": result,
            }
        )
        if content is not UNSET:
            field_dict["content"] = content
        if event_kind is not UNSET:
            field_dict["event_kind"] = event_kind

        return field_dict

    @classmethod
    def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
        from ..models.audio_url import AudioUrl
        from ..models.binary_content import BinaryContent
        from ..models.cache_point import CachePoint
        from ..models.document_url import DocumentUrl
        from ..models.image_url import ImageUrl
        from ..models.retry_prompt_part import RetryPromptPart
        from ..models.tool_return_part import ToolReturnPart
        from ..models.video_url import VideoUrl

        d = dict(src_dict)

        def _parse_result(data: object) -> RetryPromptPart | ToolReturnPart:
            try:
                if not isinstance(data, dict):
                    raise TypeError()
                result_type_0 = ToolReturnPart.from_dict(data)

                return result_type_0
            except (TypeError, ValueError, AttributeError, KeyError):
                pass
            if not isinstance(data, dict):
                raise TypeError()
            result_type_1 = RetryPromptPart.from_dict(data)

            return result_type_1

        result = _parse_result(d.pop("result"))

        def _parse_content(
            data: object,
        ) -> list[AudioUrl | BinaryContent | CachePoint | DocumentUrl | ImageUrl | str | VideoUrl] | None | str | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, list):
                    raise TypeError()
                content_type_1 = []
                _content_type_1 = data
                for content_type_1_item_data in _content_type_1:

                    def _parse_content_type_1_item(
                        data: object,
                    ) -> AudioUrl | BinaryContent | CachePoint | DocumentUrl | ImageUrl | str | VideoUrl:
                        try:
                            if not isinstance(data, dict):
                                raise TypeError()
                            content_type_1_item_type_1_type_0 = ImageUrl.from_dict(data)

                            return content_type_1_item_type_1_type_0
                        except (TypeError, ValueError, AttributeError, KeyError):
                            pass
                        try:
                            if not isinstance(data, dict):
                                raise TypeError()
                            content_type_1_item_type_1_type_1 = AudioUrl.from_dict(data)

                            return content_type_1_item_type_1_type_1
                        except (TypeError, ValueError, AttributeError, KeyError):
                            pass
                        try:
                            if not isinstance(data, dict):
                                raise TypeError()
                            content_type_1_item_type_1_type_2 = DocumentUrl.from_dict(data)

                            return content_type_1_item_type_1_type_2
                        except (TypeError, ValueError, AttributeError, KeyError):
                            pass
                        try:
                            if not isinstance(data, dict):
                                raise TypeError()
                            content_type_1_item_type_1_type_3 = VideoUrl.from_dict(data)

                            return content_type_1_item_type_1_type_3
                        except (TypeError, ValueError, AttributeError, KeyError):
                            pass
                        try:
                            if not isinstance(data, dict):
                                raise TypeError()
                            content_type_1_item_type_1_type_4 = BinaryContent.from_dict(data)

                            return content_type_1_item_type_1_type_4
                        except (TypeError, ValueError, AttributeError, KeyError):
                            pass
                        try:
                            if not isinstance(data, dict):
                                raise TypeError()
                            content_type_1_item_type_2 = CachePoint.from_dict(data)

                            return content_type_1_item_type_2
                        except (TypeError, ValueError, AttributeError, KeyError):
                            pass
                        return cast(
                            AudioUrl | BinaryContent | CachePoint | DocumentUrl | ImageUrl | str | VideoUrl, data
                        )

                    content_type_1_item = _parse_content_type_1_item(content_type_1_item_data)

                    content_type_1.append(content_type_1_item)

                return content_type_1
            except (TypeError, ValueError, AttributeError, KeyError):
                pass
            return cast(
                list[AudioUrl | BinaryContent | CachePoint | DocumentUrl | ImageUrl | str | VideoUrl]
                | None
                | str
                | Unset,
                data,
            )

        content = _parse_content(d.pop("content", UNSET))

        event_kind = cast(Literal["function_tool_result"] | Unset, d.pop("event_kind", UNSET))
        if event_kind != "function_tool_result" and not isinstance(event_kind, Unset):
            raise ValueError(f"event_kind must match const 'function_tool_result', got '{event_kind}'")

        function_tool_result_event = cls(
            result=result,
            content=content,
            event_kind=event_kind,
        )

        function_tool_result_event.additional_properties = d
        return function_tool_result_event

    @property
    def additional_keys(self) -> list[str]:
        return list(self.additional_properties.keys())

    def __getitem__(self, key: str) -> Any:
        return self.additional_properties[key]

    def __setitem__(self, key: str, value: Any) -> None:
        self.additional_properties[key] = value

    def __delitem__(self, key: str) -> None:
        del self.additional_properties[key]

    def __contains__(self, key: str) -> bool:
        return key in self.additional_properties
