# coding: utf-8

"""
    Pinterest REST API

    Pinterest's REST API

    The version of the OpenAPI document: 5.23.0
    Contact: blah+oapicf@cliffano.com
    Generated by OpenAPI Generator (https://openapi-generator.tech)

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


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional, Union
from typing_extensions import Annotated
from pinterestsdk.models.action_type import ActionType
from pinterestsdk.models.budget_type import BudgetType
from pinterestsdk.models.entity_status import EntityStatus
from pinterestsdk.models.optimization_goal_metadata import OptimizationGoalMetadata
from pinterestsdk.models.pacing_delivery_type import PacingDeliveryType
from pinterestsdk.models.placement_group_type import PlacementGroupType
from pinterestsdk.models.targeting_spec import TargetingSpec
from pinterestsdk.models.tracking_urls import TrackingUrls
from typing import Optional, Set
from typing_extensions import Self

class AdGroupCreateRequest(BaseModel):
    """
    AdGroupCreateRequest
    """ # noqa: E501
    auto_targeting_enabled: Optional[StrictBool] = Field(default=None, description="Enable auto-targeting for ad group. Default value is True. Also known as <a href=\"https://help.pinterest.com/en/business/article/performance-plus-targeting\" target=\"_blank\">\"Pinterest Performance+ targeting\"</a>.")
    bid_in_micro_currency: Optional[StrictInt] = Field(default=None, description="Bid price in micro currency. This field is **REQUIRED** for the following campaign objective_type/billable_event combinations: AWARENESS/IMPRESSION, CONSIDERATION/CLICKTHROUGH, CATALOG_SALES/CLICKTHROUGH.")
    bid_strategy_type: Optional[StrictStr] = Field(default=None, description="Bid strategy type. For Campaigns with Video Completion objectives, the only supported bid strategy type is AUTOMATIC_BID, also known as \"Pinterest Performance+ bidding\".")
    billable_event: ActionType
    budget_in_micro_currency: Optional[StrictInt] = Field(default=None, description="Budget in micro currency. This field is **REQUIRED** for non-CBO (campaign budget optimization) campaigns.  A CBO campaign automatically generates ad group budgets from its campaign budget to maximize campaign outcome. A CBO campaign is limited to 70 or less ad groups.")
    budget_type: Optional[BudgetType] = 'DAILY'
    campaign_id: Annotated[str, Field(strict=True)] = Field(description="Campaign ID of the ad group.")
    end_time: Optional[StrictInt] = Field(default=None, description="Timestamp in Unix format for scheduling when ads in the ad group stop appearing. If not specified, ads run indefinitely unless you update the ad group by changing their status to `paused`. Cannot occur after `end_time` for parent campaign (if specified). Learn about <a href=\"/docs/api-features/managing-ads/#step-2-create-an-ad-group\" target=\"blank\">scheduling ads</a>. For certain organizations (<a href=\"/docs/getting-started/using-beta-and-restricted-features/\" target=\"blank\" target=\"blank\">Closed beta</a>): Supported for campaigns with Campaign Budget Optimization (CBO). For all organizations: Supported for campaigns without CBO.")
    is_creative_optimization: Optional[StrictBool] = Field(default=None, description="Enable creative optimization for the ad group, default value is FALSE. When enabled, you allow Pinterest to automatically turn your product Pins into ads in different formats (collections and shopping) and deliver those ads to users at scale.")
    lifetime_frequency_cap: Optional[StrictInt] = Field(default=None, description="Set a limit to the number of times a promoted pin from this campaign can be impressed by a pinner within the past rolling 30 days. Only available for CPM (cost per mille (1000 impressions))  ad groups. A CPM ad group has an IMPRESSION <a href=\"/docs/redoc/#section/Billable-event\">billable_event</a> value. This field **REQUIRES** the `end_time` field.")
    name: StrictStr = Field(description="Ad group name.")
    optimization_goal_metadata: Optional[OptimizationGoalMetadata] = Field(default=None, description="Optimization goals for objective-based performance campaigns. **REQUIRED** when campaign's `objective_type` is set to `\"WEB_CONVERSION\"`.")
    pacing_delivery_type: Optional[PacingDeliveryType] = 'STANDARD'
    placement_group: Optional[PlacementGroupType] = Field(default=None, description="<a href=\"/docs/redoc/#section/Placement-group\">Placement group</a>.")
    promotion_application_level: Optional[StrictStr] = Field(default=None, description="Specify if the promotion is applied at ad group or item level")
    promotion_id: Optional[Annotated[str, Field(strict=True)]] = Field(default='0', description="Promotion ID. To clear this field, set to null.")
    start_time: Optional[StrictInt] = Field(default=None, description="Timestamp in Unix format for scheduling when ads in the ad group start to appear. If not specified, ads appear during parent campaign's `start_time`. Cannot precede `start_time` for parent campaign (if specified). Learn about <a href=\"/docs/api-features/managing-ads/#step-2-create-an-ad-group\" target=\"blank\">scheduling ads</a>. For certain organizations (<a href=\"/docs/getting-started/using-beta-and-restricted-features/\" target=\"blank\" target=\"blank\">Closed beta</a>): Supported for campaigns with Campaign Budget Optimization (CBO). For all organizations: Supported for campaigns without CBO.")
    status: Optional[EntityStatus] = Field(default=None, description="Ad group/entity status.")
    targeting_spec: Optional[TargetingSpec] = None
    targeting_template_ids: Optional[Annotated[List[Annotated[str, Field(strict=True)]], Field(max_length=1)]] = Field(default=None, description="Targeting template IDs applied to the ad group. We currently only support 1 targeting template per ad group. To use targeting templates, do not set any other targeting fields: targeting_spec, tracking_urls, auto_targeting_enabled, placement_group. To clear all targeting template IDs, set this field to ['0'].")
    tracking_urls: Optional[TrackingUrls] = Field(default=None, description="Third-party tracking URLs.<br> JSON object with the format: {\"<a href=\"/docs/redoc/#section/Tracking-URL-event\">Tracking event enum</a>\":[URL string array],...}<br> For example: {\"impression\": [\"URL1\", \"URL2\"], \"click\": [\"URL1\", \"URL2\", \"URL3\"]}.<br>Up to three tracking URLs are supported for each event type. Tracking URLs set at the ad group or ad level can override those set at the campaign level. May be null. Pass in an empty object - {} - to remove tracking URLs.<br><br> For more information, see <a href=\"https://help.pinterest.com/en/business/article/third-party-and-dynamic-tracking\" target=\"_blank\">Third-party and dynamic tracking</a>.")
    bid_multiplier: Optional[Union[Annotated[float, Field(le=10, strict=True, ge=0)], Annotated[int, Field(le=10, strict=True, ge=0)]]] = Field(default=None, description="<a href=\"/docs/getting-started/using-beta-and-restricted-features/\" target=\"blank>Open beta</a> Bid multiplier for ad group. This value is a double between 0.1 and 10.0. Enter 0 to remove the bid multiplier. - Make sure the `bid_strategy` type for your ad group is set to `AUTOMATIC_BID`. - Not currently supported for <a href=\"/docs/api-features/pinterest-performance-plus-setup/\" target=\"blank\">Pinterest Performance+ campaigns</a>.")
    __properties: ClassVar[List[str]] = ["auto_targeting_enabled", "bid_in_micro_currency", "bid_strategy_type", "billable_event", "budget_in_micro_currency", "budget_type", "campaign_id", "end_time", "is_creative_optimization", "lifetime_frequency_cap", "name", "optimization_goal_metadata", "pacing_delivery_type", "placement_group", "promotion_application_level", "promotion_id", "start_time", "status", "targeting_spec", "targeting_template_ids", "tracking_urls", "bid_multiplier"]

    @field_validator('bid_strategy_type')
    def bid_strategy_type_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['AUTOMATIC_BID', 'MAX_BID', 'TARGET_AVG']):
            raise ValueError("must be one of enum values ('AUTOMATIC_BID', 'MAX_BID', 'TARGET_AVG')")
        return value

    @field_validator('campaign_id')
    def campaign_id_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if not re.match(r"^[C]?\d+$", value):
            raise ValueError(r"must validate the regular expression /^[C]?\d+$/")
        return value

    @field_validator('promotion_application_level')
    def promotion_application_level_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in set(['NONE', 'ITEM', 'AD_GROUP']):
            raise ValueError("must be one of enum values ('NONE', 'ITEM', 'AD_GROUP')")
        return value

    @field_validator('promotion_id')
    def promotion_id_validate_regular_expression(cls, value):
        """Validates the regular expression"""
        if value is None:
            return value

        if not re.match(r"^\d+$", value):
            raise ValueError(r"must validate the regular expression /^\d+$/")
        return value

    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 AdGroupCreateRequest 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 optimization_goal_metadata
        if self.optimization_goal_metadata:
            _dict['optimization_goal_metadata'] = self.optimization_goal_metadata.to_dict()
        # override the default output from pydantic by calling `to_dict()` of targeting_spec
        if self.targeting_spec:
            _dict['targeting_spec'] = self.targeting_spec.to_dict()
        # override the default output from pydantic by calling `to_dict()` of tracking_urls
        if self.tracking_urls:
            _dict['tracking_urls'] = self.tracking_urls.to_dict()
        # set to None if bid_in_micro_currency (nullable) is None
        # and model_fields_set contains the field
        if self.bid_in_micro_currency is None and "bid_in_micro_currency" in self.model_fields_set:
            _dict['bid_in_micro_currency'] = None

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

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

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

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

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

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

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

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

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

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

        return _dict

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

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

        _obj = cls.model_validate({
            "auto_targeting_enabled": obj.get("auto_targeting_enabled"),
            "bid_in_micro_currency": obj.get("bid_in_micro_currency"),
            "bid_strategy_type": obj.get("bid_strategy_type"),
            "billable_event": obj.get("billable_event"),
            "budget_in_micro_currency": obj.get("budget_in_micro_currency"),
            "budget_type": obj.get("budget_type") if obj.get("budget_type") is not None else 'DAILY',
            "campaign_id": obj.get("campaign_id"),
            "end_time": obj.get("end_time"),
            "is_creative_optimization": obj.get("is_creative_optimization"),
            "lifetime_frequency_cap": obj.get("lifetime_frequency_cap"),
            "name": obj.get("name"),
            "optimization_goal_metadata": OptimizationGoalMetadata.from_dict(obj["optimization_goal_metadata"]) if obj.get("optimization_goal_metadata") is not None else None,
            "pacing_delivery_type": obj.get("pacing_delivery_type") if obj.get("pacing_delivery_type") is not None else 'STANDARD',
            "placement_group": obj.get("placement_group"),
            "promotion_application_level": obj.get("promotion_application_level"),
            "promotion_id": obj.get("promotion_id") if obj.get("promotion_id") is not None else '0',
            "start_time": obj.get("start_time"),
            "status": obj.get("status"),
            "targeting_spec": TargetingSpec.from_dict(obj["targeting_spec"]) if obj.get("targeting_spec") is not None else None,
            "targeting_template_ids": obj.get("targeting_template_ids"),
            "tracking_urls": TrackingUrls.from_dict(obj["tracking_urls"]) if obj.get("tracking_urls") is not None else None,
            "bid_multiplier": obj.get("bid_multiplier")
        })
        return _obj


