//! Verified phone credential policy builder for WASM.

use wasm_bindgen::prelude::*;

use crate::error::LastIDError;
use crate::policies::PolicyBuilder;
use crate::types::CredentialPolicyRequest;

/// Verified phone credential policy builder for WASM.
///
/// # JavaScript Usage
///
/// ```javascript
/// const policy = new VerifiedPhonePolicy()
///     .withCountryCode("+1")
///     .withCallback("https://yourapp.com/callback");
/// ```
#[wasm_bindgen(js_name = VerifiedPhonePolicy)]
pub struct WasmVerifiedPhonePolicy {
    callback_url: Option<String>,
    country_code: Option<String>,
}

#[wasm_bindgen(js_class = VerifiedPhonePolicy)]
impl WasmVerifiedPhonePolicy {
    #[wasm_bindgen(constructor)]
    pub fn new() -> Self {
        Self {
            callback_url: None,
            country_code: None,
        }
    }

    /// Add a country code constraint (e.g., "+1" for US numbers).
    #[wasm_bindgen(js_name = withCountryCode)]
    pub fn with_country_code(mut self, code: String) -> Self {
        self.country_code = Some(code);
        self
    }

    #[wasm_bindgen(js_name = withCallback)]
    pub fn with_callback(mut self, url: String) -> Self {
        self.callback_url = Some(url);
        self
    }

    #[wasm_bindgen(js_name = credentialType, getter)]
    pub fn credential_type(&self) -> String {
        "LastID.VerifiedPhone".to_string()
    }

    #[wasm_bindgen(js_name = isComplete, getter)]
    pub fn is_complete(&self) -> bool {
        self.callback_url.is_some()
    }
}

impl Default for WasmVerifiedPhonePolicy {
    fn default() -> Self {
        Self::new()
    }
}

impl PolicyBuilder for WasmVerifiedPhonePolicy {
    fn credential_type(&self) -> &'static str {
        "LastID.VerifiedPhone"
    }

    fn to_request(self) -> Result<CredentialPolicyRequest, LastIDError> {
        let callback_url = self
            .callback_url
            .ok_or_else(|| LastIDError::policy_validation("Callback URL is required"))?;

        crate::types::EndpointUrl::new(&callback_url)?;

        if let Some(ref code) = self.country_code {
            if !code.starts_with('+') || code.len() < 2 {
                return Err(LastIDError::policy_validation(
                    "Country code must start with '+' and have at least one digit (e.g., '+1')",
                ));
            }
        }

        let constraints = self.country_code.as_ref().map(|code| {
            let mut map = std::collections::HashMap::new();
            map.insert("countryCode".to_string(), serde_json::json!(code));
            map
        });

        let mut request = CredentialPolicyRequest::with_chain("LastID.VerifiedPhone");
        request.callback_url = Some(callback_url);
        request.constraints = constraints;
        Ok(request)
    }
}
