use serde::{Deserialize, Serialize};
/// This object represents a quiz poll.
/// # Notes
/// This object represents a poll from original poll type `quiz`.
/// # Documentation
/// <https://core.telegram.org/bots/api#poll>
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PollQuiz {
    /// Unique poll identifier
    pub id: Box<str>,
    /// Poll question, 1-300 characters
    pub question: Box<str>,
    /// Special entities that appear in the question. Currently, only custom emoji entities are allowed in poll questions
    #[serde(skip_serializing_if = "Option::is_none")]
    pub question_entities: Option<Box<[crate::types::MessageEntity]>>,
    /// List of poll options
    pub options: Box<[crate::types::PollOption]>,
    /// Total number of users that voted in the poll
    pub total_voter_count: i64,
    /// `true`, if the poll is closed
    pub is_closed: bool,
    /// `true`, if the poll is anonymous
    pub is_anonymous: bool,
    /// `true`, if the poll allows multiple answers
    pub allows_multiple_answers: bool,
    /// `true`, if the poll allows to change the chosen answer options
    pub allows_revoting: bool,
    /// `true` if voting is limited to users who have been members of the chat where the poll was originally sent for more than 24 hours
    pub members_only: bool,
    /// A list of two-letter ISO 3166-1 alpha-2 country codes indicating the countries from which users can vote in the poll. If omitted, then users from any country can participate in the poll.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub country_codes: Option<Box<[Box<str>]>>,
    /// Array of 0-based identifiers of the correct answer options. Available only for polls in quiz mode which are closed or were sent (not forwarded) by the bot or to the private chat with the bot.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub correct_option_ids: Option<Box<[i64]>>,
    /// Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters
    #[serde(skip_serializing_if = "Option::is_none")]
    pub explanation: Option<Box<str>>,
    /// Special entities like usernames, URLs, bot commands, etc. that appear in the explanation
    #[serde(skip_serializing_if = "Option::is_none")]
    pub explanation_entities: Option<Box<[crate::types::MessageEntity]>>,
    /// Media added to the quiz explanation
    #[serde(skip_serializing_if = "Option::is_none")]
    pub explanation_media: Option<crate::types::PollMedia>,
    /// Amount of time in seconds the poll will be active after creation
    #[serde(skip_serializing_if = "Option::is_none")]
    pub open_period: Option<i64>,
    /// Point in time (Unix timestamp) when the poll will be automatically closed
    #[serde(skip_serializing_if = "Option::is_none")]
    pub close_date: Option<i64>,
    /// Description of the poll; for polls inside the Message object only
    #[serde(skip_serializing_if = "Option::is_none")]
    pub description: Option<Box<str>>,
    /// Special entities like usernames, URLs, bot commands, etc. that appear in the description
    #[serde(skip_serializing_if = "Option::is_none")]
    pub description_entities: Option<Box<[crate::types::MessageEntity]>>,
    /// Media added to the poll description; for polls inside the Message object only
    #[serde(skip_serializing_if = "Option::is_none")]
    pub media: Option<crate::types::PollMedia>,
}
impl PollQuiz {
    /// Creates a new `PollQuiz`.
    ///
    /// # Arguments
    /// * `id` - Unique poll identifier
    /// * `question` - Poll question, 1-300 characters
    /// * `options` - List of poll options
    /// * `total_voter_count` - Total number of users that voted in the poll
    /// * `is_closed` - `true`, if the poll is closed
    /// * `is_anonymous` - `true`, if the poll is anonymous
    /// * `allows_multiple_answers` - `true`, if the poll allows multiple answers
    /// * `allows_revoting` - `true`, if the poll allows to change the chosen answer options
    /// * `members_only` - `true` if voting is limited to users who have been members of the chat where the poll was originally sent for more than 24 hours
    ///
    /// # Notes
    /// Use builder methods to set optional fields.
    #[must_use]
    pub fn new<
        T0: Into<Box<str>>,
        T1: Into<Box<str>>,
        T2Item: Into<crate::types::PollOption>,
        T2: IntoIterator<Item = T2Item>,
        T3: Into<i64>,
        T4: Into<bool>,
        T5: Into<bool>,
        T6: Into<bool>,
        T7: Into<bool>,
        T8: Into<bool>,
    >(
        id: T0,
        question: T1,
        options: T2,
        total_voter_count: T3,
        is_closed: T4,
        is_anonymous: T5,
        allows_multiple_answers: T6,
        allows_revoting: T7,
        members_only: T8,
    ) -> Self {
        Self {
            id: id.into(),
            question: question.into(),
            question_entities: None,
            options: options.into_iter().map(Into::into).collect(),
            total_voter_count: total_voter_count.into(),
            is_closed: is_closed.into(),
            is_anonymous: is_anonymous.into(),
            allows_multiple_answers: allows_multiple_answers.into(),
            allows_revoting: allows_revoting.into(),
            members_only: members_only.into(),
            country_codes: None,
            correct_option_ids: None,
            explanation: None,
            explanation_entities: None,
            explanation_media: None,
            open_period: None,
            close_date: None,
            description: None,
            description_entities: None,
            media: None,
        }
    }

