# coding: utf-8

"""
    Klaviyo API

    The Klaviyo REST API. Please visit https://developers.klaviyo.com for more details.

    Contact: developers@klaviyo.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 datetime import datetime
from pydantic import BaseModel, ConfigDict, Field, StrictFloat, StrictInt, StrictStr, field_validator
from typing import Any, ClassVar, Dict, List, Optional, Union
from typing import Optional, Set
from typing_extensions import Self

class PredictiveAnalytics(BaseModel):
    """
    PredictiveAnalytics
    """ # noqa: E501
    historic_clv: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Total value of all historically placed orders")
    predicted_clv: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Predicted value of all placed orders in the next 365 days")
    total_clv: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Sum of historic and predicted CLV")
    historic_number_of_orders: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Number of already placed orders")
    predicted_number_of_orders: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Predicted number of placed orders in the next 365 days")
    average_days_between_orders: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Average number of days between orders (None if only one order has been placed)")
    average_order_value: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Average value of placed orders")
    churn_probability: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Probability the customer has churned")
    expected_date_of_next_order: Optional[datetime] = Field(default=None, description="Expected date of next order, as calculated at the time of their most recent order")
    ranked_channel_affinity: Optional[List[StrictStr]] = Field(default=None, description="List of channels ranked by their predicted effectiveness for this profile, with the best channel being listed first at index 0")
    __properties: ClassVar[List[str]] = ["historic_clv", "predicted_clv", "total_clv", "historic_number_of_orders", "predicted_number_of_orders", "average_days_between_orders", "average_order_value", "churn_probability", "expected_date_of_next_order", "ranked_channel_affinity"]

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

        for i in value:
            if i not in set(['email', 'push', 'sms']):
                raise ValueError("each list item must be one of ('email', 'push', 'sms')")
        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 PredictiveAnalytics 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,
        )
        # set to None if historic_clv (nullable) is None
        # and model_fields_set contains the field
        if self.historic_clv is None and "historic_clv" in self.model_fields_set:
            _dict['historic_clv'] = None

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

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

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

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

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

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

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

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

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

        return _dict

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

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

        _obj = cls.model_validate({
            "historic_clv": obj.get("historic_clv"),
            "predicted_clv": obj.get("predicted_clv"),
            "total_clv": obj.get("total_clv"),
            "historic_number_of_orders": obj.get("historic_number_of_orders"),
            "predicted_number_of_orders": obj.get("predicted_number_of_orders"),
            "average_days_between_orders": obj.get("average_days_between_orders"),
            "average_order_value": obj.get("average_order_value"),
            "churn_probability": obj.get("churn_probability"),
            "expected_date_of_next_order": obj.get("expected_date_of_next_order"),
            "ranked_channel_affinity": obj.get("ranked_channel_affinity")
        })
        return _obj


