//! Rendering traits for routing abstraction
//!
//! This module defines the core traits that allow client and SSR systems
//! to implement their own rendering logic while sharing the same routing
//! engine.

use super::components::RouteComponent;

/// Trait for rendering route components in different contexts (client vs SSR)
pub trait RouteRenderer {
    /// The view type that this renderer produces
    type View;

    /// Render a route component to a view
    fn render_component(
        &self,
        component: &RouteComponent,
        path: &str,
        language: &str,
        parameters: &std::collections::HashMap<String, String>,
    ) -> Self::View;

    /// Render a not found page
    fn render_not_found(&self, path: &str, language: &str) -> Self::View;
}

/// Metadata provider trait for routes
pub trait RouteMetadataProvider {
    /// Get the page title for a route
    fn get_title(&self, component: &RouteComponent, language: &str) -> String;

    /// Get the page description for a route
    fn get_description(&self, component: &RouteComponent, language: &str) -> String;

    /// Get the page keywords for a route
    fn get_keywords(&self, component: &RouteComponent, language: &str) -> String;
}

/// Combined trait for route handling
pub trait RouteHandler: RouteRenderer + RouteMetadataProvider {
    /// Handle a route request, returning the rendered view and metadata
    fn handle_route(&self, path: &str) -> RouteResult<Self::View> {
        let route_info = crate::engine::resolve_route(path);

        match &route_info.component {
            Some(component) => RouteResult {
                view: self.render_component(
                    component,
                    &route_info.path,
                    &route_info.language,
                    &route_info.parameters,
                ),
                title: self.get_title(component, &route_info.language),
                description: self.get_description(component, &route_info.language),
                keywords: self.get_keywords(component, &route_info.language),
                language: route_info.language,
                canonical_path: route_info.canonical_path,
                is_not_found: false,
            },
            None => RouteResult {
                view: self.render_not_found(&route_info.path, &route_info.language),
                title: self.get_title(&RouteComponent::NOT_FOUND, &route_info.language),
                description: self.get_description(&RouteComponent::NOT_FOUND, &route_info.language),
                keywords: self.get_keywords(&RouteComponent::NOT_FOUND, &route_info.language),
                language: route_info.language,
                canonical_path: route_info.canonical_path,
                is_not_found: true,
            },
        }
    }
}

/// Result of handling a route
#[derive(Debug, Clone)]
pub struct RouteResult<V> {
    pub view: V,
    pub title: String,
    pub description: String,
    pub keywords: String,
    pub language: String,
    pub canonical_path: String,
    pub is_not_found: bool,
}

/// Route resolution information
#[derive(Debug, Clone)]
pub struct ResolvedRoute {
    pub path: String,
    pub language: String,
    pub canonical_path: String,
    pub component: Option<RouteComponent>,
}
