//! LinkedIn profile URL validation library with AI-first design.
//!
//! Credify provides comprehensive LinkedIn URL validation with multiple API levels,
//! from simple boolean checks to rich structured data optimized for AI agents and
//! LLM tool calling, especially with frameworks like [Rig](https://github.com/0xPlaygrounds/rig).
//!
//! # Features
//!
//! - 🤖 **AI-First Design** - Multiple API levels for different use cases
//! - 🎯 **Rig Framework Optimized** - Ergonomic async helpers that prevent runtime panics
//! - ⚡ **Async & Sync APIs** - Full async support for modern applications
//! - 📊 **Structured Responses** - Rich data with confidence scores and decisions
//! - 🔍 **Smart Validation** - Format checking and existence verification
//! - 🛡️ **Never Panics** - Comprehensive error handling throughout
//!
//! # Quick Start
//!
//! ## For AI Agents & Rig Framework (Recommended)
//!
//! ```no_run
//! # async fn example() {
//! use credify::{rig_is_valid, rig_validate_text};
//!
//! // Ultra-simple validation
//! if rig_is_valid("https://linkedin.com/in/johndoe").await {
//!     println!("Valid LinkedIn profile!");
//! }
//!
//! // Get a human-readable response  
//! let message = rig_validate_text("https://linkedin.com/in/johndoe").await;
//! println!("{}", message); // "✅ Valid profile @johndoe (95% confidence)"
//! # }
//! ```
//!
//! ## Traditional API
//!
//! ```no_run
//! use credify::{LinkedInValidator, LinkedInUrlError};
//!
//! let validator = LinkedInValidator::new().expect("Failed to create validator");
//! match validator.is_valid_linkedin_profile_url("https://www.linkedin.com/in/johndoe") {
//!     Ok(_) => println!("Profile exists!"),
//!     Err(LinkedInUrlError::ProfileNotFound) => println!("Profile not found"),
//!     Err(LinkedInUrlError::AuthenticationRequired) => println!("LinkedIn requires auth"),
//!     Err(e) => println!("Error: {}", e),
//! }
//! ```
//!
//! ## Format validation only
//!
//! ```
//! use credify::is_valid_linkedin_profile_format;
//!
//! if is_valid_linkedin_profile_format("https://www.linkedin.com/in/johndoe") {
//!     println!("Valid LinkedIn profile URL format");
//! }
//! ```
//!
//! ## LLM-friendly validation
//!
//! ```no_run
//! use credify::validate_for_llm;
//!
//! let result = validate_for_llm("https://www.linkedin.com/in/johndoe");
//! println!("{}", result);
//! // Parse the structured output for automated decision making
//! ```
//!
//! ## AI-optimized API
//!
//! ```no_run
//! use credify::{ai_validate, AIDecision};
//!
//! let result = ai_validate("https://www.linkedin.com/in/johndoe");
//!
//! // Simple boolean check
//! if result.is_valid {
//!     println!("Valid profile!");
//! }
//!
//! // Use confidence level
//! if result.confidence >= 0.9 {
//!     println!("High confidence validation");
//! }
//!
//! // AI decision making
//! match result.decision {
//!     AIDecision::Accept => println!("Use this profile"),
//!     AIDecision::Retry => println!("Try again later"),
//!     AIDecision::Reject => println!("Invalid URL"),
//! }
//!
//! // Get JSON for direct consumption
//! use credify::ai_validate_json;
//! let json = ai_validate_json("https://linkedin.com/in/user");
//! ```
//!
//! ## Rig Tool Implementation
//!
//! ```no_run
//! # use serde::{Deserialize, Serialize};
//! # #[derive(Deserialize)]
//! # struct Args { url: String }
//! # #[derive(Debug)]
//! # struct Error;
//! # trait Tool {
//! #     async fn call(&self, args: Args) -> Result<String, Error>;
//! # }
//! # #[derive(Deserialize, Serialize)]
//! # struct LinkedInValidator;
//! # impl Tool for LinkedInValidator {
//! async fn call(&self, args: Args) -> Result<String, Error> {
//!     // Just one line! No runtime panics, perfect for Rig
//!     Ok(credify::rig_validate_json(&args.url).await)
//! }
//! # }
//! ```
//!
//! # API Levels
//!
//! Credify provides multiple API levels for different use cases:
//!
//! | API Level | Functions | Use Case |
//! |-----------|-----------|----------|
//! | **Ergonomic Rig** | `rig_*` functions | AI agents, Rig tools |
//! | **AI-Optimized** | `ai_*` functions | Structured data for AI |
//! | **LLM-Friendly** | `validate_for_llm*` | Verbose text reports |
//! | **Traditional** | `LinkedInValidator` | Direct validation |
//!
//! # Important: Async Usage
//!
//! When using Credify in async contexts, **always use async versions**:
//!
//! ```no_run
//! # async fn example() {
//! // ❌ WRONG - Can panic in async context
//! // let result = credify::ai_validate_json(url);
//!
//! // ✅ CORRECT - Use async version
//! let result = credify::ai_validate_json_async("url").await;
//!
//! // ✅ BEST - Rig helpers are always async
//! let result = credify::rig_validate_json("url").await;
//! # }
//! ```

use once_cell::sync::Lazy;
use regex::Regex;
use serde::{Deserialize, Serialize};
use serde_json::json;
use thiserror::Error;
use url::Url;

mod rig_helpers;
pub use rig_helpers::{rig_is_valid, rig_validate, rig_validate_json, rig_validate_text, RigValidationResult};

/// Errors that can occur during `LinkedIn` URL validation.
#[derive(Error, Debug)]
pub enum LinkedInUrlError {
    /// The provided URL has invalid format.
    #[error("[INVALID_URL_FORMAT] The provided URL is not a valid URL: {0}")]
    InvalidUrl(String),

    /// The URL is not from `LinkedIn` domain.
    #[error("[NOT_LINKEDIN_DOMAIN] The URL is not from linkedin.com or www.linkedin.com domain")]
    NotLinkedInUrl,

    /// The URL is from `LinkedIn` but not a profile URL.
    #[error(
        "[NOT_PROFILE_URL] The URL is not a LinkedIn profile URL (expected format: /in/username)"
    )]
    NotProfileUrl,

    /// Network error occurred during validation.
    #[error("[NETWORK_ERROR] Failed to connect to LinkedIn: {0}")]
    NetworkError(#[from] reqwest::Error),

    /// The `LinkedIn` profile was not found (404).
    #[error("[PROFILE_NOT_FOUND] The LinkedIn profile does not exist (404)")]
    ProfileNotFound,

    /// `LinkedIn` requires authentication to verify the profile.
    #[error("[AUTH_REQUIRED] LinkedIn requires authentication to verify this profile - cannot determine if profile exists")]
    AuthenticationRequired,

    /// HTTP client build error
    #[error("[CLIENT_BUILD_ERROR] Failed to create HTTP client: {0}")]
    ClientBuildError(String),
}

/// A `LinkedIn` profile validator that performs HTTP requests to verify profile existence.
///
/// # Example
///
/// ```no_run
/// use credify::LinkedInValidator;
///
/// let validator = LinkedInValidator::new().expect("Failed to create validator");
/// let result = validator.is_valid_linkedin_profile_url("https://www.linkedin.com/in/johndoe");
/// ```
pub struct LinkedInValidator {
    client: reqwest::blocking::Client,
}

impl LinkedInValidator {
    /// Creates a new `LinkedIn` validator instance.
    ///
    /// # Errors
    ///
    /// Returns an error if the HTTP client cannot be built.
    pub fn new() -> Result<Self, LinkedInUrlError> {
        let client = reqwest::blocking::Client::builder()
            .user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
            .timeout(std::time::Duration::from_secs(10))
            .build()
            .map_err(|e| LinkedInUrlError::ClientBuildError(e.to_string()))?;

        Ok(Self { client })
    }

