from collections.abc import Mapping
from typing import Any, TypeVar, Optional, BinaryIO, TextIO, TYPE_CHECKING, Generator

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

from ..types import UNSET, Unset

from ..models.record_state import check_record_state
from ..models.record_state import RecordState
from ..types import UNSET, Unset
from dateutil.parser import isoparse
from typing import cast
from typing import cast, Union
from typing import Union
from uuid import UUID
import datetime

if TYPE_CHECKING:
  from ..models.record_relation_dto import RecordRelationDto
  from ..models.upsert_record_dto_tags import UpsertRecordDtoTags
  from ..models.record_authorization_dto import RecordAuthorizationDto





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



@_attrs_define
class UpsertRecordDto:
    """ 
        Attributes:
            title (str):
            mini_id (str):
            id (Union[None, UUID, Unset]):
            external_uri (Union[Unset, Any]):
            description (Union[None, Unset, str]):
            event_date (Union[None, Unset, datetime.datetime]):
            schema (Union[Unset, Any]):
            content (Union[Unset, Any]):
            relations (Union[Unset, list['RecordRelationDto']]):
            labels (Union[Unset, list[str]]):
            tags (Union[Unset, UpsertRecordDtoTags]):
            authorization (Union['RecordAuthorizationDto', Any, Unset]):
            state (Union[Any, RecordState, Unset]):
     """

    title: str
    mini_id: str
    id: Union[None, UUID, Unset] = UNSET
    external_uri: Union[Unset, Any] = UNSET
    description: Union[None, Unset, str] = UNSET
    event_date: Union[None, Unset, datetime.datetime] = UNSET
    schema: Union[Unset, Any] = UNSET
    content: Union[Unset, Any] = UNSET
    relations: Union[Unset, list['RecordRelationDto']] = UNSET
    labels: Union[Unset, list[str]] = UNSET
    tags: Union[Unset, 'UpsertRecordDtoTags'] = UNSET
    authorization: Union['RecordAuthorizationDto', Any, Unset] = UNSET
    state: Union[Any, RecordState, Unset] = UNSET
    additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)





    def to_dict(self) -> dict[str, Any]:
        from ..models.record_relation_dto import RecordRelationDto
        from ..models.upsert_record_dto_tags import UpsertRecordDtoTags
        from ..models.record_authorization_dto import RecordAuthorizationDto
        title = self.title

        mini_id = self.mini_id

        id: Union[None, Unset, str]
        if isinstance(self.id, Unset):
            id = UNSET
        elif isinstance(self.id, UUID):
            id = str(self.id)
        else:
            id = self.id

        external_uri = self.external_uri

        description: Union[None, Unset, str]
        if isinstance(self.description, Unset):
            description = UNSET
        else:
            description = self.description

        event_date: Union[None, Unset, str]
        if isinstance(self.event_date, Unset):
            event_date = UNSET
        elif isinstance(self.event_date, datetime.datetime):
            event_date = self.event_date.isoformat()
        else:
            event_date = self.event_date

        schema = self.schema

        content = self.content

        relations: Union[Unset, list[dict[str, Any]]] = UNSET
        if not isinstance(self.relations, Unset):
            relations = []
            for relations_item_data in self.relations:
                relations_item = relations_item_data.to_dict()
                relations.append(relations_item)



        labels: Union[Unset, list[str]] = UNSET
        if not isinstance(self.labels, Unset):
            labels = self.labels



        tags: Union[Unset, dict[str, Any]] = UNSET
        if not isinstance(self.tags, Unset):
            tags = self.tags.to_dict()

        authorization: Union[Any, Unset, dict[str, Any]]
        if isinstance(self.authorization, Unset):
            authorization = UNSET
        elif isinstance(self.authorization, RecordAuthorizationDto):
            authorization = self.authorization.to_dict()
        else:
            authorization = self.authorization

        state: Union[Any, Unset, str]
        if isinstance(self.state, Unset):
            state = UNSET
        elif isinstance(self.state, str):
            state = self.state
        else:
            state = self.state


        field_dict: dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update({
            "title": title,
            "miniId": mini_id,
        })
        if id is not UNSET:
            field_dict["id"] = id
        if external_uri is not UNSET:
            field_dict["externalUri"] = external_uri
        if description is not UNSET:
            field_dict["description"] = description
        if event_date is not UNSET:
            field_dict["eventDate"] = event_date
        if schema is not UNSET:
            field_dict["schema"] = schema
        if content is not UNSET:
            field_dict["content"] = content
        if relations is not UNSET:
            field_dict["relations"] = relations
        if labels is not UNSET:
            field_dict["labels"] = labels
        if tags is not UNSET:
            field_dict["tags"] = tags
        if authorization is not UNSET:
            field_dict["authorization"] = authorization
        if state is not UNSET:
            field_dict["state"] = state

        return field_dict



    @classmethod
    def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
        from ..models.record_relation_dto import RecordRelationDto
        from ..models.upsert_record_dto_tags import UpsertRecordDtoTags
        from ..models.record_authorization_dto import RecordAuthorizationDto
        d = dict(src_dict)
        title = d.pop("title")

        mini_id = d.pop("miniId")

        def _parse_id(data: object) -> Union[None, UUID, Unset]:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, str):
                    raise TypeError()
                id_type_0 = UUID(data)



                return id_type_0
            except: # noqa: E722
                pass
            return cast(Union[None, UUID, Unset], data)

        id = _parse_id(d.pop("id", UNSET))


        external_uri = d.pop("externalUri", UNSET)

        def _parse_description(data: object) -> Union[None, Unset, str]:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            return cast(Union[None, Unset, str], data)

        description = _parse_description(d.pop("description", UNSET))


        def _parse_event_date(data: object) -> Union[None, Unset, datetime.datetime]:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, str):
                    raise TypeError()
                event_date_type_0 = isoparse(data)



                return event_date_type_0
            except: # noqa: E722
                pass
            return cast(Union[None, Unset, datetime.datetime], data)

        event_date = _parse_event_date(d.pop("eventDate", UNSET))


        schema = d.pop("schema", UNSET)

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

        relations = []
        _relations = d.pop("relations", UNSET)
        for relations_item_data in (_relations or []):
            relations_item = RecordRelationDto.from_dict(relations_item_data)



            relations.append(relations_item)


        labels = cast(list[str], d.pop("labels", UNSET))


        _tags = d.pop("tags", UNSET)
        tags: Union[Unset, UpsertRecordDtoTags]
        if isinstance(_tags,  Unset):
            tags = UNSET
        else:
            tags = UpsertRecordDtoTags.from_dict(_tags)




        def _parse_authorization(data: object) -> Union['RecordAuthorizationDto', Any, Unset]:
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, dict):
                    raise TypeError()
                authorization_type_1 = RecordAuthorizationDto.from_dict(data)



                return authorization_type_1
            except: # noqa: E722
                pass
            return cast(Union['RecordAuthorizationDto', Any, Unset], data)

        authorization = _parse_authorization(d.pop("authorization", UNSET))


        def _parse_state(data: object) -> Union[Any, RecordState, Unset]:
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, str):
                    raise TypeError()
                state_type_1 = check_record_state(data)



                return state_type_1
            except: # noqa: E722
                pass
            return cast(Union[Any, RecordState, Unset], data)

        state = _parse_state(d.pop("state", UNSET))


        upsert_record_dto = cls(
            title=title,
            mini_id=mini_id,
            id=id,
            external_uri=external_uri,
            description=description,
            event_date=event_date,
            schema=schema,
            content=content,
            relations=relations,
            labels=labels,
            tags=tags,
            authorization=authorization,
            state=state,
        )


        upsert_record_dto.additional_properties = d
        return upsert_record_dto

    @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
