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

use crate::Result;

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

use super::AdvancedRequest;

/// Auto-generated request for `getAvailableGifts`.
#[derive(Clone, Debug, Default, Serialize)]
pub struct AdvancedGetAvailableGiftsRequest {}

impl AdvancedGetAvailableGiftsRequest {
    pub fn new() -> Self {
        Self {}
    }
}

impl AdvancedRequest for AdvancedGetAvailableGiftsRequest {
    type Response = Value;
    const METHOD: &'static str = "getAvailableGifts";
}

/// Auto-generated request for `sendGift`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedSendGiftRequest {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub user_id: Option<crate::types::common::UserId>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub chat_id: Option<crate::types::common::ChatId>,
    pub gift_id: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub pay_for_upgrade: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub text: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub text_parse_mode: Option<crate::types::common::ParseMode>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub text_entities: Option<Vec<crate::types::message::MessageEntity>>,
}

impl AdvancedSendGiftRequest {
    pub fn new(gift_id: impl Into<String>) -> Self {
        Self {
            user_id: None,
            chat_id: None,
            gift_id: gift_id.into(),
            pay_for_upgrade: None,
            text: None,
            text_parse_mode: None,
            text_entities: None,
        }
    }
}

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

    fn validate(&self) -> Result<()> {
        if let Some(value) = self.user_id.as_ref() {
            value.validate()?;
        }
        if let Some(value) = self.chat_id.as_ref() {
            value.validate()?;
        }
        validate_string_id("gift_id", &self.gift_id)?;
        Ok(())
    }
}

/// Auto-generated request for `giftPremiumSubscription`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedGiftPremiumSubscriptionRequest {
    pub user_id: crate::types::common::UserId,
    pub month_count: i64,
    pub star_count: i64,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub text: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub text_parse_mode: Option<crate::types::common::ParseMode>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub text_entities: Option<Vec<crate::types::message::MessageEntity>>,
}

impl AdvancedGiftPremiumSubscriptionRequest {
    pub fn new(user_id: crate::types::common::UserId, month_count: i64, star_count: i64) -> Self {
        Self {
            user_id,
            month_count,
            star_count,
            text: None,
            text_parse_mode: None,
            text_entities: None,
        }
    }
}

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

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

/// Auto-generated request for `getUserGifts`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedGetUserGiftsRequest {
    pub user_id: crate::types::common::UserId,
    #[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_from_blockchain: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub exclude_unique: 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 AdvancedGetUserGiftsRequest {
    pub fn new(user_id: crate::types::common::UserId) -> Self {
        Self {
            user_id,
            exclude_unlimited: None,
            exclude_limited_upgradable: None,
            exclude_limited_non_upgradable: None,
            exclude_from_blockchain: None,
            exclude_unique: None,
            sort_by_price: None,
            offset: None,
            limit: None,
        }
    }
}

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

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

/// Auto-generated request for `getChatGifts`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedGetChatGiftsRequest {
    pub chat_id: crate::types::common::ChatId,
    #[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_from_blockchain: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub exclude_unique: 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 AdvancedGetChatGiftsRequest {
    pub fn new(chat_id: impl Into<crate::types::common::ChatId>) -> Self {
        Self {
            chat_id: chat_id.into(),
            exclude_unsaved: None,
            exclude_saved: None,
            exclude_unlimited: None,
            exclude_limited_upgradable: None,
            exclude_limited_non_upgradable: None,
            exclude_from_blockchain: None,
            exclude_unique: None,
            sort_by_price: None,
            offset: None,
            limit: None,
        }
    }
}

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

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

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

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

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

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

/// Auto-generated request for `upgradeGift`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedUpgradeGiftRequest {
    pub business_connection_id: String,
    pub owned_gift_id: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub keep_original_details: Option<bool>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub star_count: Option<i64>,
}

impl AdvancedUpgradeGiftRequest {
    pub fn new(
        business_connection_id: impl Into<String>,
        owned_gift_id: impl Into<String>,
    ) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            owned_gift_id: owned_gift_id.into(),
            keep_original_details: None,
            star_count: None,
        }
    }
}

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

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

/// Auto-generated request for `transferGift`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedTransferGiftRequest {
    pub business_connection_id: String,
    pub owned_gift_id: String,
    pub new_owner_chat_id: crate::types::common::NumericChatId,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub star_count: Option<i64>,
}

impl AdvancedTransferGiftRequest {
    pub fn new(
        business_connection_id: impl Into<String>,
        owned_gift_id: impl Into<String>,
        new_owner_chat_id: impl Into<crate::types::common::NumericChatId>,
    ) -> Self {
        Self {
            business_connection_id: business_connection_id.into(),
            owned_gift_id: owned_gift_id.into(),
            new_owner_chat_id: new_owner_chat_id.into(),
            star_count: None,
        }
    }
}

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

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

/// Auto-generated request for `getMyStarBalance`.
#[derive(Clone, Debug, Default, Serialize)]
pub struct AdvancedGetMyStarBalanceRequest {}

impl AdvancedGetMyStarBalanceRequest {
    pub fn new() -> Self {
        Self {}
    }
}

impl AdvancedRequest for AdvancedGetMyStarBalanceRequest {
    type Response = Value;
    const METHOD: &'static str = "getMyStarBalance";
}

/// Auto-generated request for `getStarTransactions`.
#[derive(Clone, Debug, Default, Serialize)]
pub struct AdvancedGetStarTransactionsRequest {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub offset: Option<i64>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub limit: Option<i64>,
}

impl AdvancedGetStarTransactionsRequest {
    pub fn new() -> Self {
        Self::default()
    }
}

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

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

/// Auto-generated request for `refundStarPayment`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedRefundStarPaymentRequest {
    pub user_id: crate::types::common::UserId,
    pub telegram_payment_charge_id: String,
}

impl AdvancedRefundStarPaymentRequest {
    pub fn new(
        user_id: crate::types::common::UserId,
        telegram_payment_charge_id: impl Into<String>,
    ) -> Self {
        Self {
            user_id,
            telegram_payment_charge_id: telegram_payment_charge_id.into(),
        }
    }
}

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

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

/// Auto-generated request for `editUserStarSubscription`.
#[derive(Clone, Debug, Serialize)]
pub struct AdvancedEditUserStarSubscriptionRequest {
    pub user_id: crate::types::common::UserId,
    pub telegram_payment_charge_id: String,
    pub is_canceled: bool,
}

impl AdvancedEditUserStarSubscriptionRequest {
    pub fn new(
        user_id: crate::types::common::UserId,
        telegram_payment_charge_id: impl Into<String>,
        is_canceled: bool,
    ) -> Self {
        Self {
            user_id,
            telegram_payment_charge_id: telegram_payment_charge_id.into(),
            is_canceled,
        }
    }
}

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

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