    /// Validates a `LinkedIn` profile URL by checking format and existence.
    ///
    /// This method performs an HTTP request to verify if the profile actually exists.
    ///
    /// # Arguments
    ///
    /// * `url_str` - The `LinkedIn` profile URL to validate
    ///
    /// # Returns
    ///
    /// * `Ok(true)` - If the profile exists
    /// * `Err(LinkedInUrlError)` - If validation fails
    ///
    /// # Errors
    ///
    /// Returns an error if:
    /// - The URL format is invalid
    /// - The URL is not from `LinkedIn` domain
    /// - The URL is not a profile URL
    /// - Network request fails
    /// - The profile doesn't exist (404)
    /// - `LinkedIn` requires authentication
    ///
    /// # Example
    ///
    /// ```no_run
    /// use credify::LinkedInValidator;
    ///
    /// let validator = LinkedInValidator::new().expect("Failed to create validator");
    /// match validator.is_valid_linkedin_profile_url("https://www.linkedin.com/in/johndoe") {
    ///     Ok(_) => println!("Valid profile"),
    ///     Err(e) => println!("Invalid: {}", e),
    /// }
    /// ```
    pub fn is_valid_linkedin_profile_url(&self, url_str: &str) -> Result<bool, LinkedInUrlError> {
        let url = Url::parse(url_str).map_err(|e| LinkedInUrlError::InvalidUrl(e.to_string()))?;

        if !is_linkedin_domain(&url) {
            return Err(LinkedInUrlError::NotLinkedInUrl);
        }

        if !is_profile_path(&url) {
            return Err(LinkedInUrlError::NotProfileUrl);
        }

        self.check_profile_exists(url_str)?;

        Ok(true)
    }

    fn check_profile_exists(&self, url: &str) -> Result<(), LinkedInUrlError> {
        let mut response = self.client.get(url).send()?;

        // LinkedIn returns 999 status for bot detection/rate limiting
        // In this case, we need to follow redirects manually
        if response.status().as_u16() == 999 {
            // Try with cookie header to bypass authwall
            response = self.client.get(url).header("Cookie", "sl=v=1&1").send()?;
        }

        // Check if redirected to 404 page
        let final_url = response.url().to_string();
        if final_url.contains("/404/") || final_url.contains("linkedin.com/404") {
            return Err(LinkedInUrlError::ProfileNotFound);
        }

        // Get response body
        let body = response.text()?;

        // Check for authwall (indicates we're being blocked)
        if body.contains("/authwall") || body.contains("sessionRedirect") {
            // When we hit authwall, we can't determine if profile exists
            return Err(LinkedInUrlError::AuthenticationRequired);
        }

        // Check for common error page indicators
        if body.contains("This page doesn't exist")
            || body.contains("This page doesn't exist")
            || body.contains("Page not found")
            || body.contains("Check the URL or return to LinkedIn home")
            || body.contains("return to LinkedIn home")
            || body.contains("Go to your feed") && body.contains("doesn't exist")
        {
            return Err(LinkedInUrlError::ProfileNotFound);
        }

        Ok(())
    }
}

fn is_linkedin_domain(url: &Url) -> bool {
    matches!(url.domain(), Some(domain) if domain == "linkedin.com" || domain == "www.linkedin.com")
}

static PROFILE_REGEX: Lazy<Regex> = Lazy::new(|| {
    Regex::new(r"^/in/[a-zA-Z0-9\-\.]+/?$")
        .expect("[INTERNAL_ERROR] Failed to compile profile regex pattern")
});

fn is_profile_path(url: &Url) -> bool {
    let path = url.path();
    PROFILE_REGEX.is_match(path)
}

impl LinkedInValidator {
    /// Creates a new validator with default configuration.
    ///
    /// This is a convenience method that panics on error.
    /// For production use, prefer `new()` and handle the error.
    #[must_use]
    pub fn new_unchecked() -> Self {
        Self::new().expect("[INTERNAL_ERROR] Failed to create LinkedIn validator")
    }
}

/// Validates a `LinkedIn` profile URL asynchronously.
///
/// This function performs an HTTP request to verify if the profile actually exists.
/// Use this for async contexts like web servers.
///
/// # Arguments
///
/// * `url` - The `LinkedIn` profile URL to validate
///
/// # Returns
///
/// * `Ok(true)` - If the profile exists
/// * `Err(LinkedInUrlError)` - If validation fails
///
/// # Errors
///
/// Returns an error if:
/// - The URL format is invalid
/// - The URL is not from `LinkedIn` domain
/// - The URL is not a profile URL
/// - Network request fails
/// - The profile doesn't exist (404)
/// - `LinkedIn` requires authentication
///
/// # Example
///
/// ```no_run
/// use credify::validate_linkedin_url_async;
///
/// # async fn example() {
/// match validate_linkedin_url_async("https://www.linkedin.com/in/johndoe").await {
///     Ok(_) => println!("Valid profile"),
///     Err(e) => println!("Invalid: {}", e),
/// }
/// # }
/// ```
pub async fn validate_linkedin_url_async(url: &str) -> Result<bool, LinkedInUrlError> {
    let url_parsed = Url::parse(url).map_err(|e| LinkedInUrlError::InvalidUrl(e.to_string()))?;

    if !is_linkedin_domain(&url_parsed) {
        return Err(LinkedInUrlError::NotLinkedInUrl);
    }

    if !is_profile_path(&url_parsed) {
        return Err(LinkedInUrlError::NotProfileUrl);
    }

    let client = reqwest::Client::builder()
        .user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
        .timeout(std::time::Duration::from_secs(10))
        .build()
        .map_err(|e| LinkedInUrlError::ClientBuildError(e.to_string()))?;

    let mut response = client.get(url).send().await?;

    // LinkedIn returns 999 status for bot detection/rate limiting
    if response.status().as_u16() == 999 {
        // Try with cookie header to bypass authwall
        response = client.get(url).header("Cookie", "sl=v=1&1").send().await?;
    }

    // Check if redirected to 404 page
    let final_url = response.url().to_string();
    if final_url.contains("/404/") || final_url.contains("linkedin.com/404") {
        return Err(LinkedInUrlError::ProfileNotFound);
    }

    // Get response body
    let body = response.text().await?;

    // Check for authwall (indicates we're being blocked)
    if body.contains("/authwall") || body.contains("sessionRedirect") {
        return Err(LinkedInUrlError::AuthenticationRequired);
    }

    // Check for common error page indicators
    if body.contains("This page doesn't exist")
        || body.contains("This page doesn't exist")
        || body.contains("Page not found")
        || body.contains("Check the URL or return to LinkedIn home")
        || body.contains("return to LinkedIn home")
        || body.contains("Go to your feed") && body.contains("doesn't exist")
    {
        return Err(LinkedInUrlError::ProfileNotFound);
    }

    Ok(true)
}

