// The contents of this file are generated; do not modify them.

//! Endpoints to manage account members. Members are users that have membership within merchant accounts.
use super::common::*;
/// A member is user within specific resource identified by resource id, resource type, and associated roles.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Member {
    /// ID of the member.
    ///
    /// Example: `mem_WZsm7QTPhVrompscmPhoGTXXcrd58fr9MOhP`
    pub id: String,
    /// User's roles.
    pub roles: Vec<String>,
    /// User's permissions.
    #[deprecated(
        note = "Permissions include only legacy permissions, please use roles instead. Member access is based on roles within a given resource and the permissions these roles grant."
    )]
    pub permissions: Vec<String>,
    /// The timestamp of when the member was created.
    ///
    /// Example: `2023-01-20T15:16:17Z`
    pub created_at: crate::datetime::DateTime,
    /// The timestamp of when the member was last updated.
    ///
    /// Example: `2023-01-20T15:16:17Z`
    pub updated_at: crate::datetime::DateTime,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub user: Option<MembershipUser>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub invite: Option<Invite>,
    pub status: MembershipStatus,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub metadata: Option<Metadata>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub attributes: Option<Attributes>,
}
/// Information about the user associated with the membership.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct MembershipUser {
    /// Identifier for the End-User (also called Subject).
    ///
    /// Example: `44ca0f5b-813b-46e1-aee7-e6242010662e`
    pub id: String,
    /// End-User's preferred e-mail address. Its value MUST conform to the RFC 5322 [RFC5322] addr-spec syntax. The RP MUST NOT rely upon this value being unique, for unique identification use ID instead.
    ///
    /// Example: `example@sumup.com`
    pub email: String,
    /// True if the user has enabled MFA on login.
    ///
    /// Example: `true`
    pub mfa_on_login_enabled: bool,
    /// True if the user is a virtual user (operator).
    ///
    /// Example: `false`
    pub virtual_user: bool,
    /// True if the user is a service account.
    ///
    /// Example: `false`
    pub service_account_user: bool,
    /// Time when the user has been disabled. Applies only to virtual users (`virtual_user: true`).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub disabled_at: Option<crate::datetime::DateTime>,
    /// User's preferred name. Used for display purposes only.
    ///
    /// Example: `Test User`
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nickname: Option<String>,
    /// URL of the End-User's profile picture. This URL refers to an image file (for example, a PNG, JPEG, or GIF image file), rather than to a Web page containing an image.
    ///
    /// Constraints:
    /// - format: `uri`
    ///
    /// Example: `https://usercontent.sumup.com/44ca0f5b-813b-46e1-aee7-e6242010662e.png`
    #[serde(skip_serializing_if = "Option::is_none")]
    pub picture: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub classic: Option<MembershipUserClassic>,
}
/// Classic identifiers of the user.
#[deprecated]
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct MembershipUserClassic {
    pub user_id: i32,
}
/// Allows you to update user data of managed users.
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct UpdateBodyUser {
    /// User's preferred name. Used for display purposes only.
    ///
    /// Example: `Test User`
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nickname: Option<String>,
    /// Password of the member to add. Only used if `is_managed_user` is true.
    ///
    /// Constraints:
    /// - min length: 8
    #[serde(skip_serializing_if = "Option::is_none")]
    pub password: Option<crate::secret::Secret>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ListParams {
    /// Offset of the first member to return.
    ///
    /// Constraints:
    /// - value >= 0
    ///
    /// Example: `0`
    #[serde(skip_serializing_if = "Option::is_none")]
    pub offset: Option<i64>,
    /// Maximum number of members to return.
    ///
    /// Constraints:
    /// - value >= 1
    /// - value <= 25
    ///
    /// Example: `10`
    #[serde(skip_serializing_if = "Option::is_none")]
    pub limit: Option<i64>,
    /// Indicates to skip count query.
    ///
    /// Example: `true`
    #[serde(skip_serializing_if = "Option::is_none")]
    pub scroll: Option<bool>,
    /// Filter the returned members by email address prefix.
    ///
    /// Example: `user`
    #[serde(skip_serializing_if = "Option::is_none")]
    pub email: Option<String>,
    /// Search for a member by user id.
    ///
    /// Constraints:
    /// - format: `uuid`
    ///
    /// Example: `245b2ead-85bf-45ff-856f-311a88a5d454`
    #[serde(rename = "user.id")]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub user_id: Option<String>,
    /// Filter the returned members by the membership status.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub status: Option<MembershipStatus>,
    /// Filter the returned members by role.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub roles: Option<Vec<String>>,
}
/// Returns a list of Member objects.
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct ListResponse {
    pub items: Vec<Member>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub total_count: Option<i64>,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct CreateBody {
    /// True if the user is managed by the merchant. In this case, we'll created a virtual user with the provided password and nickname.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub is_managed_user: Option<bool>,
    /// Email address of the member to add.
    ///
    /// Constraints:
    /// - format: `email`
    pub email: String,
    /// Password of the member to add. Only used if `is_managed_user` is true. In the case of service accounts, the password is not used and can not be defined by the caller.
    ///
    /// Constraints:
    /// - min length: 8
    #[serde(skip_serializing_if = "Option::is_none")]
    pub password: Option<crate::secret::Secret>,
    /// Nickname of the member to add. Only used if `is_managed_user` is true. Used for display purposes only.
    ///
    /// Example: `Test User`
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nickname: Option<String>,
    /// List of roles to assign to the new member.
    pub roles: Vec<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub metadata: Option<Metadata>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub attributes: Option<Attributes>,
}
#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct UpdateBody {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub roles: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub metadata: Option<Metadata>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub attributes: Option<Attributes>,
    /// Allows you to update user data of managed users.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub user: Option<UpdateBodyUser>,
}
use crate::client::Client;
#[derive(Debug)]
pub enum ListErrorBody {
    NotFound(Problem),
}
#[derive(Debug)]
pub enum CreateErrorBody {
    BadRequest(Problem),
    NotFound(Problem),
    TooManyRequests(Problem),
}
#[derive(Debug)]
pub enum DeleteErrorBody {
    NotFound(Problem),
}
#[derive(Debug)]
pub enum GetErrorBody {
    NotFound(Problem),
}
#[derive(Debug)]
pub enum UpdateErrorBody {
    BadRequest(Problem),
    Forbidden(Problem),
    NotFound(Problem),
    Conflict(Problem),
}
/// Client for the Members API endpoints.
#[derive(Debug)]
pub struct MembersClient<'a> {
    client: &'a Client,
}
impl<'a> MembersClient<'a> {
    pub(crate) fn new(client: &'a Client) -> Self {
        Self { client }
    }
    /// Returns a reference to the underlying client.
    pub fn client(&self) -> &Client {
        self.client
    }
    /// List members
    ///
    /// Lists merchant members.
    ///
    /// Responses:
    /// - 200: Returns a list of Member objects.
    /// - 404: Merchant not found.
    pub async fn list(
        &self,
        merchant_code: impl Into<String>,
        params: ListParams,
    ) -> crate::error::SdkResult<ListResponse, ListErrorBody> {
        let path = format!("/v0.1/merchants/{}/members", merchant_code.into());
        let url = format!("{}{}", self.client.base_url(), path);
        let mut request = self
            .client
            .http_client()
            .get(&url)
            .header("User-Agent", crate::version::user_agent())
            .timeout(self.client.timeout());
        if let Some(authorization) = self.client.authorization() {
            request = request.header("Authorization", format!("Bearer {}", authorization));
        }
        for (header_name, header_value) in self.client.runtime_headers() {
            request = request.header(*header_name, header_value);
        }
        if let Some(ref value) = params.offset {
            request = request.query(&[("offset", value)]);
        }
        if let Some(ref value) = params.limit {
            request = request.query(&[("limit", value)]);
        }
        if let Some(ref value) = params.scroll {
            request = request.query(&[("scroll", value)]);
        }
        if let Some(ref value) = params.email {
            request = request.query(&[("email", value)]);
        }
        if let Some(ref value) = params.user_id {
            request = request.query(&[("user.id", value)]);
        }
        if let Some(ref value) = params.status {
            request = request.query(&[("status", value)]);
        }
        if let Some(ref value) = params.roles {
            request = request.query(&[("roles", value)]);
        }
        let response = request.send().await?;
        let status = response.status();
        match status {
            reqwest::StatusCode::OK => {
                let data: ListResponse = response.json().await?;
                Ok(data)
            }
            reqwest::StatusCode::NOT_FOUND => {
                let body: Problem = response.json().await?;
                Err(crate::error::SdkError::api(ListErrorBody::NotFound(body)))
            }
            _ => {
                let body_bytes = response.bytes().await?;
                let body = crate::error::UnknownApiBody::from_bytes(body_bytes.as_ref());
                Err(crate::error::SdkError::unexpected(status, body))
            }
        }
    }
    /// Create a member
    ///
    /// Create a merchant member.
    ///
    /// Responses:
    /// - 201: Returns the Member object if the creation succeeded.
    /// - 400: Invalid request.
    /// - 404: Merchant not found.
    /// - 429: Too many invitations were sent to that user and the rate limit was exceeded. The Retry-After header indicates when the client can retry.
    pub async fn create(
        &self,
        merchant_code: impl Into<String>,
        body: CreateBody,
    ) -> crate::error::SdkResult<Member, CreateErrorBody> {
        let path = format!("/v0.1/merchants/{}/members", merchant_code.into());
        let url = format!("{}{}", self.client.base_url(), path);
        let mut request = self
            .client
            .http_client()
            .post(&url)
            .header("User-Agent", crate::version::user_agent())
            .timeout(self.client.timeout())
            .json(&body);
        if let Some(authorization) = self.client.authorization() {
            request = request.header("Authorization", format!("Bearer {}", authorization));
        }
        for (header_name, header_value) in self.client.runtime_headers() {
            request = request.header(*header_name, header_value);
        }
        let response = request.send().await?;
        let status = response.status();
        match status {
            reqwest::StatusCode::CREATED => {
                let data: Member = response.json().await?;
                Ok(data)
            }
            reqwest::StatusCode::BAD_REQUEST => {
                let body: Problem = response.json().await?;
                Err(crate::error::SdkError::api(CreateErrorBody::BadRequest(
                    body,
                )))
            }
            reqwest::StatusCode::NOT_FOUND => {
                let body: Problem = response.json().await?;
                Err(crate::error::SdkError::api(CreateErrorBody::NotFound(body)))
            }
            reqwest::StatusCode::TOO_MANY_REQUESTS => {
                let body: Problem = response.json().await?;
                Err(crate::error::SdkError::api(
                    CreateErrorBody::TooManyRequests(body),
                ))
            }
            _ => {
                let body_bytes = response.bytes().await?;
                let body = crate::error::UnknownApiBody::from_bytes(body_bytes.as_ref());
                Err(crate::error::SdkError::unexpected(status, body))
            }
        }
    }
    /// Delete a member
    ///
    /// Deletes a merchant member.
    ///
    /// Responses:
    /// - 200: Returns an empty response if the deletion succeeded.
    /// - 404: Merchant or member not found.
    pub async fn delete(
        &self,
        merchant_code: impl Into<String>,
        member_id: impl Into<String>,
    ) -> crate::error::SdkResult<(), DeleteErrorBody> {
        let path = format!(
            "/v0.1/merchants/{}/members/{}",
            merchant_code.into(),
            member_id.into()
        );
        let url = format!("{}{}", self.client.base_url(), path);
        let mut request = self
            .client
            .http_client()
            .delete(&url)
            .header("User-Agent", crate::version::user_agent())
            .timeout(self.client.timeout());
        if let Some(authorization) = self.client.authorization() {
            request = request.header("Authorization", format!("Bearer {}", authorization));
        }
        for (header_name, header_value) in self.client.runtime_headers() {
            request = request.header(*header_name, header_value);
        }
        let response = request.send().await?;
        let status = response.status();
        match status {
            reqwest::StatusCode::OK => Ok(()),
            reqwest::StatusCode::NOT_FOUND => {
                let body: Problem = response.json().await?;
                Err(crate::error::SdkError::api(DeleteErrorBody::NotFound(body)))
            }
            _ => {
                let body_bytes = response.bytes().await?;
                let body = crate::error::UnknownApiBody::from_bytes(body_bytes.as_ref());
                Err(crate::error::SdkError::unexpected(status, body))
            }
        }
    }
    /// Retrieve a member
    ///
    /// Retrieve a merchant member.
    ///
    /// Responses:
    /// - 200: Returns the Member object for a valid identifier.
    /// - 404: Merchant or member not found.
    pub async fn get(
        &self,
        merchant_code: impl Into<String>,
        member_id: impl Into<String>,
    ) -> crate::error::SdkResult<Member, GetErrorBody> {
        let path = format!(
            "/v0.1/merchants/{}/members/{}",
            merchant_code.into(),
            member_id.into()
        );
        let url = format!("{}{}", self.client.base_url(), path);
        let mut request = self
            .client
            .http_client()
            .get(&url)
            .header("User-Agent", crate::version::user_agent())
            .timeout(self.client.timeout());
        if let Some(authorization) = self.client.authorization() {
            request = request.header("Authorization", format!("Bearer {}", authorization));
        }
        for (header_name, header_value) in self.client.runtime_headers() {
            request = request.header(*header_name, header_value);
        }
        let response = request.send().await?;
        let status = response.status();
        match status {
            reqwest::StatusCode::OK => {
                let data: Member = response.json().await?;
                Ok(data)
            }
            reqwest::StatusCode::NOT_FOUND => {
                let body: Problem = response.json().await?;
                Err(crate::error::SdkError::api(GetErrorBody::NotFound(body)))
            }
            _ => {
                let body_bytes = response.bytes().await?;
                let body = crate::error::UnknownApiBody::from_bytes(body_bytes.as_ref());
                Err(crate::error::SdkError::unexpected(status, body))
            }
        }
    }
    /// Update a member
    ///
    /// Update the merchant member.
    ///
    /// Responses:
    /// - 200: Returns the updated Member object if the update succeeded.
    /// - 400: Cannot set password or nickname for an invited user.
    /// - 403: Cannot change password for managed user. Password was already used before.
    /// - 404: Merchant or member not found.
    /// - 409: Cannot update member as some data conflict with existing members.
    pub async fn update(
        &self,
        merchant_code: impl Into<String>,
        member_id: impl Into<String>,
        body: UpdateBody,
    ) -> crate::error::SdkResult<Member, UpdateErrorBody> {
        let path = format!(
            "/v0.1/merchants/{}/members/{}",
            merchant_code.into(),
            member_id.into()
        );
        let url = format!("{}{}", self.client.base_url(), path);
        let mut request = self
            .client
            .http_client()
            .put(&url)
            .header("User-Agent", crate::version::user_agent())
            .timeout(self.client.timeout())
            .json(&body);
        if let Some(authorization) = self.client.authorization() {
            request = request.header("Authorization", format!("Bearer {}", authorization));
        }
        for (header_name, header_value) in self.client.runtime_headers() {
            request = request.header(*header_name, header_value);
        }
        let response = request.send().await?;
        let status = response.status();
        match status {
            reqwest::StatusCode::OK => {
                let data: Member = response.json().await?;
                Ok(data)
            }
            reqwest::StatusCode::BAD_REQUEST => {
                let body: Problem = response.json().await?;
                Err(crate::error::SdkError::api(UpdateErrorBody::BadRequest(
                    body,
                )))
            }
            reqwest::StatusCode::FORBIDDEN => {
                let body: Problem = response.json().await?;
                Err(crate::error::SdkError::api(UpdateErrorBody::Forbidden(
                    body,
                )))
            }
            reqwest::StatusCode::NOT_FOUND => {
                let body: Problem = response.json().await?;
                Err(crate::error::SdkError::api(UpdateErrorBody::NotFound(body)))
            }
            reqwest::StatusCode::CONFLICT => {
                let body: Problem = response.json().await?;
                Err(crate::error::SdkError::api(UpdateErrorBody::Conflict(body)))
            }
            _ => {
                let body_bytes = response.bytes().await?;
                let body = crate::error::UnknownApiBody::from_bytes(body_bytes.as_ref());
                Err(crate::error::SdkError::unexpected(status, body))
            }
        }
    }
}
