use crate::constants::USER_ME;
use crate::types::UserId;
use crate::v2::builder::UserRequestError;
use crate::v2::responses::UserMangaRatingsResponseType;
use crate::v2::MangaDexV2;
use crate::MangaDexClient;

/// Builder for the `/api/v2/user/{id}/ratings` endpoint.
pub struct GetUserMangaRatingsBuilder<'a> {
    md_client: &'a MangaDexV2,
    user_id: Option<UserId>,
    me: bool,
}

impl<'a> GetUserMangaRatingsBuilder<'a> {
    pub fn new(md_client: &'a MangaDexV2) -> Self {
        Self {
            md_client,
            user_id: None,
            me: false,
        }
    }

    /// Set the numeric user ID.
    ///
    /// This takes priority over the `me` field if both are set.
    pub fn user_id(&mut self, user_id: UserId) -> &mut Self {
        self.user_id = Some(user_id);
        self
    }

    /// Set `true` to use the current cookie-authenticated user.
    pub fn me(&mut self, me: bool) -> &mut Self {
        self.me = me;
        self
    }

    pub async fn send(&self) -> Result<UserMangaRatingsResponseType, UserRequestError> {
        let user_id = if let Some(user_id) = self.user_id {
            user_id.to_string()
        } else if self.me {
            String::from(USER_ME)
        } else {
            return Err(UserRequestError::IDNotProvidedError);
        };

        Ok(self
            .md_client
            .client()
            .get(&format!(
                "{base_url}/user/{user_id}/ratings",
                base_url = self.md_client.api_url(),
                user_id = user_id
            ))
            .send()
            .await?
            .json::<UserMangaRatingsResponseType>()
            .await?)
    }
}