/// Validates a LinkedIn profile URL and returns a structured string for LLM consumption.
///
/// This function provides a verbose, structured response that's easy for LLM agents to parse
/// and make decisions based on. It includes validation result, error type, and suggested actions.
///
/// # Arguments
///
/// * `url` - The LinkedIn profile URL to validate
///
/// # Returns
///
/// A structured string containing:
/// - `VALIDATION_RESULT`: SUCCESS or ERROR
/// - `PROFILE_EXISTS`: TRUE or FALSE (only if successful)
/// - `ERROR_TYPE`: Specific error type (only if failed)
/// - `ERROR_MESSAGE`: Detailed error message
/// - `SUGGESTED_ACTION`: What the LLM should do next
///
/// # Example
///
/// ```no_run
/// use credify::validate_for_llm;
///
/// let result = validate_for_llm("https://www.linkedin.com/in/johndoe");
/// println!("{}", result);
/// // Output:
/// // === LINKEDIN PROFILE VALIDATION REPORT ===
/// //
/// // TIMESTAMP: 2025-07-31T13:10:54.691091+00:00
/// // INPUT_URL: https://www.linkedin.com/in/johndoe
/// //
/// // VALIDATION_RESULT: SUCCESS
/// // VALIDATION_STATUS: PASSED
/// // PROFILE_EXISTS: TRUE
/// // URL_FORMAT: VALID
/// // DOMAIN_VERIFIED: TRUE
/// // PROFILE_ACCESSIBLE: TRUE
/// // LINKEDIN_USERNAME: johndoe
/// //
/// // DETAILED_EXPLANATION:
/// // The provided URL has been successfully validated. The LinkedIn profile exists and is accessible. The URL follows the correct LinkedIn profile format and the domain has been verified as authentic. The profile page returned a successful response, confirming the profile is active and publicly viewable.
/// //
/// // SUGGESTED_ACTIONS:
/// // 1. Proceed with profile data extraction using LinkedIn API or web scraping tools
/// // 2. Cache this validation result to avoid repeated network requests
/// // 3. Store the profile URL in your database as a verified LinkedIn profile
/// // 4. Consider extracting additional profile metadata (name, headline, etc.)
/// // 5. Set up monitoring to periodically re-validate the profile existence
/// //
/// // RECOMMENDED_NEXT_STEP: Extract profile data using appropriate LinkedIn data extraction methods
/// //
/// // === END OF VALIDATION REPORT ===
/// ```
pub fn validate_for_llm(url: &str) -> String {
    let mut result = String::new();

    // Header
    result.push_str("=== LINKEDIN PROFILE VALIDATION REPORT ===\n\n");
    result.push_str(&format!("TIMESTAMP: {}\n", chrono::Utc::now().to_rfc3339()));
    result.push_str(&format!("INPUT_URL: {url}\n"));
    result.push('\n');

    let validator = match LinkedInValidator::new() {
        Ok(v) => v,
        Err(e) => {
            result.push_str("VALIDATION_RESULT: ERROR\n");
            result.push_str("VALIDATION_STATUS: FAILED\n");
            result.push_str("ERROR_TYPE: VALIDATOR_INITIALIZATION_FAILED\n");
            result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
            result.push_str("ERROR_SEVERITY: CRITICAL\n");
            result.push_str("\nDETAILED_EXPLANATION:\n");
            result.push_str(
                "The HTTP client required for LinkedIn validation could not be initialized. ",
            );
            result.push_str("This is typically caused by system resource constraints or TLS configuration issues.\n");
            result.push_str("\nSUGGESTED_ACTIONS:\n");
            result.push_str("1. Check available system memory and ensure sufficient resources\n");
            result.push_str("2. Verify TLS/SSL libraries are properly installed on the system\n");
            result
                .push_str("3. Check for any system-level network restrictions or firewall rules\n");
            result.push_str("4. Try restarting the application or service\n");
            result.push_str(
                "5. If problem persists, check system logs for more detailed error information\n",
            );
            result.push_str("\nRECOMMENDED_NEXT_STEP: Resolve system-level issues before attempting validation again\n");
            result.push_str("\n=== END OF VALIDATION REPORT ===\n");
            return result;
        }
    };

    match validator.is_valid_linkedin_profile_url(url) {
        Ok(_) => {
            result.push_str("VALIDATION_RESULT: SUCCESS\n");
            result.push_str("VALIDATION_STATUS: PASSED\n");
            result.push_str("PROFILE_EXISTS: TRUE\n");
            result.push_str("URL_FORMAT: VALID\n");
            result.push_str("DOMAIN_VERIFIED: TRUE\n");
            result.push_str("PROFILE_ACCESSIBLE: TRUE\n");

            // Extract username from URL
            if let Ok(parsed_url) = url::Url::parse(url) {
                if let Some(mut path_segments) = parsed_url.path_segments() {
                    if let Some(username) = path_segments.next_back() {
                        result.push_str(&format!(
                            "LINKEDIN_USERNAME: {}\n",
                            username.trim_end_matches('/')
                        ));
                    }
                }
            }

            result.push_str("\nDETAILED_EXPLANATION:\n");
            result.push_str("The provided URL has been successfully validated. The LinkedIn profile exists and is accessible. ");
            result.push_str("The URL follows the correct LinkedIn profile format and the domain has been verified as authentic. ");
            result.push_str("The profile page returned a successful response, confirming the profile is active and publicly viewable.\n");

            result.push_str("\nSUGGESTED_ACTIONS:\n");
            result.push_str("1. Proceed with profile data extraction using LinkedIn API or web scraping tools\n");
            result.push_str("2. Cache this validation result to avoid repeated network requests\n");
            result.push_str(
                "3. Store the profile URL in your database as a verified LinkedIn profile\n",
            );
            result.push_str(
                "4. Consider extracting additional profile metadata (name, headline, etc.)\n",
            );
            result.push_str(
                "5. Set up monitoring to periodically re-validate the profile existence\n",
            );

            result.push_str("\nRECOMMENDED_NEXT_STEP: Extract profile data using appropriate LinkedIn data extraction methods\n");
        }
        Err(e) => {
            result.push_str("VALIDATION_RESULT: ERROR\n");
            result.push_str("VALIDATION_STATUS: FAILED\n");

            match e {
                LinkedInUrlError::InvalidUrl(ref msg) => {
                    result.push_str("ERROR_TYPE: INVALID_URL_FORMAT\n");
                    result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
                    result.push_str(&format!("ERROR_DETAILS: {msg}\n"));
                    result.push_str("ERROR_SEVERITY: HIGH\n");
                    result.push_str("PROFILE_EXISTS: UNKNOWN\n");
                    result.push_str("URL_FORMAT: INVALID\n");

                    result.push_str("\nDETAILED_EXPLANATION:\n");
                    result.push_str("The provided string is not a valid URL. The URL parser failed to interpret the input as a properly formatted URL. ");
                    result.push_str("Common causes include missing protocol (http/https), invalid characters, or malformed structure.\n");

                    result.push_str("\nSUGGESTED_ACTIONS:\n");
                    result.push_str("1. Ensure the URL starts with 'https://' or 'http://'\n");
                    result.push_str("2. Check for special characters that need URL encoding\n");
                    result.push_str("3. Verify there are no spaces or line breaks in the URL\n");
                    result.push_str(
                        "4. Confirm the URL follows standard format: protocol://domain/path\n",
                    );
                    result.push_str(
                        "5. Try URL encoding the input if it contains special characters\n",
                    );
                    result.push_str(
                        "6. Example valid format: https://www.linkedin.com/in/username\n",
                    );

                    result.push_str(
                        "\nRECOMMENDED_NEXT_STEP: Fix the URL format and retry validation\n",
                    );
                }
                LinkedInUrlError::NotLinkedInUrl => {
                    result.push_str("ERROR_TYPE: NOT_LINKEDIN_DOMAIN\n");
                    result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
                    result.push_str("ERROR_SEVERITY: MEDIUM\n");
                    result.push_str("PROFILE_EXISTS: NOT_APPLICABLE\n");
                    result.push_str("URL_FORMAT: VALID\n");
                    result.push_str("DOMAIN_VERIFIED: FALSE\n");

                    // Extract the actual domain from URL
                    if let Ok(parsed_url) = url::Url::parse(url) {
                        if let Some(domain) = parsed_url.domain() {
                            result.push_str(&format!("ACTUAL_DOMAIN: {domain}\n"));
                        }
                    }

                    result.push_str("\nDETAILED_EXPLANATION:\n");
                    result
                        .push_str("The URL is properly formatted but does not point to LinkedIn. ");
                    result.push_str("Only URLs from 'linkedin.com' or 'www.linkedin.com' domains are accepted for LinkedIn profile validation. ");
                    result.push_str("The provided URL points to a different domain.\n");

                    result.push_str("\nSUGGESTED_ACTIONS:\n");
                    result.push_str("1. Verify the URL is meant to be a LinkedIn profile URL\n");
                    result.push_str("2. Check if the URL was copied correctly from LinkedIn\n");
                    result
                        .push_str("3. Ensure the domain is 'linkedin.com' or 'www.linkedin.com'\n");
                    result.push_str("4. Look for the correct LinkedIn profile URL in the user's social media links\n");
                    result.push_str(
                        "5. Ask the user to provide their LinkedIn profile URL directly\n",
                    );

                    result.push_str("\nRECOMMENDED_NEXT_STEP: Obtain the correct LinkedIn profile URL from the user or source\n");
                }
                LinkedInUrlError::NotProfileUrl => {
                    result.push_str("ERROR_TYPE: NOT_PROFILE_URL\n");
                    result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
                    result.push_str("ERROR_SEVERITY: MEDIUM\n");
                    result.push_str("PROFILE_EXISTS: NOT_APPLICABLE\n");
                    result.push_str("URL_FORMAT: VALID\n");
                    result.push_str("DOMAIN_VERIFIED: TRUE\n");
                    result.push_str("URL_TYPE: NON_PROFILE_LINKEDIN_URL\n");

                    result.push_str("\nDETAILED_EXPLANATION:\n");
                    result
                        .push_str("The URL points to LinkedIn but is not a personal profile URL. ");
                    result.push_str(
                        "It might be a company page, job posting, or other LinkedIn content. ",
                    );
                    result.push_str(
                        "Valid profile URLs follow the pattern: linkedin.com/in/username\n",
                    );

                    result.push_str("\nSUGGESTED_ACTIONS:\n");
                    result.push_str(
                        "1. Check if this is a company page URL (contains '/company/')\n",
                    );
                    result.push_str("2. Verify if this is a job posting URL (contains '/jobs/')\n");
                    result.push_str(
                        "3. Look for the '/in/' segment that indicates a personal profile\n",
                    );
                    result
                        .push_str("4. Navigate to the person's actual profile page on LinkedIn\n");
                    result.push_str("5. Use LinkedIn search to find the correct profile URL\n");

                    result.push_str("\nRECOMMENDED_NEXT_STEP: Navigate to the personal profile section of LinkedIn\n");
                }
                LinkedInUrlError::ProfileNotFound => {
                    result.push_str("ERROR_TYPE: PROFILE_NOT_FOUND\n");
                    result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
                    result.push_str("ERROR_SEVERITY: LOW\n");
                    result.push_str("PROFILE_EXISTS: FALSE\n");
                    result.push_str("URL_FORMAT: VALID\n");
                    result.push_str("DOMAIN_VERIFIED: TRUE\n");
                    result.push_str("HTTP_STATUS: 404\n");

                    result.push_str("\nDETAILED_EXPLANATION:\n");
                    result.push_str("The URL format is correct and points to LinkedIn, but the profile does not exist. ");
                    result
                        .push_str("LinkedIn returned a 404 error or redirected to an error page. ");
                    result.push_str("This means the username in the URL does not correspond to any active LinkedIn profile.\n");

                    result.push_str("\nSUGGESTED_ACTIONS:\n");
                    result.push_str("1. Double-check the username/URL for typos\n");
                    result.push_str(
                        "2. Verify if the profile might have been deleted or deactivated\n",
                    );
                    result.push_str("3. Check if the user might have changed their LinkedIn URL\n");
                    result.push_str("4. Search for the person on LinkedIn using their name\n");
                    result.push_str(
                        "5. Contact the person to get their current LinkedIn profile URL\n",
                    );
                    result.push_str("6. Remove this URL from your database if it's stored\n");

                    result.push_str("\nRECOMMENDED_NEXT_STEP: Search for the correct profile or mark as invalid in your system\n");
                }
                LinkedInUrlError::AuthenticationRequired => {
                    result.push_str("ERROR_TYPE: AUTH_REQUIRED\n");
                    result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
                    result.push_str("ERROR_SEVERITY: MEDIUM\n");
                    result.push_str("PROFILE_EXISTS: UNKNOWN\n");
                    result.push_str("URL_FORMAT: VALID\n");
                    result.push_str("DOMAIN_VERIFIED: TRUE\n");
                    result.push_str("LINKEDIN_RESPONSE: AUTHENTICATION_WALL\n");

                    result.push_str("\nDETAILED_EXPLANATION:\n");
                    result.push_str("LinkedIn is requiring authentication to view this profile. ");
                    result.push_str("This typically happens when LinkedIn detects automated access patterns or when accessing from certain IP ranges. ");
                    result.push_str("The profile format is valid and the profile LIKELY EXISTS, but LinkedIn is preventing automated verification.\n");

                    result.push_str("\nSUGGESTED_ACTIONS:\n");
                    result.push_str(
                        "1. ACCEPT AS VALID: The URL format is correct and points to LinkedIn - treat as valid profile URL\n",
                    );
                    result.push_str(
                        "2. RETRY LATER: Wait 30-60 seconds before trying to validate this URL again\n",
                    );
                    result.push_str("3. CONTINUE SEARCH: This URL is likely correct, but continue searching for alternative profiles if needed\n");
                    result.push_str("4. CONFIDENCE: HIGH - LinkedIn auth walls usually indicate real profiles\n");
                    result.push_str("5. FOR AI AGENTS: You can safely return this URL as a valid LinkedIn profile\n");
                    result.push_str(
                        "6. VERIFICATION: The URL follows pattern https://linkedin.com/in/USERNAME which is correct\n",
                    );
                    result.push_str(
                        "7. RECOMMENDATION: Use this URL - it's almost certainly a valid profile\n",
                    );

                    result.push_str("\nRECOMMENDED_NEXT_STEP: ACCEPT this URL as valid - LinkedIn authentication requirements typically indicate the profile exists\n");
                }
                LinkedInUrlError::NetworkError(_) => {
                    result.push_str("ERROR_TYPE: NETWORK_ERROR\n");
                    result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
                    result.push_str("ERROR_SEVERITY: HIGH\n");
                    result.push_str("PROFILE_EXISTS: UNKNOWN\n");
                    result.push_str("URL_FORMAT: VALID\n");
                    result.push_str("NETWORK_STATUS: FAILED\n");

                    result.push_str("\nDETAILED_EXPLANATION:\n");
                    result.push_str("Failed to establish a network connection to LinkedIn. ");
                    result.push_str("This could be due to network connectivity issues, DNS resolution problems, ");
                    result.push_str(
                        "firewall restrictions, or LinkedIn being temporarily unavailable.\n",
                    );

                    result.push_str("\nSUGGESTED_ACTIONS:\n");
                    result.push_str("1. Check internet connectivity with a simple ping test\n");
                    result.push_str("2. Verify DNS resolution for linkedin.com\n");
                    result.push_str("3. Check firewall settings for outbound HTTPS connections\n");
                    result.push_str("4. Test if LinkedIn is accessible from a web browser\n");
                    result.push_str("5. Implement retry logic with exponential backoff\n");
                    result.push_str("6. Check for any proxy configuration requirements\n");
                    result.push_str("7. Monitor LinkedIn's status page for any outages\n");

                    result.push_str("\nRECOMMENDED_NEXT_STEP: Diagnose and resolve network connectivity issues\n");
                }
                LinkedInUrlError::ClientBuildError(ref msg) => {
                    result.push_str("ERROR_TYPE: CLIENT_BUILD_ERROR\n");
                    result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
                    result.push_str(&format!("ERROR_DETAILS: {msg}\n"));
                    result.push_str("ERROR_SEVERITY: CRITICAL\n");
                    result.push_str("PROFILE_EXISTS: UNKNOWN\n");

                    result.push_str("\nDETAILED_EXPLANATION:\n");
                    result.push_str("Failed to build the HTTP client needed for validation. ");
                    result.push_str("This is an internal error that prevents any network requests from being made. ");
                    result.push_str("Common causes include TLS configuration issues or system resource constraints.\n");

                    result.push_str("\nSUGGESTED_ACTIONS:\n");
                    result.push_str("1. Check system TLS/SSL library installation\n");
                    result.push_str("2. Verify sufficient memory is available\n");
                    result.push_str("3. Check for any security software blocking connections\n");
                    result.push_str("4. Review system logs for detailed error information\n");
                    result.push_str("5. Restart the application or service\n");
                    result.push_str("6. Update system libraries and dependencies\n");

                    result.push_str("\nRECOMMENDED_NEXT_STEP: Resolve system configuration issues before retry\n");
                }
            }
        }
    }

    result.push_str("\n=== END OF VALIDATION REPORT ===\n");
    result
}

