from __future__ import annotations

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 ..types import UNSET, Unset

if TYPE_CHECKING:
    from ..models.types_activity import TypesActivity
    from ..models.types_comment import TypesComment
    from ..models.types_deal import TypesDeal
    from ..models.types_field import TypesField
    from ..models.types_task import TypesTask


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


@_attrs_define
class TypesProject:
    """
    Attributes:
        field_id (str | Unset):
        access (list[str] | Unset): Access control - this is essentially just a list of user IDs who have tasks in this
            project that are assigned to them.
            R/W access is controlled by the individual use scopes
        activity (list[TypesActivity] | Unset): For returning when loading
        client (str | Unset):
        client_name (str | Unset):
        comments (list[TypesComment] | Unset):
        completed_at (str | Unset):
        created_at (str | Unset): Time tracking
        deal (str | Unset):
        deal_name (str | Unset):
        deal_object (TypesDeal | Unset):
        deleted_at (str | Unset):
        description (str | Unset):
        due (str | Unset):
        fields (list[TypesField] | Unset):
        incomplete_tasks (int | Unset):
        lead (str | Unset):
        next_ (TypesTask | Unset):
        plan (str | Unset):
        plan_name (str | Unset):
        starred (list[str] | Unset):
        status (str | Unset): Status (this is based on the status of tasks within the project)
        tags (list[str] | Unset):
        tasks (list[TypesTask] | Unset):
        team (str | Unset):
        team_wide_access (bool | Unset): Team-wide access - if true, all team members have access to this project
        template (str | Unset):
        title (str | Unset):
        total_tasks (int | Unset):
        view (str | Unset):
    """

    field_id: str | Unset = UNSET
    access: list[str] | Unset = UNSET
    activity: list[TypesActivity] | Unset = UNSET
    client: str | Unset = UNSET
    client_name: str | Unset = UNSET
    comments: list[TypesComment] | Unset = UNSET
    completed_at: str | Unset = UNSET
    created_at: str | Unset = UNSET
    deal: str | Unset = UNSET
    deal_name: str | Unset = UNSET
    deal_object: TypesDeal | Unset = UNSET
    deleted_at: str | Unset = UNSET
    description: str | Unset = UNSET
    due: str | Unset = UNSET
    fields: list[TypesField] | Unset = UNSET
    incomplete_tasks: int | Unset = UNSET
    lead: str | Unset = UNSET
    next_: TypesTask | Unset = UNSET
    plan: str | Unset = UNSET
    plan_name: str | Unset = UNSET
    starred: list[str] | Unset = UNSET
    status: str | Unset = UNSET
    tags: list[str] | Unset = UNSET
    tasks: list[TypesTask] | Unset = UNSET
    team: str | Unset = UNSET
    team_wide_access: bool | Unset = UNSET
    template: str | Unset = UNSET
    title: str | Unset = UNSET
    total_tasks: int | Unset = UNSET
    view: str | Unset = UNSET
    additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)

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

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

        activity: list[dict[str, Any]] | Unset = UNSET
        if not isinstance(self.activity, Unset):
            activity = []
            for activity_item_data in self.activity:
                activity_item = activity_item_data.to_dict()
                activity.append(activity_item)

        client = self.client

        client_name = self.client_name

        comments: list[dict[str, Any]] | Unset = UNSET
        if not isinstance(self.comments, Unset):
            comments = []
            for comments_item_data in self.comments:
                comments_item = comments_item_data.to_dict()
                comments.append(comments_item)

        completed_at = self.completed_at

        created_at = self.created_at

        deal = self.deal

        deal_name = self.deal_name

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

        deleted_at = self.deleted_at

        description = self.description

        due = self.due

        fields: list[dict[str, Any]] | Unset = UNSET
        if not isinstance(self.fields, Unset):
            fields = []
            for fields_item_data in self.fields:
                fields_item = fields_item_data.to_dict()
                fields.append(fields_item)

        incomplete_tasks = self.incomplete_tasks

        lead = self.lead

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

        plan = self.plan

        plan_name = self.plan_name

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

        status = self.status

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

        tasks: list[dict[str, Any]] | Unset = UNSET
        if not isinstance(self.tasks, Unset):
            tasks = []
            for tasks_item_data in self.tasks:
                tasks_item = tasks_item_data.to_dict()
                tasks.append(tasks_item)

        team = self.team

        team_wide_access = self.team_wide_access

        template = self.template

        title = self.title

        total_tasks = self.total_tasks

        view = self.view

        field_dict: dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update({})
        if field_id is not UNSET:
            field_dict["_id"] = field_id
        if access is not UNSET:
            field_dict["access"] = access
        if activity is not UNSET:
            field_dict["activity"] = activity
        if client is not UNSET:
            field_dict["client"] = client
        if client_name is not UNSET:
            field_dict["client_name"] = client_name
        if comments is not UNSET:
            field_dict["comments"] = comments
        if completed_at is not UNSET:
            field_dict["completed_at"] = completed_at
        if created_at is not UNSET:
            field_dict["created_at"] = created_at
        if deal is not UNSET:
            field_dict["deal"] = deal
        if deal_name is not UNSET:
            field_dict["deal_name"] = deal_name
        if deal_object is not UNSET:
            field_dict["deal_object"] = deal_object
        if deleted_at is not UNSET:
            field_dict["deleted_at"] = deleted_at
        if description is not UNSET:
            field_dict["description"] = description
        if due is not UNSET:
            field_dict["due"] = due
        if fields is not UNSET:
            field_dict["fields"] = fields
        if incomplete_tasks is not UNSET:
            field_dict["incomplete_tasks"] = incomplete_tasks
        if lead is not UNSET:
            field_dict["lead"] = lead
        if next_ is not UNSET:
            field_dict["next"] = next_
        if plan is not UNSET:
            field_dict["plan"] = plan
        if plan_name is not UNSET:
            field_dict["plan_name"] = plan_name
        if starred is not UNSET:
            field_dict["starred"] = starred
        if status is not UNSET:
            field_dict["status"] = status
        if tags is not UNSET:
            field_dict["tags"] = tags
        if tasks is not UNSET:
            field_dict["tasks"] = tasks
        if team is not UNSET:
            field_dict["team"] = team
        if team_wide_access is not UNSET:
            field_dict["team_wide_access"] = team_wide_access
        if template is not UNSET:
            field_dict["template"] = template
        if title is not UNSET:
            field_dict["title"] = title
        if total_tasks is not UNSET:
            field_dict["total_tasks"] = total_tasks
        if view is not UNSET:
            field_dict["view"] = view

        return field_dict

    @classmethod
    def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
        from ..models.types_activity import TypesActivity
        from ..models.types_comment import TypesComment
        from ..models.types_deal import TypesDeal
        from ..models.types_field import TypesField
        from ..models.types_task import TypesTask

        d = dict(src_dict)
        field_id = d.pop("_id", UNSET)

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

        _activity = d.pop("activity", UNSET)
        activity: list[TypesActivity] | Unset = UNSET
        if _activity is not UNSET:
            activity = []
            for activity_item_data in _activity:
                activity_item = TypesActivity.from_dict(activity_item_data)

                activity.append(activity_item)

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

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

        _comments = d.pop("comments", UNSET)
        comments: list[TypesComment] | Unset = UNSET
        if _comments is not UNSET:
            comments = []
            for comments_item_data in _comments:
                comments_item = TypesComment.from_dict(comments_item_data)

                comments.append(comments_item)

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

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

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

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

        _deal_object = d.pop("deal_object", UNSET)
        deal_object: TypesDeal | Unset
        if isinstance(_deal_object, Unset):
            deal_object = UNSET
        else:
            deal_object = TypesDeal.from_dict(_deal_object)

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

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

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

        _fields = d.pop("fields", UNSET)
        fields: list[TypesField] | Unset = UNSET
        if _fields is not UNSET:
            fields = []
            for fields_item_data in _fields:
                fields_item = TypesField.from_dict(fields_item_data)

                fields.append(fields_item)

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

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

        _next_ = d.pop("next", UNSET)
        next_: TypesTask | Unset
        if isinstance(_next_, Unset):
            next_ = UNSET
        else:
            next_ = TypesTask.from_dict(_next_)

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

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

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

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

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

        _tasks = d.pop("tasks", UNSET)
        tasks: list[TypesTask] | Unset = UNSET
        if _tasks is not UNSET:
            tasks = []
            for tasks_item_data in _tasks:
                tasks_item = TypesTask.from_dict(tasks_item_data)

                tasks.append(tasks_item)

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

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

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

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

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

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

        types_project = cls(
            field_id=field_id,
            access=access,
            activity=activity,
            client=client,
            client_name=client_name,
            comments=comments,
            completed_at=completed_at,
            created_at=created_at,
            deal=deal,
            deal_name=deal_name,
            deal_object=deal_object,
            deleted_at=deleted_at,
            description=description,
            due=due,
            fields=fields,
            incomplete_tasks=incomplete_tasks,
            lead=lead,
            next_=next_,
            plan=plan,
            plan_name=plan_name,
            starred=starred,
            status=status,
            tags=tags,
            tasks=tasks,
            team=team,
            team_wide_access=team_wide_access,
            template=template,
            title=title,
            total_tasks=total_tasks,
            view=view,
        )

        types_project.additional_properties = d
        return types_project

    @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
