from __future__ import annotations

import datetime
from collections.abc import Mapping
from typing import 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

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


@_attrs_define
class InstantiatedTemplateResponse:
    """Response after successful template instantiation.

    Provides all information needed to start using the newly created namespace,
    including IDs for API calls and status information.

    The namespace is immediately ready for use when status is 'ready'.
    All collections, documents, and feature stores are fully functional.

    Use Cases:
        - Retrieve namespace_id for subsequent API calls
        - Verify instantiation completed successfully
        - Track which template was used for the namespace
        - Record creation timestamp for auditing

    Fields:
        All fields are REQUIRED and populated by the server.

        Attributes:
            namespace_id (str): ID of the newly created namespace. REQUIRED. Use this ID in the X-Namespace header for all
                API calls to this namespace. Format: namespace ID starting with 'ns_'. Permanent identifier for the namespace.
            namespace_name (str): Name of the newly created namespace. REQUIRED. Matches the namespace_name from the
                request. Human-readable identifier shown in UI. Can be used for namespace lookup via GET /namespaces/{name}.
            template_id (str): ID of the template that was instantiated. REQUIRED. Reference to the source template used for
                creation. Useful for tracking which template produced this namespace. Format: template ID starting with 'tmpl_'.
            status (str | Unset): Instantiation status. REQUIRED. 'cloning' means the namespace is being created and data is
                being copied. 'ready' means the namespace is fully functional and ready to use. 'failed' means the cloning
                process encountered an error. Poll GET /namespaces/{namespace_id} to check when status becomes 'ready'. All data
                is cloned including collections, vectors, retrievers, and taxonomies. Default: 'cloning'.
            task_id (None | str | Unset): Celery task ID for tracking the clone operation. Can be used to poll task status
                if needed. Format: UUID string.
            created_at (datetime.datetime | Unset): Timestamp when namespace was created. REQUIRED. Auto-generated by
                server. Format: ISO 8601 datetime in UTC. Used for auditing and sorting namespaces by creation time.
    """

    namespace_id: str
    namespace_name: str
    template_id: str
    status: str | Unset = "cloning"
    task_id: None | str | Unset = UNSET
    created_at: datetime.datetime | Unset = UNSET
    additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)

    def to_dict(self) -> dict[str, Any]:
        namespace_id = self.namespace_id

        namespace_name = self.namespace_name

        template_id = self.template_id

        status = self.status

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

        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(
            {
                "namespace_id": namespace_id,
                "namespace_name": namespace_name,
                "template_id": template_id,
            }
        )
        if status is not UNSET:
            field_dict["status"] = status
        if task_id is not UNSET:
            field_dict["task_id"] = task_id
        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:
        d = dict(src_dict)
        namespace_id = d.pop("namespace_id")

        namespace_name = d.pop("namespace_name")

        template_id = d.pop("template_id")

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

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

        task_id = _parse_task_id(d.pop("task_id", 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)

        instantiated_template_response = cls(
            namespace_id=namespace_id,
            namespace_name=namespace_name,
            template_id=template_id,
            status=status,
            task_id=task_id,
            created_at=created_at,
        )

        instantiated_template_response.additional_properties = d
        return instantiated_template_response

    @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