/// Validates a LinkedIn profile URL asynchronously and returns a structured string for LLM consumption.
///
/// This is the async version of `validate_for_llm`. It provides the same structured response
/// that's easy for LLM agents to parse and make decisions based on.
///
/// # Arguments
///
/// * `url` - The LinkedIn profile URL to validate
///
/// # Returns
///
/// A structured string containing validation results and suggested actions.
///
/// # Example
///
/// ```no_run
/// use credify::validate_for_llm_async;
///
/// # async fn example() {
/// let result = validate_for_llm_async("https://www.linkedin.com/in/johndoe").await;
/// println!("{}", result);
/// // Output format is identical to validate_for_llm() but runs asynchronously
/// # }
/// ```
pub async fn validate_for_llm_async(url: &str) -> String {
    let mut result = String::new();

    // Header
    result.push_str("=== LINKEDIN PROFILE VALIDATION REPORT ===\n\n");
    result.push_str(&format!("TIMESTAMP: {}\n", chrono::Utc::now().to_rfc3339()));
    result.push_str(&format!("INPUT_URL: {url}\n"));
    result.push('\n');

    match validate_linkedin_url_async(url).await {
        Ok(_) => {
            result.push_str("VALIDATION_RESULT: SUCCESS\n");
            result.push_str("VALIDATION_STATUS: PASSED\n");
            result.push_str("PROFILE_EXISTS: TRUE\n");
            result.push_str("URL_FORMAT: VALID\n");
            result.push_str("DOMAIN_VERIFIED: TRUE\n");
            result.push_str("PROFILE_ACCESSIBLE: TRUE\n");

            // Extract username from URL
            if let Ok(parsed_url) = url::Url::parse(url) {
                if let Some(mut path_segments) = parsed_url.path_segments() {
                    if let Some(username) = path_segments.next_back() {
                        result.push_str(&format!(
                            "LINKEDIN_USERNAME: {}\n",
                            username.trim_end_matches('/')
                        ));
                    }
                }
            }

            result.push_str("\nDETAILED_EXPLANATION:\n");
            result.push_str("The provided URL has been successfully validated. The LinkedIn profile exists and is accessible. ");
            result.push_str("The URL follows the correct LinkedIn profile format and the domain has been verified as authentic. ");
            result.push_str("The profile page returned a successful response, confirming the profile is active and publicly viewable.\n");

            result.push_str("\nSUGGESTED_ACTIONS:\n");
            result.push_str("1. Proceed with profile data extraction using LinkedIn API or web scraping tools\n");
            result.push_str("2. Cache this validation result to avoid repeated network requests\n");
            result.push_str(
                "3. Store the profile URL in your database as a verified LinkedIn profile\n",
            );
            result.push_str(
                "4. Consider extracting additional profile metadata (name, headline, etc.)\n",
            );
            result.push_str(
                "5. Set up monitoring to periodically re-validate the profile existence\n",
            );

            result.push_str("\nRECOMMENDED_NEXT_STEP: Extract profile data using appropriate LinkedIn data extraction methods\n");
        }
        Err(e) => {
            result.push_str("VALIDATION_RESULT: ERROR\n");
            result.push_str("VALIDATION_STATUS: FAILED\n");

            match e {
                LinkedInUrlError::InvalidUrl(ref msg) => {
                    result.push_str("ERROR_TYPE: INVALID_URL_FORMAT\n");
                    result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
                    result.push_str(&format!("ERROR_DETAILS: {msg}\n"));
                    result.push_str("ERROR_SEVERITY: HIGH\n");
                    result.push_str("PROFILE_EXISTS: UNKNOWN\n");
                    result.push_str("URL_FORMAT: INVALID\n");

                    result.push_str("\nDETAILED_EXPLANATION:\n");
                    result.push_str("The provided string is not a valid URL. The URL parser failed to interpret the input as a properly formatted URL. ");
                    result.push_str("Common causes include missing protocol (http/https), invalid characters, or malformed structure.\n");

                    result.push_str("\nSUGGESTED_ACTIONS:\n");
                    result.push_str("1. Ensure the URL starts with 'https://' or 'http://'\n");
                    result.push_str("2. Check for special characters that need URL encoding\n");
                    result.push_str("3. Verify there are no spaces or line breaks in the URL\n");
                    result.push_str(
                        "4. Confirm the URL follows standard format: protocol://domain/path\n",
                    );
                    result.push_str(
                        "5. Try URL encoding the input if it contains special characters\n",
                    );
                    result.push_str(
                        "6. Example valid format: https://www.linkedin.com/in/username\n",
                    );

                    result.push_str(
                        "\nRECOMMENDED_NEXT_STEP: Fix the URL format and retry validation\n",
                    );
                }
                LinkedInUrlError::NotLinkedInUrl => {
                    result.push_str("ERROR_TYPE: NOT_LINKEDIN_DOMAIN\n");
                    result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
                    result.push_str("ERROR_SEVERITY: MEDIUM\n");
                    result.push_str("PROFILE_EXISTS: NOT_APPLICABLE\n");
                    result.push_str("URL_FORMAT: VALID\n");
                    result.push_str("DOMAIN_VERIFIED: FALSE\n");

                    // Extract the actual domain from URL
                    if let Ok(parsed_url) = url::Url::parse(url) {
                        if let Some(domain) = parsed_url.domain() {
                            result.push_str(&format!("ACTUAL_DOMAIN: {domain}\n"));
                        }
                    }

                    result.push_str("\nDETAILED_EXPLANATION:\n");
                    result.push_str("The URL is valid but points to a domain other than LinkedIn. This validator specifically checks LinkedIn profile URLs. ");
                    result.push_str("The domain must be either 'linkedin.com' or 'www.linkedin.com' to be considered valid.\n");

                    result.push_str("\nSUGGESTED_ACTIONS:\n");
                    result.push_str(
                        "1. Replace the domain with 'linkedin.com' or 'www.linkedin.com'\n",
                    );
                    result.push_str(
                        "2. Verify you have the correct URL from the LinkedIn platform\n",
                    );
                    result.push_str(
                        "3. Check if the URL was copied correctly without modification\n",
                    );
                    result.push_str("4. If this is a different social media profile, use appropriate validators\n");
                    result.push_str(
                        "5. Ensure the URL is not from a LinkedIn clone or phishing site\n",
                    );

                    result.push_str("\nRECOMMENDED_NEXT_STEP: Obtain the correct LinkedIn profile URL from the official LinkedIn website\n");
                }
                LinkedInUrlError::NotProfileUrl => {
                    result.push_str("ERROR_TYPE: NOT_PROFILE_URL\n");
                    result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
                    result.push_str("ERROR_SEVERITY: MEDIUM\n");
                    result.push_str("PROFILE_EXISTS: NOT_APPLICABLE\n");
                    result.push_str("URL_FORMAT: VALID\n");
                    result.push_str("DOMAIN_VERIFIED: TRUE\n");
                    result.push_str("URL_TYPE: NON_PROFILE_LINKEDIN_URL\n");

                    result.push_str("\nDETAILED_EXPLANATION:\n");
                    result.push_str("The URL is from LinkedIn but does not point to a user profile. It may be a company page, job listing, or other LinkedIn content. ");
                    result.push_str("This validator specifically checks for personal profile URLs that follow the pattern '/in/username'.\n");

                    result.push_str("\nSUGGESTED_ACTIONS:\n");
                    result.push_str("1. Navigate to the person's LinkedIn profile and copy the URL from there\n");
                    result.push_str(
                        "2. Look for URLs that contain '/in/' followed by the username\n",
                    );
                    result.push_str("3. If this is a company page, note that company validation requires different logic\n");
                    result.push_str(
                        "4. Check if you need to be logged in to LinkedIn to access the profile\n",
                    );
                    result.push_str(
                        "5. Verify the profile URL format: https://linkedin.com/in/[username]\n",
                    );

                    result.push_str("\nRECOMMENDED_NEXT_STEP: Find the personal profile URL that includes '/in/' in the path\n");
                }
                LinkedInUrlError::ProfileNotFound => {
                    result.push_str("ERROR_TYPE: PROFILE_NOT_FOUND\n");
                    result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
                    result.push_str("ERROR_SEVERITY: HIGH\n");
                    result.push_str("PROFILE_EXISTS: FALSE\n");
                    result.push_str("URL_FORMAT: VALID\n");
                    result.push_str("DOMAIN_VERIFIED: TRUE\n");
                    result.push_str("HTTP_STATUS: 404\n");

                    result.push_str("\nDETAILED_EXPLANATION:\n");
                    result.push_str("The URL format is correct and points to LinkedIn, but the profile does not exist. ");
                    result.push_str("This could mean the profile was deleted, the username was changed, or there's a typo in the username. ");
                    result.push_str(
                        "LinkedIn returned a 404 (Not Found) response for this profile URL.\n",
                    );

                    result.push_str("\nSUGGESTED_ACTIONS:\n");
                    result.push_str(
                        "1. Double-check the username for typos or case sensitivity issues\n",
                    );
                    result.push_str("2. Search for the person on LinkedIn using their name instead of direct URL\n");
                    result.push_str("3. Ask the person for their current LinkedIn profile URL\n");
                    result.push_str(
                        "4. Check if the profile might have been recently deleted or deactivated\n",
                    );
                    result.push_str(
                        "5. Try variations of the username (with/without hyphens, numbers, etc.)\n",
                    );
                    result.push_str(
                        "6. Verify if the person has privacy settings that hide their profile\n",
                    );
                    result.push_str(
                        "7. Consider that the profile might have moved to a different username\n",
                    );

                    result.push_str("\nRECOMMENDED_NEXT_STEP: Search for the person on LinkedIn by name or request their current profile URL\n");
                }
                LinkedInUrlError::AuthenticationRequired => {
                    result.push_str("ERROR_TYPE: AUTH_REQUIRED\n");
                    result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
                    result.push_str("ERROR_SEVERITY: MEDIUM\n");
                    result.push_str("PROFILE_EXISTS: UNKNOWN\n");
                    result.push_str("URL_FORMAT: VALID\n");
                    result.push_str("DOMAIN_VERIFIED: TRUE\n");
                    result.push_str("HTTP_STATUS: 999\n");
                    result.push_str("LINKEDIN_RESPONSE: AUTHENTICATION_WALL\n");

                    result.push_str("\nDETAILED_EXPLANATION:\n");
                    result.push_str("LinkedIn is requiring authentication to verify this profile. This is a protective measure LinkedIn uses to prevent automated access. ");
                    result.push_str("The HTTP 999 status code is LinkedIn's custom response for requests that appear to be automated. ");
                    result.push_str("The profile format is valid and the profile LIKELY EXISTS, but LinkedIn is preventing automated verification.\n");

                    result.push_str("\nSUGGESTED_ACTIONS:\n");
                    result.push_str(
                        "1. ACCEPT AS VALID: The URL format is correct and points to LinkedIn - treat as valid profile URL\n",
                    );
                    result.push_str(
                        "2. RETRY LATER: Wait 30-60 seconds before trying to validate this URL again\n",
                    );
                    result.push_str("3. CONTINUE SEARCH: This URL is likely correct, but continue searching for alternative profiles if needed\n");
                    result.push_str("4. CONFIDENCE: HIGH - LinkedIn auth walls usually indicate real profiles\n");
                    result.push_str("5. FOR AI AGENTS: You can safely return this URL as a valid LinkedIn profile\n");
                    result.push_str(
                        "6. VERIFICATION: The URL follows pattern https://linkedin.com/in/USERNAME which is correct\n",
                    );
                    result.push_str(
                        "7. RECOMMENDATION: Use this URL - it's almost certainly a valid profile\n",
                    );

                    result.push_str("\nRECOMMENDED_NEXT_STEP: ACCEPT this URL as valid - LinkedIn authentication requirements typically indicate the profile exists\n");
                }
                LinkedInUrlError::NetworkError(ref network_err) => {
                    result.push_str("ERROR_TYPE: NETWORK_ERROR\n");
                    result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
                    result.push_str(&format!("NETWORK_ERROR_DETAILS: {network_err}\n"));
                    result.push_str("ERROR_SEVERITY: HIGH\n");
                    result.push_str("PROFILE_EXISTS: UNKNOWN\n");
                    result.push_str("NETWORK_STATUS: FAILED\n");

                    result.push_str("\nDETAILED_EXPLANATION:\n");
                    result.push_str("A network error occurred while trying to reach LinkedIn. This could be due to connectivity issues, ");
                    result.push_str("DNS resolution problems, timeouts, or LinkedIn being temporarily unavailable. ");
                    result.push_str("The validation could not be completed due to this network-level failure.\n");

                    result.push_str("\nSUGGESTED_ACTIONS:\n");
                    result.push_str("1. Check your internet connection and try again\n");
                    result.push_str("2. Verify DNS resolution for linkedin.com is working\n");
                    result
                        .push_str("3. Check if LinkedIn is accessible from your network/region\n");
                    result.push_str(
                        "4. Retry the request after a short delay (exponential backoff)\n",
                    );
                    result
                        .push_str("5. Check for firewall or proxy settings blocking the request\n");
                    result.push_str("6. Verify SSL/TLS certificates are up to date\n");
                    result.push_str(
                        "7. Consider using a different network or VPN if the issue persists\n",
                    );

                    result.push_str("\nRECOMMENDED_NEXT_STEP: Diagnose network connectivity and retry the validation\n");
                }
                LinkedInUrlError::ClientBuildError(ref msg) => {
                    result.push_str("ERROR_TYPE: CLIENT_BUILD_ERROR\n");
                    result.push_str(&format!("ERROR_MESSAGE: {e}\n"));
                    result.push_str(&format!("ERROR_DETAILS: {msg}\n"));
                    result.push_str("ERROR_SEVERITY: CRITICAL\n");
                    result.push_str("VALIDATION_STATUS: FAILED\n");

                    result.push_str("\nDETAILED_EXPLANATION:\n");
                    result.push_str("Failed to create the HTTP client needed for validation. This is typically caused by system resource constraints ");
                    result.push_str("or TLS configuration issues. The validation cannot proceed without a working HTTP client.\n");

                    result.push_str("\nSUGGESTED_ACTIONS:\n");
                    result.push_str("1. Check available system memory and resources\n");
                    result.push_str("2. Verify TLS/SSL libraries are properly installed\n");
                    result.push_str("3. Check for system-level network restrictions\n");
                    result.push_str("4. Restart the application or service\n");
                    result.push_str("5. Review system logs for more detailed error information\n");

                    result.push_str("\nRECOMMENDED_NEXT_STEP: Resolve system-level issues before attempting validation\n");
                }
            }
        }
    }

    result.push_str("\n=== END OF VALIDATION REPORT ===\n");
    result
}

