# 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 datetime import datetime
from typing import Any, ClassVar, Dict, List, Optional, Set

from pydantic import BaseModel, ConfigDict, Field, StrictBool
from typing_extensions import Annotated, Self

from perigon.models.article_search_filter import ArticleSearchFilter


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

    prompt: Annotated[str, Field(min_length=0, strict=True, max_length=1024)] = Field(
        description="Natural language query to search the news articles database"
    )
    filter: Optional[ArticleSearchFilter] = None
    pub_date_from: Optional[datetime] = Field(
        default=None,
        description="'pubDateFrom' filter, will search articles published after the specified date, the date could be passed as ISO or 'yyyy-mm-dd'. Date time in ISO format, ie. 2024-01-01T00:00:00 - Default: Only articles with a pubDate within the last 30 days of the request",
        alias="pubDateFrom",
    )
    pub_date_to: Optional[datetime] = Field(
        default=None,
        description="'pubDateTo' filter, will search articles published before the specified date, the date could be passed as ISO or 'yyyy-mm-dd'. Date time in ISO format, ie. 2024-01-01T00:00:00",
        alias="pubDateTo",
    )
    show_reprints: Optional[StrictBool] = Field(
        default=True,
        description="Whether to return reprints in the response or not. Reprints are usually wired articles from sources like AP or Reuters that are reprinted in multiple sources at the same time. By default, this parameter is 'true'.",
        alias="showReprints",
    )
    size: Optional[Annotated[int, Field(le=100, strict=True, ge=1)]] = Field(
        default=10, description="The number of items per page."
    )
    page: Optional[Annotated[int, Field(le=10000, strict=True, ge=0)]] = Field(
        default=0, description="The page number to retrieve."
    )
    __properties: ClassVar[List[str]] = [
        "prompt",
        "filter",
        "pubDateFrom",
        "pubDateTo",
        "showReprints",
        "size",
        "page",
    ]

    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 ArticleSearchParams 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 filter
        if self.filter:
            _dict["filter"] = self.filter.to_dict()
        # set to None if filter (nullable) is None
        # and model_fields_set contains the field
        if self.filter is None and "filter" in self.model_fields_set:
            _dict["filter"] = None

        # set to None if pub_date_from (nullable) is None
        # and model_fields_set contains the field
        if self.pub_date_from is None and "pub_date_from" in self.model_fields_set:
            _dict["pubDateFrom"] = None

        # set to None if pub_date_to (nullable) is None
        # and model_fields_set contains the field
        if self.pub_date_to is None and "pub_date_to" in self.model_fields_set:
            _dict["pubDateTo"] = None

        # set to None if show_reprints (nullable) is None
        # and model_fields_set contains the field
        if self.show_reprints is None and "show_reprints" in self.model_fields_set:
            _dict["showReprints"] = None

        # set to None if size (nullable) is None
        # and model_fields_set contains the field
        if self.size is None and "size" in self.model_fields_set:
            _dict["size"] = None

        # set to None if page (nullable) is None
        # and model_fields_set contains the field
        if self.page is None and "page" in self.model_fields_set:
            _dict["page"] = None

        return _dict

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

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

        _obj = cls.model_validate(
            {
                "prompt": obj.get("prompt"),
                "filter": (
                    ArticleSearchFilter.from_dict(obj["filter"])
                    if obj.get("filter") is not None
                    else None
                ),
                "pubDateFrom": obj.get("pubDateFrom"),
                "pubDateTo": obj.get("pubDateTo"),
                "showReprints": (
                    obj.get("showReprints")
                    if obj.get("showReprints") is not None
                    else True
                ),
                "size": obj.get("size") if obj.get("size") is not None else 10,
                "page": obj.get("page") if obj.get("page") is not None else 0,
            }
        )
        return _obj
