from __future__ import annotations

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

from attrs import define as _attrs_define
from attrs import field as _attrs_field
from dateutil.parser import isoparse

from ..types import UNSET, Unset

if TYPE_CHECKING:
    from ..models.action_graph_doc_graph_type_0 import ActionGraphDocGraphType0
    from ..models.action_graph_doc_input_type_0 import ActionGraphDocInputType0
    from ..models.action_graph_doc_node_details import ActionGraphDocNodeDetails
    from ..models.action_graph_doc_nodes_type_0 import ActionGraphDocNodesType0
    from ..models.action_graph_doc_output_type_0 import ActionGraphDocOutputType0


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


@_attrs_define
class ActionGraphDoc:
    """
    Attributes:
        name (str):
        user_id (str):
        field_id (str):
        updated_at (datetime.datetime | Unset):
        version (float | Unset):  Default: 0.0.
        description (str | Unset):  Default: ''.
        user_manual (str | Unset):  Default: ''.
        nodes (ActionGraphDocNodesType0 | None | Unset): map of node_id to action_id
        node_details (ActionGraphDocNodeDetails | Unset): map of node_id to Node
        graph (ActionGraphDocGraphType0 | None | Unset): map of node_id to list of node_ids
        start_node_id (None | str | Unset):
        input_ (ActionGraphDocInputType0 | None | Unset):
        output (ActionGraphDocOutputType0 | None | Unset):
        is_saved (bool | Unset):  Default: False.
        is_published (bool | Unset):  Default: False.
        shared_with (list[str] | Unset):
        time_saved_per_file (float | None | Unset): Time saved per file in hours for dashboard workflow calculations
            Default: 0.1.
        dollar_cost_per_hour (float | None | Unset): Dollar cost per hour for dashboard workflow calculations Default:
            50.0.
        created_at (datetime.datetime | Unset):  Default: isoparse('2026-03-12T15:03:59.848584').
    """

    name: str
    user_id: str
    field_id: str
    updated_at: datetime.datetime | Unset = UNSET
    version: float | Unset = 0.0
    description: str | Unset = ""
    user_manual: str | Unset = ""
    nodes: ActionGraphDocNodesType0 | None | Unset = UNSET
    node_details: ActionGraphDocNodeDetails | Unset = UNSET
    graph: ActionGraphDocGraphType0 | None | Unset = UNSET
    start_node_id: None | str | Unset = UNSET
    input_: ActionGraphDocInputType0 | None | Unset = UNSET
    output: ActionGraphDocOutputType0 | None | Unset = UNSET
    is_saved: bool | Unset = False
    is_published: bool | Unset = False
    shared_with: list[str] | Unset = UNSET
    time_saved_per_file: float | None | Unset = 0.1
    dollar_cost_per_hour: float | None | Unset = 50.0
    created_at: datetime.datetime | Unset = isoparse("2026-03-12T15:03:59.848584")
    additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)

    def to_dict(self) -> dict[str, Any]:
        from ..models.action_graph_doc_graph_type_0 import ActionGraphDocGraphType0
        from ..models.action_graph_doc_input_type_0 import ActionGraphDocInputType0
        from ..models.action_graph_doc_nodes_type_0 import ActionGraphDocNodesType0
        from ..models.action_graph_doc_output_type_0 import ActionGraphDocOutputType0

        name = self.name

        user_id = self.user_id

        field_id = self.field_id

        updated_at: str | Unset = UNSET
        if not isinstance(self.updated_at, Unset):
            updated_at = self.updated_at.isoformat()

        version = self.version

        description = self.description

        user_manual = self.user_manual

        nodes: dict[str, Any] | None | Unset
        if isinstance(self.nodes, Unset):
            nodes = UNSET
        elif isinstance(self.nodes, ActionGraphDocNodesType0):
            nodes = self.nodes.to_dict()
        else:
            nodes = self.nodes

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

        graph: dict[str, Any] | None | Unset
        if isinstance(self.graph, Unset):
            graph = UNSET
        elif isinstance(self.graph, ActionGraphDocGraphType0):
            graph = self.graph.to_dict()
        else:
            graph = self.graph

        start_node_id: None | str | Unset
        if isinstance(self.start_node_id, Unset):
            start_node_id = UNSET
        else:
            start_node_id = self.start_node_id

        input_: dict[str, Any] | None | Unset
        if isinstance(self.input_, Unset):
            input_ = UNSET
        elif isinstance(self.input_, ActionGraphDocInputType0):
            input_ = self.input_.to_dict()
        else:
            input_ = self.input_

        output: dict[str, Any] | None | Unset
        if isinstance(self.output, Unset):
            output = UNSET
        elif isinstance(self.output, ActionGraphDocOutputType0):
            output = self.output.to_dict()
        else:
            output = self.output

        is_saved = self.is_saved

        is_published = self.is_published

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

        time_saved_per_file: float | None | Unset
        if isinstance(self.time_saved_per_file, Unset):
            time_saved_per_file = UNSET
        else:
            time_saved_per_file = self.time_saved_per_file

        dollar_cost_per_hour: float | None | Unset
        if isinstance(self.dollar_cost_per_hour, Unset):
            dollar_cost_per_hour = UNSET
        else:
            dollar_cost_per_hour = self.dollar_cost_per_hour

        created_at: str | Unset = UNSET
        if not isinstance(self.created_at, Unset):
            created_at = self.created_at.isoformat()

        field_dict: dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update(
            {
                "name": name,
                "user_id": user_id,
                "_id": field_id,
            }
        )
        if updated_at is not UNSET:
            field_dict["updated_at"] = updated_at
        if version is not UNSET:
            field_dict["version"] = version
        if description is not UNSET:
            field_dict["description"] = description
        if user_manual is not UNSET:
            field_dict["user_manual"] = user_manual
        if nodes is not UNSET:
            field_dict["nodes"] = nodes
        if node_details is not UNSET:
            field_dict["node_details"] = node_details
        if graph is not UNSET:
            field_dict["graph"] = graph
        if start_node_id is not UNSET:
            field_dict["start_node_id"] = start_node_id
        if input_ is not UNSET:
            field_dict["input"] = input_
        if output is not UNSET:
            field_dict["output"] = output
        if is_saved is not UNSET:
            field_dict["is_saved"] = is_saved
        if is_published is not UNSET:
            field_dict["is_published"] = is_published
        if shared_with is not UNSET:
            field_dict["shared_with"] = shared_with
        if time_saved_per_file is not UNSET:
            field_dict["time_saved_per_file"] = time_saved_per_file
        if dollar_cost_per_hour is not UNSET:
            field_dict["dollar_cost_per_hour"] = dollar_cost_per_hour
        if created_at is not UNSET:
            field_dict["created_at"] = created_at

        return field_dict

    @classmethod
    def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
        from ..models.action_graph_doc_graph_type_0 import ActionGraphDocGraphType0
        from ..models.action_graph_doc_input_type_0 import ActionGraphDocInputType0
        from ..models.action_graph_doc_node_details import ActionGraphDocNodeDetails
        from ..models.action_graph_doc_nodes_type_0 import ActionGraphDocNodesType0
        from ..models.action_graph_doc_output_type_0 import ActionGraphDocOutputType0

        d = dict(src_dict)
        name = d.pop("name")

        user_id = d.pop("user_id")

        field_id = d.pop("_id")

        _updated_at = d.pop("updated_at", UNSET)
        updated_at: datetime.datetime | Unset
        if isinstance(_updated_at, Unset):
            updated_at = UNSET
        else:
            updated_at = isoparse(_updated_at)

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

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

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

        def _parse_nodes(data: object) -> ActionGraphDocNodesType0 | None | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, dict):
                    raise TypeError()
                nodes_type_0 = ActionGraphDocNodesType0.from_dict(data)

                return nodes_type_0
            except (TypeError, ValueError, AttributeError, KeyError):
                pass
            return cast(ActionGraphDocNodesType0 | None | Unset, data)

        nodes = _parse_nodes(d.pop("nodes", UNSET))

        _node_details = d.pop("node_details", UNSET)
        node_details: ActionGraphDocNodeDetails | Unset
        if isinstance(_node_details, Unset):
            node_details = UNSET
        else:
            node_details = ActionGraphDocNodeDetails.from_dict(_node_details)

        def _parse_graph(data: object) -> ActionGraphDocGraphType0 | None | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, dict):
                    raise TypeError()
                graph_type_0 = ActionGraphDocGraphType0.from_dict(data)

                return graph_type_0
            except (TypeError, ValueError, AttributeError, KeyError):
                pass
            return cast(ActionGraphDocGraphType0 | None | Unset, data)

        graph = _parse_graph(d.pop("graph", UNSET))

        def _parse_start_node_id(data: object) -> None | str | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            return cast(None | str | Unset, data)

        start_node_id = _parse_start_node_id(d.pop("start_node_id", UNSET))

        def _parse_input_(data: object) -> ActionGraphDocInputType0 | None | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, dict):
                    raise TypeError()
                input_type_0 = ActionGraphDocInputType0.from_dict(data)

                return input_type_0
            except (TypeError, ValueError, AttributeError, KeyError):
                pass
            return cast(ActionGraphDocInputType0 | None | Unset, data)

        input_ = _parse_input_(d.pop("input", UNSET))

        def _parse_output(data: object) -> ActionGraphDocOutputType0 | None | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, dict):
                    raise TypeError()
                output_type_0 = ActionGraphDocOutputType0.from_dict(data)

                return output_type_0
            except (TypeError, ValueError, AttributeError, KeyError):
                pass
            return cast(ActionGraphDocOutputType0 | None | Unset, data)

        output = _parse_output(d.pop("output", UNSET))

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

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

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

        def _parse_time_saved_per_file(data: object) -> float | None | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            return cast(float | None | Unset, data)

        time_saved_per_file = _parse_time_saved_per_file(d.pop("time_saved_per_file", UNSET))

        def _parse_dollar_cost_per_hour(data: object) -> float | None | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            return cast(float | None | Unset, data)

        dollar_cost_per_hour = _parse_dollar_cost_per_hour(d.pop("dollar_cost_per_hour", UNSET))

        _created_at = d.pop("created_at", UNSET)
        created_at: datetime.datetime | Unset
        if isinstance(_created_at, Unset):
            created_at = UNSET
        else:
            created_at = isoparse(_created_at)

        action_graph_doc = cls(
            name=name,
            user_id=user_id,
            field_id=field_id,
            updated_at=updated_at,
            version=version,
            description=description,
            user_manual=user_manual,
            nodes=nodes,
            node_details=node_details,
            graph=graph,
            start_node_id=start_node_id,
            input_=input_,
            output=output,
            is_saved=is_saved,
            is_published=is_published,
            shared_with=shared_with,
            time_saved_per_file=time_saved_per_file,
            dollar_cost_per_hour=dollar_cost_per_hour,
            created_at=created_at,
        )

        action_graph_doc.additional_properties = d
        return action_graph_doc

    @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