    /// Unique poll identifier
    #[must_use]
    pub fn id<T: Into<Box<str>>>(mut self, val: T) -> Self {
        self.id = val.into();
        self
    }

    /// Poll question, 1-300 characters
    #[must_use]
    pub fn question<T: Into<Box<str>>>(mut self, val: T) -> Self {
        self.question = val.into();
        self
    }

    /// Special entities that appear in the question. Currently, only custom emoji entities are allowed in poll questions
    ///
    /// # Notes
    /// Adds multiple elements.
    #[must_use]
    pub fn question_entities<T: Into<Box<[crate::types::MessageEntity]>>>(
        mut self,
        val: T,
    ) -> Self {
        self.question_entities = Some(
            self.question_entities
                .unwrap_or_default()
                .into_vec()
                .into_iter()
                .chain(val.into())
                .collect(),
        );
        self
    }

    /// Special entities that appear in the question. Currently, only custom emoji entities are allowed in poll questions
    ///
    /// # Notes
    /// Adds a single element.
    #[must_use]
    pub fn question_entity<T: Into<crate::types::MessageEntity>>(mut self, val: T) -> Self {
        self.question_entities = Some(
            self.question_entities
                .unwrap_or_default()
                .into_vec()
                .into_iter()
                .chain(Some(val.into()))
                .collect(),
        );
        self
    }

    /// Special entities that appear in the question. Currently, only custom emoji entities are allowed in poll questions
    ///
    /// # Notes
    /// Adds a single element.
    #[must_use]
    pub fn question_entities_option<T: Into<Box<[crate::types::MessageEntity]>>>(
        mut self,
        val: Option<T>,
    ) -> Self {
        self.question_entities = val.map(Into::into);
        self
    }

    /// List of poll options
    ///
    /// # Notes
    /// Adds multiple elements.
    #[must_use]
    pub fn options<T: Into<Box<[crate::types::PollOption]>>>(mut self, val: T) -> Self {
        self.options = self
            .options
            .into_vec()
            .into_iter()
            .chain(val.into())
            .collect();
        self
    }

    /// List of poll options
    ///
    /// # Notes
    /// Adds a single element.
    #[must_use]
    pub fn option<T: Into<crate::types::PollOption>>(mut self, val: T) -> Self {
        self.options = self
            .options
            .into_vec()
            .into_iter()
            .chain(Some(val.into()))
            .collect();
        self
    }

    /// Total number of users that voted in the poll
    #[must_use]
    pub fn total_voter_count<T: Into<i64>>(mut self, val: T) -> Self {
        self.total_voter_count = val.into();
        self
    }

    /// `true`, if the poll is closed
    #[must_use]
    pub fn is_closed<T: Into<bool>>(mut self, val: T) -> Self {
        self.is_closed = val.into();
        self
    }

    /// `true`, if the poll is anonymous
    #[must_use]
    pub fn is_anonymous<T: Into<bool>>(mut self, val: T) -> Self {
        self.is_anonymous = val.into();
        self
    }

    /// `true`, if the poll allows multiple answers
    #[must_use]
    pub fn allows_multiple_answers<T: Into<bool>>(mut self, val: T) -> Self {
        self.allows_multiple_answers = val.into();
        self
    }

    /// `true`, if the poll allows to change the chosen answer options
    #[must_use]
    pub fn allows_revoting<T: Into<bool>>(mut self, val: T) -> Self {
        self.allows_revoting = val.into();
        self
    }

