# coding: utf-8

"""
    Moodle Webservice API

    Auto-generated OpenAPI spec for Moodle's Webservice API.

    The version of the OpenAPI document: 5.0.3 (Build: 20251006)
    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, StrictFloat, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional, Union
from poodle_async_full.models.mod_quiz_get_attempt_data_response_attempt_gradeitemmarks_inner import ModQuizGetAttemptDataResponseAttemptGradeitemmarksInner
from typing import Optional, Set
from typing_extensions import Self

from poodle_async_full.configuration import settings

class ModQuizGetUserAttemptsResponseAttemptsInner(BaseModel):
    """
    ModQuizGetUserAttemptsResponseAttemptsInner
    """ # noqa: E501
    attempt: Optional[StrictInt] = Field(default=None, description="Sequentially numbers this students attempts at this quiz.")
    currentpage: Optional[StrictInt] = Field(default=None, description="Attempt current page.")
    gradednotificationsenttime: Optional[StrictInt] = Field(default=None, description="Time when the student was notified that manual grading of their attempt was complete.")
    gradeitemmarks: Optional[List[ModQuizGetAttemptDataResponseAttemptGradeitemmarksInner]] = Field(default=None, description="If the quiz has additional grades set up, the mark for each grade for this attempt.")
    id: Optional[StrictInt] = Field(default=None, description="Attempt id.")
    layout: Optional[StrictStr] = Field(default=None, description="Attempt layout.")
    preview: Optional[StrictInt] = Field(default=None, description="Whether is a preview attempt or not.")
    quiz: Optional[StrictInt] = Field(default=None, description="Foreign key reference to the quiz that was attempted.")
    state: Optional[StrictStr] = Field(default=None, description="The current state of the attempts. 'inprogress',                                                 'overdue', 'finished' or 'abandoned'. For backwards compatibility, attempts in 'submitted' state will return 'finished' and attempts in 'notstarted' state will return 'inprogress'. To get attempts with all real states, call get_user_quiz_attempts() instead.")
    sumgrades: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, description="Total marks for this attempt.")
    timecheckstate: Optional[StrictInt] = Field(default=None, description="Next time quiz cron should check attempt for                                                         state changes.  NULL means never check.")
    timefinish: Optional[StrictInt] = Field(default=None, description="Time when the attempt was submitted.                                                     0 if the attempt has not been submitted yet.")
    timemodified: Optional[StrictInt] = Field(default=None, description="Last modified time.")
    timemodifiedoffline: Optional[StrictInt] = Field(default=None, description="Last modified time via webservices.")
    timestart: Optional[StrictInt] = Field(default=None, description="Time when the attempt was started.")
    uniqueid: Optional[StrictInt] = Field(default=None, description="Foreign key reference to the question_usage that holds the                                                     details of the the question_attempts that make up this quiz                                                     attempt.")
    userid: Optional[StrictInt] = Field(default=None, description="Foreign key reference to the user whose attempt this is.")
    __properties: ClassVar[List[str]] = ["attempt", "currentpage", "gradednotificationsenttime", "gradeitemmarks", "id", "layout", "preview", "quiz", "state", "sumgrades", "timecheckstate", "timefinish", "timemodified", "timemodifiedoffline", "timestart", "uniqueid", "userid"]

    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 ModQuizGetUserAttemptsResponseAttemptsInner 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 each item in gradeitemmarks (list)
        _items = []
        if self.gradeitemmarks:
            for _item_gradeitemmarks in self.gradeitemmarks:
                if _item_gradeitemmarks:
                    _items.append(_item_gradeitemmarks.to_dict())
            _dict['gradeitemmarks'] = _items
        # set to None if attempt (nullable) is None
        # and model_fields_set contains the field
        if self.attempt is None and "attempt" in self.model_fields_set:
            _dict['attempt'] = None

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        return _dict

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

        relaxed = settings.relaxe_all_models or "ModQuizGetUserAttemptsResponseAttemptsInner" in settings.relaxed_models

        if not isinstance(obj, dict):
            return cls.model_construct(**obj) if relaxed else cls.model_validate(obj)

        data = {
            "attempt": obj.get("attempt"),
            "currentpage": obj.get("currentpage"),
            "gradednotificationsenttime": obj.get("gradednotificationsenttime"),
            "gradeitemmarks": [ModQuizGetAttemptDataResponseAttemptGradeitemmarksInner.from_dict(_item) for _item in obj["gradeitemmarks"]] if obj.get("gradeitemmarks") is not None else None,
            "id": obj.get("id"),
            "layout": obj.get("layout"),
            "preview": obj.get("preview"),
            "quiz": obj.get("quiz"),
            "state": obj.get("state"),
            "sumgrades": obj.get("sumgrades"),
            "timecheckstate": obj.get("timecheckstate"),
            "timefinish": obj.get("timefinish"),
            "timemodified": obj.get("timemodified"),
            "timemodifiedoffline": obj.get("timemodifiedoffline"),
            "timestart": obj.get("timestart"),
            "uniqueid": obj.get("uniqueid"),
            "userid": obj.get("userid")
        }
        _obj = cls.model_construct(**data) if relaxed else cls.model_validate(data)
        return _obj


