// Auto-generated by crates/tele-codegen. Do not edit manually.
use serde::Serialize;
use serde_json::Value;

use crate::Result;

use crate::types::validation::{
    positive_i64 as validate_positive_i64, string_id as validate_string_id,
};

use super::AdvancedRequest;

trait GeneratedValidate {
    fn validate_generated(&self) -> Result<()>;
}

impl GeneratedValidate for crate::types::telegram::StoryArea {
    fn validate_generated(&self) -> Result<()> {
        self.validate()
    }
}

fn validate_items<T: GeneratedValidate>(values: &[T]) -> Result<()> {
    for value in values {
        value.validate_generated()?;
    }

    Ok(())
}

/// Auto-generated request for `postStory`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedPostStoryRequest {
    pub business_connection_id: String,
    pub content: crate::types::telegram::InputStoryContent,
    pub active_period: i64,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub caption: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub parse_mode: Option<crate::types::common::ParseMode>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub caption_entities: Option<Vec<crate::types::message::MessageEntity>>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub areas: Option<Vec<crate::types::telegram::StoryArea>>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub post_to_chat_page: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub protect_content: Option<bool>,
}

impl AdvancedPostStoryRequest {
    pub fn new(
        business_connection_id: impl Into<String>,
        content: crate::types::telegram::InputStoryContent,
        active_period: i64,
    ) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            content,
            active_period,
            caption: None,
            parse_mode: None,
            caption_entities: None,
            areas: None,
            post_to_chat_page: None,
            protect_content: None,
        }
    }
}

impl AdvancedRequest for AdvancedPostStoryRequest {
    type Response = Value;
    const METHOD: &'static str = "postStory";

    fn validate(&self) -> Result<()> {
        validate_string_id("business_connection_id", &self.business_connection_id)?;
        self.content.validate()?;
        validate_positive_i64("active_period", self.active_period)?;
        if let Some(values) = self.areas.as_deref() {
            validate_items(values)?;
        }
        Ok(())
    }
}

/// Auto-generated request for `repostStory`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedRepostStoryRequest {
    pub business_connection_id: String,
    pub from_chat_id: crate::types::common::NumericChatId,
    pub from_story_id: i64,
    pub active_period: i64,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub post_to_chat_page: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub protect_content: Option<bool>,
}

impl AdvancedRepostStoryRequest {
    pub fn new(
        business_connection_id: impl Into<String>,
        from_chat_id: impl Into<crate::types::common::NumericChatId>,
        from_story_id: i64,
        active_period: i64,
    ) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            from_chat_id: from_chat_id.into(),
            from_story_id,
            active_period,
            post_to_chat_page: None,
            protect_content: None,
        }
    }
}

impl AdvancedRequest for AdvancedRepostStoryRequest {
    type Response = Value;
    const METHOD: &'static str = "repostStory";

    fn validate(&self) -> Result<()> {
        validate_string_id("business_connection_id", &self.business_connection_id)?;
        self.from_chat_id.validate()?;
        validate_positive_i64("from_story_id", self.from_story_id)?;
        validate_positive_i64("active_period", self.active_period)?;
        Ok(())
    }
}

/// Auto-generated request for `editStory`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedEditStoryRequest {
    pub business_connection_id: String,
    pub story_id: i64,
    pub content: crate::types::telegram::InputStoryContent,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub caption: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub parse_mode: Option<crate::types::common::ParseMode>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub caption_entities: Option<Vec<crate::types::message::MessageEntity>>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub areas: Option<Vec<crate::types::telegram::StoryArea>>,
}

impl AdvancedEditStoryRequest {
    pub fn new(
        business_connection_id: impl Into<String>,
        story_id: i64,
        content: crate::types::telegram::InputStoryContent,
    ) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            story_id,
            content,
            caption: None,
            parse_mode: None,
            caption_entities: None,
            areas: None,
        }
    }
}

impl AdvancedRequest for AdvancedEditStoryRequest {
    type Response = Value;
    const METHOD: &'static str = "editStory";

    fn validate(&self) -> Result<()> {
        validate_string_id("business_connection_id", &self.business_connection_id)?;
        validate_positive_i64("story_id", self.story_id)?;
        self.content.validate()?;
        if let Some(values) = self.areas.as_deref() {
            validate_items(values)?;
        }
        Ok(())
    }
}

/// Auto-generated request for `deleteStory`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedDeleteStoryRequest {
    pub business_connection_id: String,
    pub story_id: i64,
}

impl AdvancedDeleteStoryRequest {
    pub fn new(business_connection_id: impl Into<String>, story_id: i64) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            story_id,
        }
    }
}

impl AdvancedRequest for AdvancedDeleteStoryRequest {
    type Response = bool;
    const METHOD: &'static str = "deleteStory";

    fn validate(&self) -> Result<()> {
        validate_string_id("business_connection_id", &self.business_connection_id)?;
        validate_positive_i64("story_id", self.story_id)?;
        Ok(())
    }
}