/// Checks if a URL has valid `LinkedIn` profile format without making network calls.
///
/// This function only validates the URL format and does not check if the profile exists.
/// Use this for quick validation without network overhead.
///
/// # Arguments
///
/// * `url` - The URL to validate
///
/// # Returns
///
/// * `true` - If the URL has valid `LinkedIn` profile format
/// * `false` - If the URL is invalid or not a `LinkedIn` profile URL
///
/// # Example
///
/// ```
/// use credify::is_valid_linkedin_profile_format;
///
/// assert!(is_valid_linkedin_profile_format("https://www.linkedin.com/in/johndoe"));
/// assert!(!is_valid_linkedin_profile_format("https://www.google.com/in/johndoe"));
/// assert!(!is_valid_linkedin_profile_format("https://linkedin.com/company/microsoft"));
/// ```
#[must_use]
pub fn is_valid_linkedin_profile_format(url: &str) -> bool {
    let Ok(url_parsed) = Url::parse(url) else {
        return false;
    };

    is_linkedin_domain(&url_parsed) && is_profile_path(&url_parsed)
}

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

    #[test]
    fn test_valid_profile_format() {
        // Test with real valid profiles
        assert!(is_valid_linkedin_profile_format(
            "https://www.linkedin.com/in/hamze/"
        ));
        assert!(is_valid_linkedin_profile_format(
            "https://www.linkedin.com/in/hamzeghalebi/"
        ));
        assert!(is_valid_linkedin_profile_format(
            "https://www.linkedin.com/in/johndoe"
        ));
        assert!(is_valid_linkedin_profile_format(
            "https://linkedin.com/in/jane-doe"
        ));
        assert!(is_valid_linkedin_profile_format(
            "https://www.linkedin.com/in/john-doe-123/"
        ));
    }

    #[test]
    fn test_invalid_profile_format() {
        assert!(!is_valid_linkedin_profile_format(
            "https://www.google.com/in/johndoe"
        ));
        assert!(!is_valid_linkedin_profile_format(
            "https://linkedin.com/company/microsoft"
        ));
        assert!(!is_valid_linkedin_profile_format("https://linkedin.com/"));
        assert!(!is_valid_linkedin_profile_format("not-a-url"));
    }

    #[test]
    fn test_real_valid_profile() {
        let validator = match LinkedInValidator::new() {
            Ok(v) => v,
            Err(e) => {
                eprintln!("[TEST_SETUP_ERROR] Failed to create validator: {e}");
                return;
            }
        };
        // This is a valid LinkedIn profile
        match validator.is_valid_linkedin_profile_url("https://www.linkedin.com/in/hamze/") {
            Ok(true) => (),
            Ok(false) => eprintln!("[TEST_FAILED] Expected profile to be valid but got false"),
            Err(LinkedInUrlError::AuthenticationRequired) => {
                println!("[AUTH_REQUIRED] LinkedIn requires authentication - cannot verify profile existence");
            }
            Err(e) => eprintln!(
                "[TEST_FAILED] Expected profile to be valid or require auth, got error: {e}"
            ),
        }
    }

    #[test]
    fn test_real_invalid_profile() {
        let validator = match LinkedInValidator::new() {
            Ok(v) => v,
            Err(e) => {
                eprintln!("[TEST_SETUP_ERROR] Failed to create validator: {e}");
                return;
            }
        };
        // This LinkedIn profile doesn't exist - LinkedIn shows error page
        match validator.is_valid_linkedin_profile_url("https://www.linkedin.com/in/hamzeghalebi/") {
            Ok(_) => {
                // LinkedIn might be allowing access sometimes, especially after multiple requests
                // This is inconsistent behavior from LinkedIn
                println!("[WARNING] LinkedIn allowed access to profile page - cannot determine if profile actually exists");
            }
            Err(LinkedInUrlError::ProfileNotFound) => (),
            Err(LinkedInUrlError::AuthenticationRequired) => {
                println!("[AUTH_REQUIRED] LinkedIn requires authentication - cannot verify profile existence");
            }
            Err(e) => eprintln!(
                "[TEST_FAILED] Expected ProfileNotFound or AuthenticationRequired error, got: {e}"
            ),
        }
    }

    #[tokio::test]
    async fn test_async_valid_profile() {
        // Test async validation with valid profile
        match validate_linkedin_url_async("https://www.linkedin.com/in/hamze/").await {
            Ok(true) => (),
            Ok(false) => eprintln!("[TEST_FAILED] Expected profile to be valid but got false"),
            Err(LinkedInUrlError::AuthenticationRequired) => {
                println!("[AUTH_REQUIRED] LinkedIn requires authentication - cannot verify profile existence");
            }
            Err(e) => eprintln!(
                "[TEST_FAILED] Expected profile to be valid or require auth, got error: {e}"
            ),
        }
    }

    #[tokio::test]
    async fn test_async_invalid_profile() {
        // Test async validation with invalid profile that shows error page
        match validate_linkedin_url_async("https://www.linkedin.com/in/hamzeghalebi/").await {
            Ok(_) => {
                // LinkedIn might be allowing access sometimes, especially after multiple requests
                // This is inconsistent behavior from LinkedIn
                println!("[WARNING] LinkedIn allowed access to profile page - cannot determine if profile actually exists");
            }
            Err(LinkedInUrlError::ProfileNotFound) => (),
            Err(LinkedInUrlError::AuthenticationRequired) => {
                println!("[AUTH_REQUIRED] LinkedIn requires authentication - cannot verify profile existence");
            }
            Err(e) => eprintln!(
                "[TEST_FAILED] Expected ProfileNotFound or AuthenticationRequired error, got: {e}"
            ),
        }
    }

    #[test]
    fn test_validate_for_llm_success() {
        let result = validate_for_llm("https://www.linkedin.com/in/valid-format");
        assert!(result.contains("VALIDATION_RESULT:"));
        assert!(result.contains("SUGGESTED_ACTIONS:"));
        assert!(result.contains("=== LINKEDIN PROFILE VALIDATION REPORT ==="));
        assert!(result.contains("TIMESTAMP:"));
        assert!(result.contains("INPUT_URL:"));
    }

    #[test]
    fn test_validate_for_llm_invalid_url() {
        let result = validate_for_llm("not-a-url");
        assert!(result.contains("VALIDATION_RESULT: ERROR"));
        assert!(result.contains("ERROR_TYPE: INVALID_URL_FORMAT"));
        assert!(result.contains("SUGGESTED_ACTIONS:"));
        assert!(result.contains("ERROR_SEVERITY: HIGH"));
        assert!(result.contains("DETAILED_EXPLANATION:"));
    }

    #[test]
    fn test_validate_for_llm_not_linkedin() {
        let result = validate_for_llm("https://www.google.com/in/someone");
        assert!(result.contains("VALIDATION_RESULT: ERROR"));
        assert!(result.contains("ERROR_TYPE: NOT_LINKEDIN_DOMAIN"));
        assert!(result.contains("SUGGESTED_ACTIONS:"));
        assert!(result.contains("ERROR_SEVERITY: MEDIUM"));
        assert!(result.contains("ACTUAL_DOMAIN: www.google.com"));
    }

    #[test]
    fn test_validate_for_llm_not_profile() {
        let result = validate_for_llm("https://www.linkedin.com/company/microsoft");
        assert!(result.contains("VALIDATION_RESULT: ERROR"));
        assert!(result.contains("ERROR_TYPE: NOT_PROFILE_URL"));
        assert!(result.contains("SUGGESTED_ACTIONS:"));
        assert!(result.contains("URL_TYPE: NON_PROFILE_LINKEDIN_URL"));
        assert!(result.contains("RECOMMENDED_NEXT_STEP:"));
    }

    #[tokio::test]
    async fn test_validate_for_llm_async() {
        let result = validate_for_llm_async("https://www.linkedin.com/in/test-user").await;
        assert!(result.contains("VALIDATION_RESULT:"));
        assert!(result.contains("SUGGESTED_ACTIONS:"));
        assert!(result.contains("=== LINKEDIN PROFILE VALIDATION REPORT ==="));
        assert!(result.contains("TIMESTAMP:"));
        assert!(result.contains("=== END OF VALIDATION REPORT ==="));
    }

    #[test]
    #[ignore = "Debug test to inspect LinkedIn response"]
    fn debug_linkedin_response() {
        let client = match reqwest::blocking::Client::builder()
            .user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36")
            .timeout(std::time::Duration::from_secs(10))
            .build()
        {
            Ok(c) => c,
            Err(e) => {
                eprintln!("[CLIENT_BUILD_ERROR] Failed to build client: {e}");
                return;
            }
        };

        let url = "https://www.linkedin.com/in/hamzeghalebi/";
        let response = match client.get(url).send() {
            Ok(r) => r,
            Err(e) => {
                eprintln!("[NETWORK_ERROR] Failed to send request: {e}");
                return;
            }
        };

        println!("Status: {}", response.status());
        println!("Final URL: {}", response.url());

        match response.text() {
            Ok(body) => {
                println!("Body length: {}", body.len());
                println!(
                    "First 2000 chars:\n{}",
                    &body.chars().take(2000).collect::<String>()
                );
            }
            Err(e) => eprintln!("[RESPONSE_ERROR] Failed to read response body: {e}"),
        }
    }
}

