use rustelo_core_lib::i18n::language_config::get_language_registry;
use rustelo_core_lib::routing::engine::*;

#[test]
fn test_routing_engine_creation() {
    let engine = RoutingEngine::new();
    // We can't access private fields, but we can test that it creates successfully
    // and test its public methods work
    assert!(engine.route_exists("/") || engine.route_exists("/es"));
}

#[test]
fn test_route_resolution() {
    let resolved = resolve_route("/");
    assert!(resolved.exists);
    assert!(resolved.component.is_some());
}

#[test]
fn test_language_routes() {
    let language_registry = get_language_registry();
    let available_languages = language_registry.get_available_languages();
    let default_language = language_registry.get_default_language();

    // Test default language route
    let resolved_default = resolve_route("/");
    assert_eq!(resolved_default.language, default_language);
    assert!(resolved_default.component.is_some());

    // Test other language routes
    for language in &available_languages {
        if language != default_language {
            let test_path = format!("/{language}");
            let resolved = resolve_route(&test_path);
            assert_eq!(resolved.language, *language);
        }
    }
}

#[test]
fn test_navigation_generation() {
    let mut engine = RoutingEngine::new();
    let language_registry = get_language_registry();
    let default_language = language_registry.get_default_language();

    let nav_items = engine.get_navigation_items(default_language);

    // Debug info if test fails
    if nav_items.is_empty() {
        tracing::debug!(
            "No navigation items found for language: {}",
            default_language
        );
        // We can't access private fields anymore, but we can check
        // that routes exist using public methods
        let toml_routes = get_toml_routes_for_language(default_language);
        tracing::debug!(
            "Available TOML routes for {}: {}",
            default_language,
            toml_routes.len()
        );
    }

    assert!(
        !nav_items.is_empty(),
        "Navigation items should not be empty for language: {default_language}"
    );

    // Check that items have required fields
    for item in &nav_items {
        assert!(
            !item.label.is_empty(),
            "Navigation item label should not be empty"
        );
        match &item.target {
            NavigationTarget::Route(path) => {
                assert!(
                    path.starts_with('/'),
                    "Internal route path '{path}' should start with '/'"
                );
            }
            NavigationTarget::External(url) => {
                assert!(
                    url.starts_with("http"),
                    "External URL '{url}' should start with 'http'"
                );
            }
            _ => {} // Other types (email, phone) are valid too
        }
    }

    tracing::debug!(
        "Navigation test passed with {} items for language {}",
        nav_items.len(),
        default_language
    );
}

#[test]
fn test_global_routing_engine() {
    let engine1 = get_routing_engine();
    let engine2 = get_routing_engine();

    // Should return the same instance
    assert!(std::ptr::eq(engine1, engine2));
}

#[test]
fn test_generic_content_existence_checking() {
    // Since content_exists is now in a separate module and not exposed as a public
    // method, we can test it indirectly through route resolution
    use rustelo_core_lib::routing::engine::content::content_exists;

    // Test generic content existence checking with valid content types
    // Skip test if content directory is not accessible (e.g., in minimal test
    // environments)
    let valid_types = match std::panic::catch_unwind(
        rustelo_core_lib::content_resolver::get_available_content_types,
    ) {
        Ok(types) => types,
        Err(_) => {
            println!("Skipping test - content directory not accessible");
            return;
        }
    };

    for content_type in &valid_types {
        // Test basic slug validation
        assert!(
            !content_exists(content_type, "", "en"),
            "Empty slug should be invalid"
        );
        assert!(
            !content_exists(content_type, "ab", "en"),
            "Too short slug should be invalid"
        );
        assert!(
            !content_exists(content_type, "-invalid", "en"),
            "Slug starting with dash should be invalid"
        );
        assert!(
            !content_exists(content_type, "invalid-", "en"),
            "Slug ending with dash should be invalid"
        );

        // Test valid slug format
        assert!(
            content_exists(content_type, "valid-content-slug", "en"),
            "Valid slug should pass basic validation"
        );
    }

    // Test invalid content type
    assert!(
        !content_exists("invalid-content-type", "valid-slug", "en"),
        "Invalid content type should return false"
    );
}

#[test]
fn test_sitemap_generation() {
    let sitemap_entries = get_sitemap_routes();
    assert!(!sitemap_entries.is_empty());

    for entry in sitemap_entries {
        assert!(entry.url.starts_with("http"));
        assert!(!entry.language.is_empty());
    }
}

#[test]
fn test_route_validation() {
    assert!(is_valid_route("/"));
    assert!(!is_valid_route("/completely-nonexistent-route-12345"));
}

#[test]
fn test_language_switching() {
    let language_registry = get_language_registry();
    let available_languages = language_registry.get_available_languages();

    if available_languages.len() > 1 {
        let source_lang = &available_languages[0];
        let target_lang = &available_languages[1];

        let switch_url = get_language_switch_url("/", target_lang);
        assert!(!switch_url.is_empty());

        // Should be different from original path for different languages
        if source_lang != target_lang {
            assert_ne!(switch_url, "/");
        }
    }
}
