//! ContentRenderer trait for type-safe rendering without heterogeneous matching
//!
//! This trait eliminates the need for heterogeneous type matching in Leptos
//! views by providing unified rendering methods for all content types.

use leptos::prelude::*;
use rustelo_components_leptos::content::card::UnifiedContentCard;
use rustelo_core_lib::{
    content::{ContentItemTrait, UnifiedContentItem},
    create_content_kind_registry,
};

use crate::content::helpers::ContentPageConfig;

/// Type-safe content renderer trait that eliminates heterogeneous matching
pub trait ContentRenderer {
    /// Render a single content item as a card view
    fn render_content_card(&self, config: &ContentPageConfig, language: &str) -> AnyView;

    /// Render featured content item with enhanced styling
    fn render_featured_content(&self, config: &ContentPageConfig, language: &str) -> AnyView;

    /// Check if this item should be featured
    fn is_featured(&self) -> bool;

    /// Get the category for filtering purposes
    fn get_category(&self) -> Option<&str>;

    /// Get title for display
    fn get_title(&self) -> &str;

    /// Get excerpt for display
    fn get_excerpt(&self) -> Option<&str>;

    /// Get date for display
    fn get_date(&self) -> Option<&str>;
}

/// Implementation for UnifiedContentItem
impl ContentRenderer for UnifiedContentItem {
    fn render_content_card(&self, _config: &ContentPageConfig, language: &str) -> AnyView {
        let content_type = self.content_type().to_string();
        let content_config = create_content_kind_registry()
            .kinds
            .get(&content_type)
            .cloned()
            .unwrap_or_else(|| {
                tracing::warn!(
                    "Unknown content type: {}, using default config",
                    content_type
                );
                rustelo_core_lib::ContentConfig::from_env()
            });
        view! {
            <UnifiedContentCard
                content_item=self.clone()
                content_type=content_type.clone()
                language=language.to_string()
                _content_config=content_config.clone()
            />
        }
        .into_any()
    }

    fn render_featured_content(&self, config: &ContentPageConfig, language: &str) -> AnyView {
        let title = self.title().to_string();
        let excerpt = self.excerpt.as_deref().unwrap_or("No excerpt available");
        let date = self.created_at();
        let category_html = if config.uses_categories {
            if let Some(category) = self.categories().first() {
                let cat_label = if config.uses_emojis {
                    format!(
                        "{} {}",
                        rustelo_core_lib::get_category_emoji(
                            self.content_type(),
                            language,
                            category
                        ),
                        category
                    )
                } else {
                    category.clone()
                };
                view! {
                    <span class="ds-bg ds-rounded-md px-2 py-1">{cat_label}</span>
                }
            } else {
                view! { <span class="ds-bg ds-rounded-md px-2 py-1">{String::new()}</span> }
            }
        } else {
            view! { <span class="ds-bg ds-rounded-md px-2 py-1">{String::new()}</span> }
        };

        view! {
            <article class="ds-bg ds-rounded-lg ds-shadow-lg p-6 hover:ds-shadow-xl transition-shadow">
                <h3 class="text-xl font-bold ds-text mb-3">{title}</h3>
                <p class="ds-text-secondary mb-4">{excerpt}</p>
                <div class="flex justify-between items-center text-sm ds-text-secondary">
                    <span>{date}</span>
                    {category_html}
                </div>
            </article>
        }.into_any()
    }

    fn is_featured(&self) -> bool {
        // Simple fallback - check if item has "featured" in categories or always return
        // false
        false // Default to not featured
    }

    fn get_category(&self) -> Option<&str> {
        self.categories().first().map(|s| s.as_str())
    }

    fn get_title(&self) -> &str {
        self.title()
    }

    fn get_excerpt(&self) -> Option<&str> {
        self.excerpt.as_deref()
    }

    fn get_date(&self) -> Option<&str> {
        Some(self.created_at())
    }
}

// ContentIndex is a collection type, not a single content item
// Individual generic content items would need their own struct definition

/// Unified content collection renderer that works with any content type
pub struct UnifiedContentRenderer;

impl UnifiedContentRenderer {
    /// Render a collection of content items using the ContentRenderer trait
    pub fn render_content_collection<T: ContentRenderer>(
        items: &[T],
        config: &ContentPageConfig,
        language: &str,
    ) -> Vec<AnyView> {
        items
            .iter()
            .map(|item| item.render_content_card(config, language))
            .collect()
    }

    /// Render a collection of content item references using the ContentRenderer
    /// trait
    pub fn render_content_collection_refs<T: ContentRenderer>(
        items: &[&T],
        config: &ContentPageConfig,
        language: &str,
    ) -> Vec<AnyView> {
        items
            .iter()
            .map(|item| item.render_content_card(config, language))
            .collect()
    }

    /// Render featured content items using the ContentRenderer trait
    pub fn render_featured_collection<T: ContentRenderer>(
        items: &[T],
        limit: usize,
        config: &ContentPageConfig,
        language: &str,
    ) -> Vec<AnyView> {
        items
            .iter()
            .filter(|item| item.is_featured())
            .take(limit)
            .map(|item| item.render_featured_content(config, language))
            .collect()
    }

    /// Render featured content item references using the ContentRenderer trait
    pub fn render_featured_collection_refs<T: ContentRenderer>(
        items: &[&T],
        config: &ContentPageConfig,
        language: &str,
    ) -> Vec<AnyView> {
        items
            .iter()
            .map(|item| item.render_featured_content(config, language))
            .collect()
    }

    /// Filter content items by category using the ContentRenderer trait
    pub fn filter_by_category<'a, T: ContentRenderer>(
        items: &'a [T],
        category: &str,
    ) -> Vec<&'a T> {
        if category == "all" {
            items.iter().collect()
        } else {
            items
                .iter()
                .filter(|item| {
                    item.get_category()
                        .map(|cat| cat == category)
                        .unwrap_or(false)
                })
                .collect()
        }
    }
}
