use crate::client::EuroMail;
use crate::errors::EuroMailError;
use crate::types::{
    AddContactParams, BulkAddContactsParams, BulkAddContactsResponse, Contact, ContactList,
    CreateContactListParams, ListContactsParams, PaginatedResponse, UpdateContactListParams,
};

impl EuroMail {
    pub async fn create_contact_list(
        &self,
        params: &CreateContactListParams,
    ) -> Result<ContactList, EuroMailError> {
        self.post("/v1/contact-lists", params).await
    }

    pub async fn get_contact_list(&self, list_id: &str) -> Result<ContactList, EuroMailError> {
        self.get(&format!("/v1/contact-lists/{list_id}")).await
    }

    pub async fn update_contact_list(
        &self,
        list_id: &str,
        params: &UpdateContactListParams,
    ) -> Result<ContactList, EuroMailError> {
        self.put(&format!("/v1/contact-lists/{list_id}"), params)
            .await
    }

    pub async fn delete_contact_list(&self, list_id: &str) -> Result<(), EuroMailError> {
        self.delete(&format!("/v1/contact-lists/{list_id}")).await
    }

    pub async fn list_contact_lists(&self) -> Result<Vec<ContactList>, EuroMailError> {
        self.get_direct::<Vec<ContactList>>("/v1/contact-lists").await
    }

    pub async fn add_contact(
        &self,
        list_id: &str,
        params: &AddContactParams,
    ) -> Result<Contact, EuroMailError> {
        self.post(
            &format!("/v1/contact-lists/{list_id}/contacts"),
            params,
        )
        .await
    }

    pub async fn bulk_add_contacts(
        &self,
        list_id: &str,
        params: &BulkAddContactsParams,
    ) -> Result<BulkAddContactsResponse, EuroMailError> {
        self.post_direct(
            &format!("/v1/contact-lists/{list_id}/contacts/bulk"),
            params,
        )
        .await
    }

    pub async fn list_contacts(
        &self,
        list_id: &str,
        params: Option<&ListContactsParams>,
    ) -> Result<PaginatedResponse<Contact>, EuroMailError> {
        let mut query: Vec<(&str, String)> = Vec::new();
        if let Some(p) = params {
            if let Some(page) = p.page {
                query.push(("page", page.to_string()));
            }
            if let Some(per_page) = p.per_page {
                query.push(("per_page", per_page.to_string()));
            }
            if let Some(ref status) = p.status {
                query.push(("status", status.clone()));
            }
        }
        self.get_with_query(
            &format!("/v1/contact-lists/{list_id}/contacts"),
            &query,
        )
        .await
    }

    pub async fn remove_contact(
        &self,
        list_id: &str,
        contact_id: &str,
    ) -> Result<(), EuroMailError> {
        self.delete(&format!(
            "/v1/contact-lists/{list_id}/contacts/{contact_id}"
        ))
        .await
    }
}
