from __future__ import annotations

from collections.abc import Mapping
from typing import Any, TypeVar, 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 ..types import UNSET, Unset
from typing import cast

if TYPE_CHECKING:
  from ..models.daily_usage import DailyUsage
  from ..models.project_usage_response_by_feature import ProjectUsageResponseByFeature
  from ..models.project_usage_response_by_user import ProjectUsageResponseByUser
  from ..models.project_usage_response_by_workspace import ProjectUsageResponseByWorkspace
  from ..models.project_usage_response_model_groups import ProjectUsageResponseModelGroups





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



@_attrs_define
class ProjectUsageResponse:
    """ Usage breakdown for a project's billing period.

        Attributes:
            project_ext_id (str):
            period_start (str):
            period_end (str):
            total_spend (float | Unset):  Default: 0.0.
            total_tokens (int | Unset):  Default: 0.
            total_requests (int | Unset):  Default: 0.
            daily (list[DailyUsage] | Unset):
            model_groups (ProjectUsageResponseModelGroups | Unset):
            by_workspace (ProjectUsageResponseByWorkspace | Unset):
            by_user (ProjectUsageResponseByUser | Unset):
            by_feature (ProjectUsageResponseByFeature | Unset):
            invoice_pdf (None | str | Unset):
     """

    project_ext_id: str
    period_start: str
    period_end: str
    total_spend: float | Unset = 0.0
    total_tokens: int | Unset = 0
    total_requests: int | Unset = 0
    daily: list[DailyUsage] | Unset = UNSET
    model_groups: ProjectUsageResponseModelGroups | Unset = UNSET
    by_workspace: ProjectUsageResponseByWorkspace | Unset = UNSET
    by_user: ProjectUsageResponseByUser | Unset = UNSET
    by_feature: ProjectUsageResponseByFeature | Unset = UNSET
    invoice_pdf: None | str | Unset = UNSET
    additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)





    def to_dict(self) -> dict[str, Any]:
        from ..models.project_usage_response_model_groups import ProjectUsageResponseModelGroups
        from ..models.project_usage_response_by_user import ProjectUsageResponseByUser
        from ..models.project_usage_response_by_workspace import ProjectUsageResponseByWorkspace
        from ..models.project_usage_response_by_feature import ProjectUsageResponseByFeature
        from ..models.daily_usage import DailyUsage
        project_ext_id = self.project_ext_id

        period_start = self.period_start

        period_end = self.period_end

        total_spend = self.total_spend

        total_tokens = self.total_tokens

        total_requests = self.total_requests

        daily: list[dict[str, Any]] | Unset = UNSET
        if not isinstance(self.daily, Unset):
            daily = []
            for daily_item_data in self.daily:
                daily_item = daily_item_data.to_dict()
                daily.append(daily_item)



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

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

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

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

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


        field_dict: dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update({
            "project_ext_id": project_ext_id,
            "period_start": period_start,
            "period_end": period_end,
        })
        if total_spend is not UNSET:
            field_dict["total_spend"] = total_spend
        if total_tokens is not UNSET:
            field_dict["total_tokens"] = total_tokens
        if total_requests is not UNSET:
            field_dict["total_requests"] = total_requests
        if daily is not UNSET:
            field_dict["daily"] = daily
        if model_groups is not UNSET:
            field_dict["model_groups"] = model_groups
        if by_workspace is not UNSET:
            field_dict["by_workspace"] = by_workspace
        if by_user is not UNSET:
            field_dict["by_user"] = by_user
        if by_feature is not UNSET:
            field_dict["by_feature"] = by_feature
        if invoice_pdf is not UNSET:
            field_dict["invoice_pdf"] = invoice_pdf

        return field_dict



    @classmethod
    def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
        from ..models.daily_usage import DailyUsage
        from ..models.project_usage_response_by_feature import ProjectUsageResponseByFeature
        from ..models.project_usage_response_by_user import ProjectUsageResponseByUser
        from ..models.project_usage_response_by_workspace import ProjectUsageResponseByWorkspace
        from ..models.project_usage_response_model_groups import ProjectUsageResponseModelGroups
        d = dict(src_dict)
        project_ext_id = d.pop("project_ext_id")

        period_start = d.pop("period_start")

        period_end = d.pop("period_end")

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

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

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

        _daily = d.pop("daily", UNSET)
        daily: list[DailyUsage] | Unset = UNSET
        if _daily is not UNSET:
            daily = []
            for daily_item_data in _daily:
                daily_item = DailyUsage.from_dict(daily_item_data)



                daily.append(daily_item)


        _model_groups = d.pop("model_groups", UNSET)
        model_groups: ProjectUsageResponseModelGroups | Unset
        if isinstance(_model_groups,  Unset):
            model_groups = UNSET
        else:
            model_groups = ProjectUsageResponseModelGroups.from_dict(_model_groups)




        _by_workspace = d.pop("by_workspace", UNSET)
        by_workspace: ProjectUsageResponseByWorkspace | Unset
        if isinstance(_by_workspace,  Unset):
            by_workspace = UNSET
        else:
            by_workspace = ProjectUsageResponseByWorkspace.from_dict(_by_workspace)




        _by_user = d.pop("by_user", UNSET)
        by_user: ProjectUsageResponseByUser | Unset
        if isinstance(_by_user,  Unset):
            by_user = UNSET
        else:
            by_user = ProjectUsageResponseByUser.from_dict(_by_user)




        _by_feature = d.pop("by_feature", UNSET)
        by_feature: ProjectUsageResponseByFeature | Unset
        if isinstance(_by_feature,  Unset):
            by_feature = UNSET
        else:
            by_feature = ProjectUsageResponseByFeature.from_dict(_by_feature)




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

        invoice_pdf = _parse_invoice_pdf(d.pop("invoice_pdf", UNSET))


        project_usage_response = cls(
            project_ext_id=project_ext_id,
            period_start=period_start,
            period_end=period_end,
            total_spend=total_spend,
            total_tokens=total_tokens,
            total_requests=total_requests,
            daily=daily,
            model_groups=model_groups,
            by_workspace=by_workspace,
            by_user=by_user,
            by_feature=by_feature,
            invoice_pdf=invoice_pdf,
        )


        project_usage_response.additional_properties = d
        return project_usage_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
