use reqwest::Method;
use crate::error::Result;
use crate::http::{push_opt, Envelope, HttpClient, Query};
use crate::models::{
Account, AccountAnalyticsHistory, AccountCreated, AccountDetail, AccountHealth,
AccountsHealthSummary, Community, CommunitySearchResult, CreateAccount, CredentialCheck,
Message, PrimaryToggled, TokenRefreshed,
};
#[derive(Debug, Clone)]
pub struct Accounts<'a> {
pub(crate) http: &'a HttpClient,
}
impl Accounts<'_> {
pub async fn list(&self, workspace_id: Option<&str>) -> Result<Vec<Account>> {
let mut query: Query = Vec::new();
push_opt(&mut query, "workspaceId", workspace_id);
let body: Envelope<Vec<Account>> = self
.http
.send::<_, ()>(Method::GET, "/accounts", Some(query), None)
.await?;
Ok(body.data)
}
pub async fn get(&self, id: &str) -> Result<AccountDetail> {
let body: Envelope<AccountDetail> = self
.http
.send::<_, ()>(Method::GET, &format!("/accounts/{id}"), None, None)
.await?;
Ok(body.data)
}
pub async fn create(&self, account: &CreateAccount) -> Result<AccountCreated> {
let body: Envelope<AccountCreated> = self
.http
.send(Method::POST, "/accounts", None, Some(account))
.await?;
Ok(body.data)
}
pub async fn delete(&self, id: &str) -> Result<Message> {
self.http
.send::<Message, ()>(Method::DELETE, &format!("/accounts/{id}"), None, None)
.await
}
pub async fn toggle_primary(&self, id: &str) -> Result<PrimaryToggled> {
let body: Envelope<PrimaryToggled> = self
.http
.send::<_, ()>(Method::POST, &format!("/accounts/{id}/primary"), None, None)
.await?;
Ok(body.data)
}
pub async fn validate(&self, id: &str) -> Result<CredentialCheck> {
let body: Envelope<CredentialCheck> = self
.http
.send::<_, ()>(
Method::POST,
&format!("/accounts/{id}/validate"),
None,
None,
)
.await?;
Ok(body.data)
}
pub async fn health(&self, id: &str, refresh: bool) -> Result<AccountHealth> {
let mut query: Query = Vec::new();
if refresh {
query.push(("refresh", "true".into()));
}
let body: Envelope<AccountHealth> = self
.http
.send::<_, ()>(
Method::GET,
&format!("/accounts/{id}/health"),
Some(query),
None,
)
.await?;
Ok(body.data)
}
pub async fn health_summary(
&self,
workspace_id: Option<&str>,
) -> Result<AccountsHealthSummary> {
let mut query: Query = Vec::new();
push_opt(&mut query, "workspaceId", workspace_id);
let body: Envelope<AccountsHealthSummary> = self
.http
.send::<_, ()>(Method::GET, "/accounts/health", Some(query), None)
.await?;
Ok(body.data)
}
pub async fn refresh_token(&self, id: &str) -> Result<TokenRefreshed> {
let body: Envelope<TokenRefreshed> = self
.http
.send::<_, ()>(
Method::POST,
&format!("/accounts/{id}/refresh-token"),
None,
None,
)
.await?;
Ok(body.data)
}
pub async fn analytics(&self, id: &str, limit: Option<u32>) -> Result<AccountAnalyticsHistory> {
let mut query: Query = Vec::new();
push_opt(&mut query, "limit", limit);
let body: Envelope<AccountAnalyticsHistory> = self
.http
.send::<_, ()>(
Method::GET,
&format!("/accounts/{id}/analytics"),
Some(query),
None,
)
.await?;
Ok(body.data)
}
pub async fn communities(&self, account_id: &str) -> Result<Vec<Community>> {
let body: Envelope<Vec<Community>> = self
.http
.send::<_, ()>(
Method::GET,
&format!("/accounts/{account_id}/communities"),
None,
None,
)
.await?;
Ok(body.data)
}
pub async fn sync_communities(&self, account_id: &str) -> Result<Vec<Community>> {
let body: Envelope<Vec<Community>> = self
.http
.send::<_, ()>(
Method::POST,
&format!("/accounts/{account_id}/communities/sync"),
None,
None,
)
.await?;
Ok(body.data)
}
pub async fn search_communities(
&self,
account_id: &str,
query: &str,
) -> Result<Vec<CommunitySearchResult>> {
let params: Query = vec![("q", query.to_string())];
let body: Envelope<Vec<CommunitySearchResult>> = self
.http
.send::<_, ()>(
Method::GET,
&format!("/accounts/{account_id}/communities/search"),
Some(params),
None,
)
.await?;
Ok(body.data)
}
pub async fn add_community(
&self,
account_id: &str,
community_id: &str,
name: Option<&str>,
) -> Result<Community> {
let payload = serde_json::json!({ "communityId": community_id, "name": name });
let body: Envelope<Community> = self
.http
.send(
Method::POST,
&format!("/accounts/{account_id}/communities/manual"),
None,
Some(&payload),
)
.await?;
Ok(body.data)
}
pub async fn remove_community(&self, account_id: &str, community_id: i64) -> Result<bool> {
#[derive(serde::Deserialize)]
struct Removed {
success: bool,
}
let body: Removed = self
.http
.send::<_, ()>(
Method::DELETE,
&format!("/accounts/{account_id}/communities/{community_id}"),
None,
None,
)
.await?;
Ok(body.success)
}
}