    /// `true` if voting is limited to users who have been members of the chat where the poll was originally sent for more than 24 hours
    #[must_use]
    pub fn members_only<T: Into<bool>>(mut self, val: T) -> Self {
        self.members_only = val.into();
        self
    }

    /// A list of two-letter ISO 3166-1 alpha-2 country codes indicating the countries from which users can vote in the poll. If omitted, then users from any country can participate in the poll.
    ///
    /// # Notes
    /// Adds multiple elements.
    #[must_use]
    pub fn country_codes<T: Into<Box<[Box<str>]>>>(mut self, val: T) -> Self {
        self.country_codes = Some(
            self.country_codes
                .unwrap_or_default()
                .into_vec()
                .into_iter()
                .chain(val.into())
                .collect(),
        );
        self
    }

    /// A list of two-letter ISO 3166-1 alpha-2 country codes indicating the countries from which users can vote in the poll. If omitted, then users from any country can participate in the poll.
    ///
    /// # Notes
    /// Adds a single element.
    #[must_use]
    pub fn country_code<T: Into<Box<str>>>(mut self, val: T) -> Self {
        self.country_codes = Some(
            self.country_codes
                .unwrap_or_default()
                .into_vec()
                .into_iter()
                .chain(Some(val.into()))
                .collect(),
        );
        self
    }

    /// A list of two-letter ISO 3166-1 alpha-2 country codes indicating the countries from which users can vote in the poll. If omitted, then users from any country can participate in the poll.
    ///
    /// # Notes
    /// Adds a single element.
    #[must_use]
    pub fn country_codes_option<T: Into<Box<[Box<str>]>>>(mut self, val: Option<T>) -> Self {
        self.country_codes = val.map(Into::into);
        self
    }

    /// Array of 0-based identifiers of the correct answer options. Available only for polls in quiz mode which are closed or were sent (not forwarded) by the bot or to the private chat with the bot.
    ///
    /// # Notes
    /// Adds multiple elements.
    #[must_use]
    pub fn correct_option_ids<T: Into<Box<[i64]>>>(mut self, val: T) -> Self {
        self.correct_option_ids = Some(
            self.correct_option_ids
                .unwrap_or_default()
                .into_vec()
                .into_iter()
                .chain(val.into())
                .collect(),
        );
        self
    }

    /// Array of 0-based identifiers of the correct answer options. Available only for polls in quiz mode which are closed or were sent (not forwarded) by the bot or to the private chat with the bot.
    ///
    /// # Notes
    /// Adds a single element.
    #[must_use]
    pub fn correct_option_id<T: Into<i64>>(mut self, val: T) -> Self {
        self.correct_option_ids = Some(
            self.correct_option_ids
                .unwrap_or_default()
                .into_vec()
                .into_iter()
                .chain(Some(val.into()))
                .collect(),
        );
        self
    }

    /// Array of 0-based identifiers of the correct answer options. Available only for polls in quiz mode which are closed or were sent (not forwarded) by the bot or to the private chat with the bot.
    ///
    /// # Notes
    /// Adds a single element.
    #[must_use]
    pub fn correct_option_ids_option<T: Into<Box<[i64]>>>(mut self, val: Option<T>) -> Self {
        self.correct_option_ids = val.map(Into::into);
        self
    }

    /// Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters
    #[must_use]
    pub fn explanation<T: Into<Box<str>>>(mut self, val: T) -> Self {
        self.explanation = Some(val.into());
        self
    }

    /// Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters
    #[must_use]
    pub fn explanation_option<T: Into<Box<str>>>(mut self, val: Option<T>) -> Self {
        self.explanation = val.map(Into::into);
        self
    }

    /// Special entities like usernames, URLs, bot commands, etc. that appear in the explanation
    ///
    /// # Notes
    /// Adds multiple elements.
    #[must_use]
    pub fn explanation_entities<T: Into<Box<[crate::types::MessageEntity]>>>(
        mut self,
        val: T,
    ) -> Self {
        self.explanation_entities = Some(
            self.explanation_entities
                .unwrap_or_default()
                .into_vec()
                .into_iter()
                .chain(val.into())
                .collect(),
        );
        self
    }

