//! Builder for SDK configuration.

use super::{CacheConfig, PollingConfig, RetryPolicy, SDKConfig};
use crate::error::LastIDError;

/// Builder for `SDKConfig`.
#[derive(Debug, Clone, Default)]
pub struct SDKConfigBuilder {
    pub(crate) config: SDKConfig,
}

impl SDKConfigBuilder {
    /// Create a new configuration builder.
    #[must_use]
    pub fn new() -> Self {
        Self::default()
    }

    /// Set the IDP endpoint.
    #[must_use]
    pub fn idp_endpoint(mut self, endpoint: impl Into<String>) -> Self {
        self.config.idp_endpoint = endpoint.into();
        self
    }

    /// Set the OAuth client ID for authentication.
    #[must_use]
    pub fn client_id(mut self, client_id: impl Into<String>) -> Self {
        self.config.client_id = client_id.into();
        self
    }

    /// Set the trust registry endpoint.
    #[must_use]
    pub fn trust_registry_endpoint(mut self, endpoint: impl Into<String>) -> Self {
        self.config.trust_registry_endpoint = Some(endpoint.into());
        self
    }

    /// Set the HTTP timeout in seconds.
    #[must_use]
    pub const fn timeout_seconds(mut self, seconds: u64) -> Self {
        self.config.timeout_seconds = seconds;
        self
    }

    /// Set the polling configuration.
    #[must_use]
    pub const fn polling(mut self, polling: PollingConfig) -> Self {
        self.config.polling = polling;
        self
    }

    /// Set the retry policy.
    #[must_use]
    pub const fn retry(mut self, retry: RetryPolicy) -> Self {
        self.config.retry = retry;
        self
    }

    /// Set the cache configuration.
    #[must_use]
    pub const fn cache(mut self, cache: CacheConfig) -> Self {
        self.config.cache = cache;
        self
    }

    // Convenience methods for common settings

    /// Set the maximum retry attempts.
    #[must_use]
    pub const fn retry_max_attempts(mut self, attempts: u32) -> Self {
        self.config.retry.max_attempts = attempts;
        self
    }

    /// Set the initial retry delay in milliseconds.
    #[must_use]
    pub const fn retry_initial_delay_ms(mut self, ms: u64) -> Self {
        self.config.retry.initial_delay_ms = ms;
        self
    }

    /// Set the initial polling interval in milliseconds.
    #[must_use]
    pub const fn polling_initial_interval_ms(mut self, ms: u64) -> Self {
        self.config.polling.initial_interval_ms = ms;
        self
    }

    /// Set the maximum polling interval in milliseconds.
    #[must_use]
    pub const fn polling_max_interval_ms(mut self, ms: u64) -> Self {
        self.config.polling.max_interval_ms = ms;
        self
    }

    /// Set the maximum polling duration in seconds.
    #[must_use]
    pub const fn polling_max_duration_seconds(mut self, seconds: u64) -> Self {
        self.config.polling.max_duration_seconds = seconds;
        self
    }

    /// Enable or disable caching.
    #[must_use]
    pub const fn cache_enabled(mut self, enabled: bool) -> Self {
        self.config.cache.enabled = enabled;
        self
    }

    /// Set the cache TTL in seconds.
    #[must_use]
    pub const fn cache_ttl_seconds(mut self, seconds: u64) -> Self {
        self.config.cache.ttl_seconds = seconds;
        self
    }

    /// Build the configuration.
    ///
    /// # Errors
    ///
    /// Returns `LastIDError::Config` if validation fails.
    #[must_use = "this method consumes the builder and returns a config that should be used"]
    pub fn build(self) -> Result<SDKConfig, LastIDError> {
        self.config.validate()?;
        Ok(self.config)
    }
}
