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

use crate::{Error, Result};

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

use super::AdvancedRequest;

fn validate_message_ids(values: &[crate::types::common::MessageId]) -> Result<()> {
    for value in values {
        value.validate()?;
    }

    Ok(())
}

fn validate_required_message_ids(
    field: &str,
    values: &[crate::types::common::MessageId],
) -> Result<()> {
    if values.is_empty() {
        return Err(Error::InvalidRequest {
            reason: format!("{field} cannot be empty"),
        });
    }

    validate_message_ids(values)
}

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

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

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

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

/// Auto-generated request for `readBusinessMessage`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedReadBusinessMessageRequest {
    pub business_connection_id: String,
    pub chat_id: crate::types::common::NumericChatId,
    pub message_id: crate::types::common::MessageId,
}

impl AdvancedReadBusinessMessageRequest {
    pub fn new(
        business_connection_id: impl Into<String>,
        chat_id: impl Into<crate::types::common::NumericChatId>,
        message_id: crate::types::common::MessageId,
    ) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            chat_id: chat_id.into(),
            message_id,
        }
    }
}

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

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

/// Auto-generated request for `deleteBusinessMessages`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedDeleteBusinessMessagesRequest {
    pub business_connection_id: String,
    pub message_ids: Vec<crate::types::common::MessageId>,
}

impl AdvancedDeleteBusinessMessagesRequest {
    pub fn new(
        business_connection_id: impl Into<String>,
        message_ids: Vec<crate::types::common::MessageId>,
    ) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            message_ids,
        }
    }
}

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

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

/// Auto-generated request for `setBusinessAccountName`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedSetBusinessAccountNameRequest {
    pub business_connection_id: String,
    pub first_name: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub last_name: Option<String>,
}

impl AdvancedSetBusinessAccountNameRequest {
    pub fn new(business_connection_id: impl Into<String>, first_name: impl Into<String>) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            first_name: first_name.into(),
            last_name: None,
        }
    }
}

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

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

/// Auto-generated request for `setBusinessAccountUsername`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedSetBusinessAccountUsernameRequest {
    pub business_connection_id: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub username: Option<String>,
}

impl AdvancedSetBusinessAccountUsernameRequest {
    pub fn new(business_connection_id: impl Into<String>) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            username: None,
        }
    }
}

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

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

/// Auto-generated request for `setBusinessAccountBio`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedSetBusinessAccountBioRequest {
    pub business_connection_id: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub bio: Option<String>,
}

impl AdvancedSetBusinessAccountBioRequest {
    pub fn new(business_connection_id: impl Into<String>) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            bio: None,
        }
    }
}

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

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

/// Auto-generated request for `setBusinessAccountProfilePhoto`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedSetBusinessAccountProfilePhotoRequest {
    pub business_connection_id: String,
    pub photo: crate::types::telegram::InputProfilePhoto,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub is_public: Option<bool>,
}

impl AdvancedSetBusinessAccountProfilePhotoRequest {
    pub fn new(
        business_connection_id: impl Into<String>,
        photo: crate::types::telegram::InputProfilePhoto,
    ) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            photo,
            is_public: None,
        }
    }
}

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

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

/// Auto-generated request for `removeBusinessAccountProfilePhoto`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedRemoveBusinessAccountProfilePhotoRequest {
    pub business_connection_id: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub is_public: Option<bool>,
}

impl AdvancedRemoveBusinessAccountProfilePhotoRequest {
    pub fn new(business_connection_id: impl Into<String>) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            is_public: None,
        }
    }
}

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

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

/// Auto-generated request for `setBusinessAccountGiftSettings`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedSetBusinessAccountGiftSettingsRequest {
    pub business_connection_id: String,
    pub show_gift_button: bool,
    pub accepted_gift_types: crate::types::telegram::AcceptedGiftTypes,
}

impl AdvancedSetBusinessAccountGiftSettingsRequest {
    pub fn new(
        business_connection_id: impl Into<String>,
        show_gift_button: bool,
        accepted_gift_types: crate::types::telegram::AcceptedGiftTypes,
    ) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            show_gift_button,
            accepted_gift_types,
        }
    }
}

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

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

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

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

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

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

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

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

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

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

/// Auto-generated request for `getBusinessAccountGifts`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedGetBusinessAccountGiftsRequest {
    pub business_connection_id: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub exclude_unsaved: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub exclude_saved: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub exclude_unlimited: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub exclude_limited_upgradable: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub exclude_limited_non_upgradable: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub exclude_unique: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub exclude_from_blockchain: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub sort_by_price: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub offset: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub limit: Option<i64>,
}

impl AdvancedGetBusinessAccountGiftsRequest {
    pub fn new(business_connection_id: impl Into<String>) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            exclude_unsaved: None,
            exclude_saved: None,
            exclude_unlimited: None,
            exclude_limited_upgradable: None,
            exclude_limited_non_upgradable: None,
            exclude_unique: None,
            exclude_from_blockchain: None,
            sort_by_price: None,
            offset: None,
            limit: None,
        }
    }
}

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

    fn validate(&self) -> Result<()> {
        validate_string_id("business_connection_id", &self.business_connection_id)?;
        if let Some(value) = self.limit {
            validate_positive_i64("limit", value)?;
        }
        Ok(())
    }
}