    /// Special entities like usernames, URLs, bot commands, etc. that appear in the explanation
    ///
    /// # Notes
    /// Adds a single element.
    #[must_use]
    pub fn explanation_entity<T: Into<crate::types::MessageEntity>>(mut self, val: T) -> Self {
        self.explanation_entities = Some(
            self.explanation_entities
                .unwrap_or_default()
                .into_vec()
                .into_iter()
                .chain(Some(val.into()))
                .collect(),
        );
        self
    }

    /// Special entities like usernames, URLs, bot commands, etc. that appear in the explanation
    ///
    /// # Notes
    /// Adds a single element.
    #[must_use]
    pub fn explanation_entities_option<T: Into<Box<[crate::types::MessageEntity]>>>(
        mut self,
        val: Option<T>,
    ) -> Self {
        self.explanation_entities = val.map(Into::into);
        self
    }

    /// Media added to the quiz explanation
    #[must_use]
    pub fn explanation_media<T: Into<crate::types::PollMedia>>(mut self, val: T) -> Self {
        self.explanation_media = Some(val.into());
        self
    }

    /// Media added to the quiz explanation
    #[must_use]
    pub fn explanation_media_option<T: Into<crate::types::PollMedia>>(
        mut self,
        val: Option<T>,
    ) -> Self {
        self.explanation_media = val.map(Into::into);
        self
    }

    /// Amount of time in seconds the poll will be active after creation
    #[must_use]
    pub fn open_period<T: Into<i64>>(mut self, val: T) -> Self {
        self.open_period = Some(val.into());
        self
    }

    /// Amount of time in seconds the poll will be active after creation
    #[must_use]
    pub fn open_period_option<T: Into<i64>>(mut self, val: Option<T>) -> Self {
        self.open_period = val.map(Into::into);
        self
    }

    /// Point in time (Unix timestamp) when the poll will be automatically closed
    #[must_use]
    pub fn close_date<T: Into<i64>>(mut self, val: T) -> Self {
        self.close_date = Some(val.into());
        self
    }

    /// Point in time (Unix timestamp) when the poll will be automatically closed
    #[must_use]
    pub fn close_date_option<T: Into<i64>>(mut self, val: Option<T>) -> Self {
        self.close_date = val.map(Into::into);
        self
    }

    /// Description of the poll; for polls inside the Message object only
    #[must_use]
    pub fn description<T: Into<Box<str>>>(mut self, val: T) -> Self {
        self.description = Some(val.into());
        self
    }

    /// Description of the poll; for polls inside the Message object only
    #[must_use]
    pub fn description_option<T: Into<Box<str>>>(mut self, val: Option<T>) -> Self {
        self.description = val.map(Into::into);
        self
    }

    /// Special entities like usernames, URLs, bot commands, etc. that appear in the description
    ///
    /// # Notes
    /// Adds multiple elements.
    #[must_use]
    pub fn description_entities<T: Into<Box<[crate::types::MessageEntity]>>>(
        mut self,
        val: T,
    ) -> Self {
        self.description_entities = Some(
            self.description_entities
                .unwrap_or_default()
                .into_vec()
                .into_iter()
                .chain(val.into())
                .collect(),
        );
        self
    }

    /// Special entities like usernames, URLs, bot commands, etc. that appear in the description
    ///
    /// # Notes
    /// Adds a single element.
    #[must_use]
    pub fn description_entity<T: Into<crate::types::MessageEntity>>(mut self, val: T) -> Self {
        self.description_entities = Some(
            self.description_entities
                .unwrap_or_default()
                .into_vec()
                .into_iter()
                .chain(Some(val.into()))
                .collect(),
        );
        self
    }

    /// Special entities like usernames, URLs, bot commands, etc. that appear in the description
    ///
    /// # Notes
    /// Adds a single element.
    #[must_use]
    pub fn description_entities_option<T: Into<Box<[crate::types::MessageEntity]>>>(
        mut self,
        val: Option<T>,
    ) -> Self {
        self.description_entities = val.map(Into::into);
        self
    }

    /// Media added to the poll description; for polls inside the Message object only
    #[must_use]
    pub fn media<T: Into<crate::types::PollMedia>>(mut self, val: T) -> Self {
        self.media = Some(val.into());
        self
    }

    /// Media added to the poll description; for polls inside the Message object only
    #[must_use]
    pub fn media_option<T: Into<crate::types::PollMedia>>(mut self, val: Option<T>) -> Self {
        self.media = val.map(Into::into);
        self
    }
}
