//! WASM Policy Builders.
//!
//! This module exposes the SDK's policy builders to JavaScript via WASM.
//! Each policy type is in its own file to stay under the 500-line limit.

mod age_proof;
mod base;
mod employment;
mod persona;
mod trust;
mod verified_email;
mod verified_persona;
mod verified_phone;

pub use age_proof::WasmAgeProofPolicy;
pub use base::WasmBaseCredentialPolicy;
pub use employment::WasmEmploymentPolicy;
pub use persona::WasmPersonaPolicy;
pub use trust::WasmTrustPolicy;
pub use verified_email::WasmVerifiedEmailPolicy;
pub use verified_persona::WasmVerifiedPersonaPolicy;
pub use verified_phone::WasmVerifiedPhonePolicy;

#[cfg(test)]
mod tests {
    use super::*;
    use crate::policies::PolicyBuilder;

    #[test]
    fn test_wasm_base_policy_fluent_api() {
        let policy = WasmBaseCredentialPolicy::new()
            .with_state("csrf-token".to_string())
            .with_nonce("binding-nonce".to_string())
            .with_callback("https://example.com/callback".to_string());

        assert!(policy.is_complete());
        assert_eq!(policy.credential_type(), "LastID.Base");
    }

    #[test]
    fn test_wasm_base_policy_to_request() {
        let policy = WasmBaseCredentialPolicy::new()
            .with_state("csrf-token".to_string())
            .with_nonce("binding-nonce".to_string())
            .with_callback("https://example.com/callback".to_string());

        let request = policy.to_request().unwrap();
        assert_eq!(request.credential_type, "LastID.Base");
        assert_eq!(
            request.callback_url,
            Some("https://example.com/callback".to_string())
        );
    }

    #[test]
    fn test_wasm_persona_policy() {
        let policy = WasmPersonaPolicy::new()
            .with_fields(vec!["FullName".to_string(), "DateOfBirth".to_string()])
            .with_callback("https://example.com/callback".to_string());

        assert!(policy.is_complete());
        let request = policy.to_request().unwrap();
        assert_eq!(request.credential_type, "LastID.Persona");
    }

    #[test]
    fn test_wasm_verified_email_policy() {
        let policy = WasmVerifiedEmailPolicy::new()
            .with_domain_constraint("example.com".to_string())
            .with_callback("https://example.com/callback".to_string());

        assert!(policy.is_complete());
        let request = policy.to_request().unwrap();
        assert_eq!(request.credential_type, "LastID.VerifiedEmail");
    }

    #[test]
    fn test_wasm_verified_phone_policy() {
        let policy = WasmVerifiedPhonePolicy::new()
            .with_country_code("+1".to_string())
            .with_callback("https://example.com/callback".to_string());

        assert!(policy.is_complete());
        let request = policy.to_request().unwrap();
        assert_eq!(request.credential_type, "LastID.VerifiedPhone");
    }

    #[test]
    fn test_wasm_verified_persona_policy() {
        let policy = WasmVerifiedPersonaPolicy::new()
            .with_verification_level("Enhanced".to_string())
            .with_fields(vec!["LegalName".to_string()])
            .with_callback("https://example.com/callback".to_string());

        assert!(policy.is_complete());
        let request = policy.to_request().unwrap();
        assert_eq!(request.credential_type, "LastID.VerifiedPersona");
    }

    #[test]
    fn test_wasm_employment_policy() {
        let policy = WasmEmploymentPolicy::new()
            .with_employer_domain("acme.com".to_string())
            .with_status("Current".to_string())
            .with_fields(vec!["JobTitle".to_string()])
            .with_callback("https://example.com/callback".to_string());

        assert!(policy.is_complete());
        let request = policy.to_request().unwrap();
        assert_eq!(request.credential_type, "LastID.Employment");
    }

    #[test]
    fn test_wasm_trust_policy() {
        let policy = WasmTrustPolicy::new()
            .with_minimum_level("Verified".to_string())
            .with_trusted_issuer("did:lastid:trusted-org".to_string())
            .require_mutual_trust()
            .with_max_age_days(30)
            .with_callback("https://example.com/callback".to_string());

        assert!(policy.is_complete());
        let request = policy.to_request().unwrap();
        assert_eq!(request.credential_type, "LastID.Trust");
    }

    #[test]
    fn test_wasm_age_proof_policy_at_least() {
        let policy = WasmAgeProofPolicy::new()
            .at_least(21)
            .with_callback("https://example.com/callback".to_string());

        assert!(policy.is_complete());
        let request = policy.to_request().unwrap();
        assert_eq!(request.credential_type, "LastID.AgeProof");
    }

    #[test]
    fn test_wasm_age_proof_policy_between() {
        let policy = WasmAgeProofPolicy::new()
            .between(18, 65)
            .with_callback("https://example.com/callback".to_string());

        assert!(policy.is_complete());
        let request = policy.to_request().unwrap();
        assert_eq!(request.credential_type, "LastID.AgeProof");
        let constraints = request.constraints.unwrap();
        assert_eq!(constraints.get("comparison").unwrap(), "between");
        assert_eq!(constraints.get("age").unwrap(), 18);
        assert_eq!(constraints.get("maxAge").unwrap(), 65);
    }
}
