# coding: utf-8

"""
    Perigon API

    The Perigon API provides access to comprehensive news and web content data. To use the API, simply sign up for a Perigon Business Solutions account to obtain your API key. Your available features may vary based on your plan. See the Authentication section for details on how to use your API key.

    The version of the OpenAPI document: 1.0.0
    Contact: data@perigon.io
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations

import json
import pprint
import re  # noqa: F401
from typing import Any, ClassVar, Dict, List, Optional, Set

from perigon_sdk.models.category_holder import CategoryHolder
from perigon_sdk.models.company_count import CompanyCount
from perigon_sdk.models.company_holder import CompanyHolder
from perigon_sdk.models.key_point import KeyPoint
from perigon_sdk.models.location_count import LocationCount
from perigon_sdk.models.location_holder import LocationHolder
from perigon_sdk.models.person_count import PersonCount
from perigon_sdk.models.person_holder import PersonHolder
from perigon_sdk.models.question import Question
from perigon_sdk.models.record_stat_holder import RecordStatHolder
from perigon_sdk.models.sentiment_holder import SentimentHolder
from perigon_sdk.models.source_holder import SourceHolder
from perigon_sdk.models.topic_holder import TopicHolder
from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr
from typing_extensions import Self


class NewsCluster(BaseModel):
    """
    NewsCluster
    """  # noqa: E501

    created_at: Optional[StrictStr] = Field(default=None, alias="createdAt")
    updated_at: Optional[StrictStr] = Field(default=None, alias="updatedAt")
    initialized_at: Optional[StrictStr] = Field(default=None, alias="initializedAt")
    id: Optional[StrictStr] = None
    duplicate_of: Optional[StrictStr] = Field(default=None, alias="duplicateOf")
    slug: Optional[StrictStr] = None
    name: Optional[StrictStr] = None
    summary: Optional[StrictStr] = None
    short_summary: Optional[StrictStr] = Field(default=None, alias="shortSummary")
    summary_references: Optional[List[StrictStr]] = Field(
        default=None, alias="summaryReferences"
    )
    image_source: Optional[SourceHolder] = Field(default=None, alias="imageSource")
    image_url: Optional[StrictStr] = Field(default=None, alias="imageUrl")
    key_points: Optional[List[KeyPoint]] = Field(default=None, alias="keyPoints")
    questions: Optional[List[Question]] = None
    unique_sources: Optional[List[StrictStr]] = Field(
        default=None, alias="uniqueSources"
    )
    selected_articles: Optional[List[Article]] = Field(
        default=None, alias="selectedArticles"
    )
    sentiment: Optional[SentimentHolder] = None
    unique_count: Optional[StrictInt] = Field(default=None, alias="uniqueCount")
    reprint_count: Optional[StrictInt] = Field(default=None, alias="reprintCount")
    total_count: Optional[StrictInt] = Field(default=None, alias="totalCount")
    countries: Optional[List[RecordStatHolder]] = None
    top_countries: Optional[List[StrictStr]] = Field(default=None, alias="topCountries")
    topics: Optional[List[RecordStatHolder]] = None
    top_topics: Optional[List[TopicHolder]] = Field(default=None, alias="topTopics")
    categories: Optional[List[RecordStatHolder]] = None
    top_categories: Optional[List[CategoryHolder]] = Field(
        default=None, alias="topCategories"
    )
    taxonomies: Optional[List[RecordStatHolder]] = None
    top_taxonomies: Optional[List[CategoryHolder]] = Field(
        default=None, alias="topTaxonomies"
    )
    people: Optional[List[PersonCount]] = None
    top_people: Optional[List[PersonHolder]] = Field(default=None, alias="topPeople")
    companies: Optional[List[CompanyCount]] = None
    top_companies: Optional[List[CompanyHolder]] = Field(
        default=None, alias="topCompanies"
    )
    locations: Optional[List[LocationCount]] = None
    top_locations: Optional[List[LocationHolder]] = Field(
        default=None, alias="topLocations"
    )
    __properties: ClassVar[List[str]] = [
        "createdAt",
        "updatedAt",
        "initializedAt",
        "id",
        "duplicateOf",
        "slug",
        "name",
        "summary",
        "shortSummary",
        "summaryReferences",
        "imageSource",
        "imageUrl",
        "keyPoints",
        "questions",
        "uniqueSources",
        "selectedArticles",
        "sentiment",
        "uniqueCount",
        "reprintCount",
        "totalCount",
        "countries",
        "topCountries",
        "topics",
        "topTopics",
        "categories",
        "topCategories",
        "taxonomies",
        "topTaxonomies",
        "people",
        "topPeople",
        "companies",
        "topCompanies",
        "locations",
        "topLocations",
    ]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )

    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of NewsCluster from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of image_source
        if self.image_source:
            _dict["imageSource"] = self.image_source.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in key_points (list)
        _items = []
        if self.key_points:
            for _item_key_points in self.key_points:
                if _item_key_points:
                    _items.append(_item_key_points.to_dict())
            _dict["keyPoints"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in questions (list)
        _items = []
        if self.questions:
            for _item_questions in self.questions:
                if _item_questions:
                    _items.append(_item_questions.to_dict())
            _dict["questions"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in selected_articles (list)
        _items = []
        if self.selected_articles:
            for _item_selected_articles in self.selected_articles:
                if _item_selected_articles:
                    _items.append(_item_selected_articles.to_dict())
            _dict["selectedArticles"] = _items
        # override the default output from pydantic by calling `to_dict()` of sentiment
        if self.sentiment:
            _dict["sentiment"] = self.sentiment.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in countries (list)
        _items = []
        if self.countries:
            for _item_countries in self.countries:
                if _item_countries:
                    _items.append(_item_countries.to_dict())
            _dict["countries"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in topics (list)
        _items = []
        if self.topics:
            for _item_topics in self.topics:
                if _item_topics:
                    _items.append(_item_topics.to_dict())
            _dict["topics"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in top_topics (list)
        _items = []
        if self.top_topics:
            for _item_top_topics in self.top_topics:
                if _item_top_topics:
                    _items.append(_item_top_topics.to_dict())
            _dict["topTopics"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in categories (list)
        _items = []
        if self.categories:
            for _item_categories in self.categories:
                if _item_categories:
                    _items.append(_item_categories.to_dict())
            _dict["categories"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in top_categories (list)
        _items = []
        if self.top_categories:
            for _item_top_categories in self.top_categories:
                if _item_top_categories:
                    _items.append(_item_top_categories.to_dict())
            _dict["topCategories"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in taxonomies (list)
        _items = []
        if self.taxonomies:
            for _item_taxonomies in self.taxonomies:
                if _item_taxonomies:
                    _items.append(_item_taxonomies.to_dict())
            _dict["taxonomies"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in top_taxonomies (list)
        _items = []
        if self.top_taxonomies:
            for _item_top_taxonomies in self.top_taxonomies:
                if _item_top_taxonomies:
                    _items.append(_item_top_taxonomies.to_dict())
            _dict["topTaxonomies"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in people (list)
        _items = []
        if self.people:
            for _item_people in self.people:
                if _item_people:
                    _items.append(_item_people.to_dict())
            _dict["people"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in top_people (list)
        _items = []
        if self.top_people:
            for _item_top_people in self.top_people:
                if _item_top_people:
                    _items.append(_item_top_people.to_dict())
            _dict["topPeople"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in companies (list)
        _items = []
        if self.companies:
            for _item_companies in self.companies:
                if _item_companies:
                    _items.append(_item_companies.to_dict())
            _dict["companies"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in top_companies (list)
        _items = []
        if self.top_companies:
            for _item_top_companies in self.top_companies:
                if _item_top_companies:
                    _items.append(_item_top_companies.to_dict())
            _dict["topCompanies"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in locations (list)
        _items = []
        if self.locations:
            for _item_locations in self.locations:
                if _item_locations:
                    _items.append(_item_locations.to_dict())
            _dict["locations"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in top_locations (list)
        _items = []
        if self.top_locations:
            for _item_top_locations in self.top_locations:
                if _item_top_locations:
                    _items.append(_item_top_locations.to_dict())
            _dict["topLocations"] = _items
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of NewsCluster from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate(
            {
                "createdAt": obj.get("createdAt"),
                "updatedAt": obj.get("updatedAt"),
                "initializedAt": obj.get("initializedAt"),
                "id": obj.get("id"),
                "duplicateOf": obj.get("duplicateOf"),
                "slug": obj.get("slug"),
                "name": obj.get("name"),
                "summary": obj.get("summary"),
                "shortSummary": obj.get("shortSummary"),
                "summaryReferences": obj.get("summaryReferences"),
                "imageSource": SourceHolder.from_dict(obj["imageSource"])
                if obj.get("imageSource") is not None
                else None,
                "imageUrl": obj.get("imageUrl"),
                "keyPoints": [KeyPoint.from_dict(_item) for _item in obj["keyPoints"]]
                if obj.get("keyPoints") is not None
                else None,
                "questions": [Question.from_dict(_item) for _item in obj["questions"]]
                if obj.get("questions") is not None
                else None,
                "uniqueSources": obj.get("uniqueSources"),
                "selectedArticles": [
                    Article.from_dict(_item) for _item in obj["selectedArticles"]
                ]
                if obj.get("selectedArticles") is not None
                else None,
                "sentiment": SentimentHolder.from_dict(obj["sentiment"])
                if obj.get("sentiment") is not None
                else None,
                "uniqueCount": obj.get("uniqueCount"),
                "reprintCount": obj.get("reprintCount"),
                "totalCount": obj.get("totalCount"),
                "countries": [
                    RecordStatHolder.from_dict(_item) for _item in obj["countries"]
                ]
                if obj.get("countries") is not None
                else None,
                "topCountries": obj.get("topCountries"),
                "topics": [RecordStatHolder.from_dict(_item) for _item in obj["topics"]]
                if obj.get("topics") is not None
                else None,
                "topTopics": [
                    TopicHolder.from_dict(_item) for _item in obj["topTopics"]
                ]
                if obj.get("topTopics") is not None
                else None,
                "categories": [
                    RecordStatHolder.from_dict(_item) for _item in obj["categories"]
                ]
                if obj.get("categories") is not None
                else None,
                "topCategories": [
                    CategoryHolder.from_dict(_item) for _item in obj["topCategories"]
                ]
                if obj.get("topCategories") is not None
                else None,
                "taxonomies": [
                    RecordStatHolder.from_dict(_item) for _item in obj["taxonomies"]
                ]
                if obj.get("taxonomies") is not None
                else None,
                "topTaxonomies": [
                    CategoryHolder.from_dict(_item) for _item in obj["topTaxonomies"]
                ]
                if obj.get("topTaxonomies") is not None
                else None,
                "people": [PersonCount.from_dict(_item) for _item in obj["people"]]
                if obj.get("people") is not None
                else None,
                "topPeople": [
                    PersonHolder.from_dict(_item) for _item in obj["topPeople"]
                ]
                if obj.get("topPeople") is not None
                else None,
                "companies": [
                    CompanyCount.from_dict(_item) for _item in obj["companies"]
                ]
                if obj.get("companies") is not None
                else None,
                "topCompanies": [
                    CompanyHolder.from_dict(_item) for _item in obj["topCompanies"]
                ]
                if obj.get("topCompanies") is not None
                else None,
                "locations": [
                    LocationCount.from_dict(_item) for _item in obj["locations"]
                ]
                if obj.get("locations") is not None
                else None,
                "topLocations": [
                    LocationHolder.from_dict(_item) for _item in obj["topLocations"]
                ]
                if obj.get("topLocations") is not None
                else None,
            }
        )
        return _obj


from perigon_sdk.models.article import Article

# TODO: Rewrite to not use raise_errors
NewsCluster.model_rebuild(raise_errors=False)