// ============================================================================
// AI AGENT OPTIMIZED API
// ============================================================================

/// AI-agent friendly validation result with structured data
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AIValidationResult {
    /// Simple boolean: is this a valid LinkedIn profile URL?
    pub is_valid: bool,

    /// Confidence level (0.0 to 1.0)
    pub confidence: f32,

    /// Decision for AI agent
    pub decision: AIDecision,

    /// Extracted username if available
    pub username: Option<String>,

    /// Human-readable reason
    pub reason: String,

    /// Detailed metadata
    pub metadata: ValidationMetadata,
}

/// Simple decision enum for AI agents
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
pub enum AIDecision {
    /// Definitely use this URL
    Accept,
    /// Try again later
    Retry,
    /// Search for a different URL
    Reject,
}

/// Validation metadata for advanced AI agents
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidationMetadata {
    pub url_format_valid: bool,
    pub domain_verified: bool,
    pub profile_pattern_matched: bool,
    pub http_status: Option<u16>,
    pub error_type: Option<String>,
    pub timestamp: String,
}

/// Validate LinkedIn URL optimized for AI agents (sync version)
///
/// This function is specifically designed for AI agents using function calling.
/// It returns a structured result that's easy to parse and make decisions with.
///
/// # Example
///
/// ```no_run
/// use credify::ai_validate;
///
/// let result = ai_validate("https://linkedin.com/in/johndoe");
/// if result.is_valid {
///     println!("Valid profile with confidence: {}", result.confidence);
/// }
/// ```
pub fn ai_validate(url: &str) -> AIValidationResult {
    let timestamp = chrono::Utc::now().to_rfc3339();

    // First check URL format
    let parsed_url = match Url::parse(url) {
        Ok(u) => u,
        Err(e) => {
            return AIValidationResult {
                is_valid: false,
                confidence: 1.0,
                decision: AIDecision::Reject,
                username: None,
                reason: format!("Invalid URL format: {e}"),
                metadata: ValidationMetadata {
                    url_format_valid: false,
                    domain_verified: false,
                    profile_pattern_matched: false,
                    http_status: None,
                    error_type: Some("INVALID_URL".to_string()),
                    timestamp,
                },
            };
        }
    };

    // Check domain
    let domain_valid = is_linkedin_domain(&parsed_url);
    if !domain_valid {
        return AIValidationResult {
            is_valid: false,
            confidence: 1.0,
            decision: AIDecision::Reject,
            username: None,
            reason: "Not a LinkedIn URL".to_string(),
            metadata: ValidationMetadata {
                url_format_valid: true,
                domain_verified: false,
                profile_pattern_matched: false,
                http_status: None,
                error_type: Some("WRONG_DOMAIN".to_string()),
                timestamp,
            },
        };
    }

    // Check profile pattern
    let is_profile = is_profile_path(&parsed_url);
    if !is_profile {
        return AIValidationResult {
            is_valid: false,
            confidence: 0.95,
            decision: AIDecision::Reject,
            username: None,
            reason: "LinkedIn URL but not a profile (might be company page)".to_string(),
            metadata: ValidationMetadata {
                url_format_valid: true,
                domain_verified: true,
                profile_pattern_matched: false,
                http_status: None,
                error_type: Some("NOT_PROFILE".to_string()),
                timestamp,
            },
        };
    }

    // Extract username
    let username = parsed_url
        .path_segments()
        .and_then(|mut segments| {
            // Skip to "in" then get next segment
            if segments.next() == Some("in") {
                segments.next()
            } else {
                None
            }
        })
        .filter(|u| !u.is_empty())
        .map(|u| u.trim_end_matches('/').to_string());

    // Try to validate with HTTP request
    let validator = match LinkedInValidator::new() {
        Ok(v) => v,
        Err(_) => {
            // Can't create validator, but URL format is good
            return AIValidationResult {
                is_valid: true,
                confidence: 0.7,
                decision: AIDecision::Accept,
                username,
                reason: "URL format is valid (network check unavailable)".to_string(),
                metadata: ValidationMetadata {
                    url_format_valid: true,
                    domain_verified: true,
                    profile_pattern_matched: true,
                    http_status: None,
                    error_type: Some("VALIDATOR_ERROR".to_string()),
                    timestamp,
                },
            };
        }
    };

    // Perform actual validation
    match validator.is_valid_linkedin_profile_url(url) {
        Ok(_) => AIValidationResult {
            is_valid: true,
            confidence: 1.0,
            decision: AIDecision::Accept,
            username,
            reason: "Verified LinkedIn profile exists".to_string(),
            metadata: ValidationMetadata {
                url_format_valid: true,
                domain_verified: true,
                profile_pattern_matched: true,
                http_status: Some(200),
                error_type: None,
                timestamp,
            },
        },
        Err(LinkedInUrlError::AuthenticationRequired) => {
            // This is actually a GOOD sign - LinkedIn auth walls mean real profiles
            AIValidationResult {
                is_valid: true,
                confidence: 0.9,
                decision: AIDecision::Accept,
                username,
                reason: "LinkedIn profile likely exists (auth required)".to_string(),
                metadata: ValidationMetadata {
                    url_format_valid: true,
                    domain_verified: true,
                    profile_pattern_matched: true,
                    http_status: Some(999),
                    error_type: Some("AUTH_REQUIRED".to_string()),
                    timestamp,
                },
            }
        }
        Err(LinkedInUrlError::ProfileNotFound) => AIValidationResult {
            is_valid: false,
            confidence: 0.95,
            decision: AIDecision::Reject,
            username,
            reason: "LinkedIn profile does not exist (404)".to_string(),
            metadata: ValidationMetadata {
                url_format_valid: true,
                domain_verified: true,
                profile_pattern_matched: true,
                http_status: Some(404),
                error_type: Some("NOT_FOUND".to_string()),
                timestamp,
            },
        },
        Err(LinkedInUrlError::NetworkError(_)) => AIValidationResult {
            is_valid: true,
            confidence: 0.6,
            decision: AIDecision::Retry,
            username,
            reason: "Network error - retry later".to_string(),
            metadata: ValidationMetadata {
                url_format_valid: true,
                domain_verified: true,
                profile_pattern_matched: true,
                http_status: None,
                error_type: Some("NETWORK_ERROR".to_string()),
                timestamp,
            },
        },
        Err(e) => AIValidationResult {
            is_valid: false,
            confidence: 0.2,
            decision: AIDecision::Reject,
            username,
            reason: format!("Validation error: {e}"),
            metadata: ValidationMetadata {
                url_format_valid: true,
                domain_verified: true,
                profile_pattern_matched: true,
                http_status: None,
                error_type: Some("OTHER_ERROR".to_string()),
                timestamp,
            },
        },
    }
}

