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

/// Builder for the `/api/v2/user/{id}/chapters` endpoint.
pub struct GetUserChaptersBuilder<'a> {
    md_client: &'a MangaDexV2,
    id: Option<UserId>,
    me: bool,
    page: Option<u32>,
    limit: Option<u32>,
}

impl<'a> GetUserChaptersBuilder<'a> {
    pub fn new(md_client: &'a MangaDexV2) -> Self {
        Self {
            md_client,
            id: None,
            me: false,
            page: None,
            limit: None,
        }
    }

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

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

    /// Set the current page of the paginated results.
    ///
    /// Default returns all chapters without pagination.
    pub fn page(&mut self, page: u32) -> &mut Self {
        self.page = Some(page);
        self
    }

    /// Set the limit of the paginated results.
    ///
    /// - **Minimum**: 10
    /// - **Maximum**: 100
    /// - **Default**: 100
    pub fn limit(&mut self, limit: u32) -> &mut Self {
        self.limit = Some(limit);
        self
    }

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

        let mut params = Vec::new();
        if let Some(page) = self.page {
            params.push(("p", page));
        }
        if let Some(limit) = self.limit {
            params.push(("limit", limit));
        }

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