# coding: utf-8

"""
    Elastic Email REST API

    This API is based on the REST API architecture, allowing the user to easily manage their data with this resource-based approach.    Every API call is established on which specific request type (GET, POST, PUT, DELETE) will be used.    The API has a limit of 20 concurrent connections and a hard timeout of 600 seconds per request.    To start using this API, you will need your Access Token (available <a target=\"_blank\" href=\"https://app.elasticemail.com/marketing/settings/new/manage-api\">here</a>). Remember to keep it safe. Required access levels are listed in the given request’s description.    Downloadable library clients can be found in our Github repository <a target=\"_blank\" href=\"https://github.com/ElasticEmail?tab=repositories&q=%22rest+api%22+in%3Areadme\">here</a>

    The version of the OpenAPI document: 4.0.0
    Contact: support@elasticemail.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, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from ElasticEmail.models.log_job_status import LogJobStatus
from ElasticEmail.models.message_category_enum import MessageCategoryEnum
from typing import Optional, Set
from typing_extensions import Self

class EmailStatus(BaseModel):
    """
    Status information of the specified email
    """ # noqa: E501
    var_from: Optional[StrictStr] = Field(default=None, description="Email address this email was sent from.", alias="From")
    to: Optional[StrictStr] = Field(default=None, description="Email address this email was sent to.", alias="To")
    var_date: Optional[datetime] = Field(default=None, description="Date the email was submitted.", alias="Date")
    status: Optional[LogJobStatus] = Field(default=None, alias="Status")
    status_name: Optional[StrictStr] = Field(default=None, description="Name of email's status", alias="StatusName")
    status_change_date: Optional[datetime] = Field(default=None, description="Date of last status change.", alias="StatusChangeDate")
    date_sent: Optional[datetime] = Field(default=None, description="Date when the email was sent", alias="DateSent")
    date_opened: Optional[datetime] = Field(default=None, description="Date when the email changed the status to 'opened'", alias="DateOpened")
    date_clicked: Optional[datetime] = Field(default=None, description="Date when the email changed the status to 'clicked'", alias="DateClicked")
    error_message: Optional[StrictStr] = Field(default=None, description="Detailed error or bounced message.", alias="ErrorMessage")
    transaction_id: Optional[StrictStr] = Field(default=None, description="ID number of transaction", alias="TransactionID")
    envelope_from: Optional[StrictStr] = Field(default=None, description="Envelope from address", alias="EnvelopeFrom")
    error_category: Optional[MessageCategoryEnum] = Field(default=None, alias="ErrorCategory")
    __properties: ClassVar[List[str]] = ["From", "To", "Date", "Status", "StatusName", "StatusChangeDate", "DateSent", "DateOpened", "DateClicked", "ErrorMessage", "TransactionID", "EnvelopeFrom", "ErrorCategory"]

    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 EmailStatus 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 date_opened (nullable) is None
        # and model_fields_set contains the field
        if self.date_opened is None and "date_opened" in self.model_fields_set:
            _dict['DateOpened'] = None

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

        return _dict

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

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

        _obj = cls.model_validate({
            "From": obj.get("From"),
            "To": obj.get("To"),
            "Date": obj.get("Date"),
            "Status": obj.get("Status"),
            "StatusName": obj.get("StatusName"),
            "StatusChangeDate": obj.get("StatusChangeDate"),
            "DateSent": obj.get("DateSent"),
            "DateOpened": obj.get("DateOpened"),
            "DateClicked": obj.get("DateClicked"),
            "ErrorMessage": obj.get("ErrorMessage"),
            "TransactionID": obj.get("TransactionID"),
            "EnvelopeFrom": obj.get("EnvelopeFrom"),
            "ErrorCategory": obj.get("ErrorCategory")
        })
        return _obj