/// Async version of ai_validate
pub async fn ai_validate_async(url: &str) -> AIValidationResult {
    let timestamp = chrono::Utc::now().to_rfc3339();

    // First check URL format
    let parsed_url = match Url::parse(url) {
        Ok(u) => u,
        Err(e) => {
            return AIValidationResult {
                is_valid: false,
                confidence: 1.0,
                decision: AIDecision::Reject,
                username: None,
                reason: format!("Invalid URL format: {e}"),
                metadata: ValidationMetadata {
                    url_format_valid: false,
                    domain_verified: false,
                    profile_pattern_matched: false,
                    http_status: None,
                    error_type: Some("INVALID_URL".to_string()),
                    timestamp,
                },
            };
        }
    };

    // Check domain
    let domain_valid = is_linkedin_domain(&parsed_url);
    if !domain_valid {
        return AIValidationResult {
            is_valid: false,
            confidence: 1.0,
            decision: AIDecision::Reject,
            username: None,
            reason: "Not a LinkedIn URL".to_string(),
            metadata: ValidationMetadata {
                url_format_valid: true,
                domain_verified: false,
                profile_pattern_matched: false,
                http_status: None,
                error_type: Some("WRONG_DOMAIN".to_string()),
                timestamp,
            },
        };
    }

    // Check profile pattern
    let is_profile = is_profile_path(&parsed_url);
    if !is_profile {
        return AIValidationResult {
            is_valid: false,
            confidence: 0.95,
            decision: AIDecision::Reject,
            username: None,
            reason: "LinkedIn URL but not a profile (might be company page)".to_string(),
            metadata: ValidationMetadata {
                url_format_valid: true,
                domain_verified: true,
                profile_pattern_matched: false,
                http_status: None,
                error_type: Some("NOT_PROFILE".to_string()),
                timestamp,
            },
        };
    }

    // Extract username
    let username = parsed_url
        .path_segments()
        .and_then(|mut segments| {
            // Skip to "in" then get next segment
            if segments.next() == Some("in") {
                segments.next()
            } else {
                None
            }
        })
        .filter(|u| !u.is_empty())
        .map(|u| u.trim_end_matches('/').to_string());

    // Perform actual validation
    match validate_linkedin_url_async(url).await {
        Ok(_) => AIValidationResult {
            is_valid: true,
            confidence: 1.0,
            decision: AIDecision::Accept,
            username,
            reason: "Verified LinkedIn profile exists".to_string(),
            metadata: ValidationMetadata {
                url_format_valid: true,
                domain_verified: true,
                profile_pattern_matched: true,
                http_status: Some(200),
                error_type: None,
                timestamp,
            },
        },
        Err(LinkedInUrlError::AuthenticationRequired) => {
            // This is actually a GOOD sign - LinkedIn auth walls mean real profiles
            AIValidationResult {
                is_valid: true,
                confidence: 0.9,
                decision: AIDecision::Accept,
                username,
                reason: "LinkedIn profile likely exists (auth required)".to_string(),
                metadata: ValidationMetadata {
                    url_format_valid: true,
                    domain_verified: true,
                    profile_pattern_matched: true,
                    http_status: Some(999),
                    error_type: Some("AUTH_REQUIRED".to_string()),
                    timestamp,
                },
            }
        }
        Err(LinkedInUrlError::ProfileNotFound) => AIValidationResult {
            is_valid: false,
            confidence: 0.95,
            decision: AIDecision::Reject,
            username,
            reason: "LinkedIn profile does not exist (404)".to_string(),
            metadata: ValidationMetadata {
                url_format_valid: true,
                domain_verified: true,
                profile_pattern_matched: true,
                http_status: Some(404),
                error_type: Some("NOT_FOUND".to_string()),
                timestamp,
            },
        },
        Err(LinkedInUrlError::NetworkError(_)) => AIValidationResult {
            is_valid: true,
            confidence: 0.6,
            decision: AIDecision::Retry,
            username,
            reason: "Network error - retry later".to_string(),
            metadata: ValidationMetadata {
                url_format_valid: true,
                domain_verified: true,
                profile_pattern_matched: true,
                http_status: None,
                error_type: Some("NETWORK_ERROR".to_string()),
                timestamp,
            },
        },
        Err(e) => AIValidationResult {
            is_valid: false,
            confidence: 0.2,
            decision: AIDecision::Reject,
            username,
            reason: format!("Validation error: {e}"),
            metadata: ValidationMetadata {
                url_format_valid: true,
                domain_verified: true,
                profile_pattern_matched: true,
                http_status: None,
                error_type: Some("OTHER_ERROR".to_string()),
                timestamp,
            },
        },
    }
}

/// Get validation result as JSON for AI agents
pub fn ai_validate_json(url: &str) -> String {
    let result = ai_validate(url);
    serde_json::to_string_pretty(&result).unwrap_or_else(|_| {
        json!({
            "error": "Failed to serialize result",
            "is_valid": false
        })
        .to_string()
    })
}

/// Async version of ai_validate_json
pub async fn ai_validate_json_async(url: &str) -> String {
    let result = ai_validate_async(url).await;
    serde_json::to_string_pretty(&result).unwrap_or_else(|_| {
        json!({
            "error": "Failed to serialize result",
            "is_valid": false
        })
        .to_string()
    })
}
