//! Factory methods for creating route resolutions
//!
//! This module contains all the factory methods for creating different types
//! of route resolutions based on various inputs.

use std::collections::HashMap;
use std::str::FromStr;

use rustelo_core_types::rendering::resolve_rendering_profile;

use super::types::{RouteMetadata, RouteResolution};
use crate::routing::components::{RouteComponent, RouteConfigToml};

/// Create route resolution from TOML route configuration
pub fn create_resolution_from_toml_route(
    toml_route: &RouteConfigToml,
    original_path: &str,
    language: &str,
) -> RouteResolution {
    #[cfg(not(target_arch = "wasm32"))]
    tracing::debug!(
        "🔧 ROUTING: Creating resolution for route '{}' -> component '{}'",
        toml_route.path,
        toml_route.component
    );

    let metadata = RouteMetadata {
        title: Some(toml_route.title_key.clone()),
        description: toml_route.description_key.clone(),
        keywords: toml_route.keywords.clone().unwrap_or_default(),
        language: language.to_string(),
        canonical_path: toml_route
            .canonical_path
            .clone()
            .unwrap_or_else(|| toml_route.path.clone()),
    };

    let route_component = toml_route.to_route_component();

    #[cfg(not(target_arch = "wasm32"))]
    tracing::debug!(
        "🔧 ROUTING: Route component converted: '{}' -> {:?}",
        toml_route.component,
        route_component
    );

    // Extract parameters from route props (especially content_type)
    let mut parameters = HashMap::new();

    // Add content_type if specified in route props
    if let Some(content_type) = toml_route.get_content_type() {
        #[cfg(not(target_arch = "wasm32"))]
        tracing::debug!(
            "🔧 ROUTING: Adding content_type parameter: '{}' for route '{}'",
            content_type,
            toml_route.path
        );
        parameters.insert("content_type".to_string(), content_type);
    }

    // Add any other properties from the route props section
    if let Some(ref props) = toml_route.props {
        for (key, value) in props {
            if key != "content_type" {
                // Don't duplicate content_type
                if let Some(string_value) = value.as_str() {
                    parameters.insert(key.clone(), string_value.to_string());
                }
            }
        }
    }

    let resolution = RouteResolution {
        path: original_path.to_string(),
        language: language.to_string(),
        component: Some(route_component),
        canonical_path: metadata.canonical_path.clone(),
        metadata,
        exists: true,
        parameters,
        rendering_profile: resolve_rendering_profile(toml_route.rendering_profile),
        template: toml_route.template.clone(),
    };

    #[cfg(not(target_arch = "wasm32"))]
    tracing::debug!(
        "🔧 ROUTING: Created resolution - path: '{}', exists: {}, component: {:?}",
        resolution.path,
        resolution.exists,
        resolution.component
    );

    resolution
}

/// Create parametric route resolution from TOML route configuration
pub fn create_parametric_resolution_from_toml_route(
    toml_route: &RouteConfigToml,
    original_path: &str,
    language: &str,
    category: Option<String>,
) -> RouteResolution {
    let metadata = RouteMetadata {
        title: Some(toml_route.title_key.clone()),
        description: toml_route.description_key.clone(),
        keywords: toml_route.keywords.clone().unwrap_or_default(),
        language: language.to_string(),
        canonical_path: toml_route
            .canonical_path
            .clone()
            .unwrap_or_else(|| toml_route.path.clone()),
    };

    let mut parameters = HashMap::new();
    if let Some(cat) = category {
        #[cfg(not(target_arch = "wasm32"))]
        tracing::info!("🔧 Storing category parameter: '{}'", cat);
        parameters.insert("category".to_string(), cat);
    }

    let resolution = RouteResolution {
        path: original_path.to_string(),
        language: language.to_string(),
        component: Some(toml_route.to_route_component()),
        canonical_path: metadata.canonical_path.clone(),
        metadata,
        exists: true,
        parameters,
        rendering_profile: resolve_rendering_profile(toml_route.rendering_profile),
        template: toml_route.template.clone(),
    };

    #[cfg(not(target_arch = "wasm32"))]
    tracing::info!(
        "🔧 Created RouteResolution with parameters: {:?}",
        resolution.parameters
    );
    resolution
}

/// Generic content post resolution creator - works with any content type
/// Uses the generated content type system to create proper resolutions
pub fn create_content_post_resolution(
    path: &str,
    language: &str,
    content_type: &str,
    slug: &str,
) -> RouteResolution {
    let mut parameters = HashMap::new();
    parameters.insert("slug".to_string(), slug.to_string());
    parameters.insert("content_type".to_string(), content_type.to_string());

    // Pure trait-based approach - use content provider to resolve component
    let component = match content_type {
        "blog" | "post" => RouteComponent::from_str("ContentPost").unwrap_or_default(),
        "page" => RouteComponent::from_str("ContentPage").unwrap_or_default(),
        _ => RouteComponent::NOT_FOUND,
    };

    RouteResolution {
        path: path.to_string(),
        language: language.to_string(),
        component: Some(component),
        canonical_path: path.to_string(),
        metadata: RouteMetadata {
            title: Some(format!("{}-post-title", content_type)),
            description: Some(format!("{}-post-description", content_type)),
            keywords: vec![content_type.to_string(), "post".to_string()],
            language: language.to_string(),
            canonical_path: path.to_string(),
        },
        exists: true,
        parameters,
        rendering_profile: resolve_rendering_profile(None),
        template: None,
    }
}

/// Create not found resolution
pub fn create_not_found_resolution(path: &str, language: &str) -> RouteResolution {
    let metadata = RouteMetadata {
        title: Some("not-found-title".to_string()),
        description: Some("not-found-description".to_string()),
        keywords: vec![],
        language: language.to_string(),
        canonical_path: path.to_string(),
    };

    RouteResolution {
        path: path.to_string(),
        language: language.to_string(),
        component: Some(RouteComponent::NOT_FOUND),
        canonical_path: path.to_string(),
        metadata,
        exists: false,
        parameters: HashMap::new(),
        rendering_profile: resolve_rendering_profile(None),
        template: None,
    }
}
