//! Unified filter components that work seamlessly in both SSR and client
//! environments
//!
//! These components automatically use the appropriate implementation
//! (client/server) based on the compilation target, providing a unified API for
//! filter functionality.

// Re-export FilterIndex from core-lib for consistency
pub use ::rustelo_core_lib::fluent::FilterIndex;
// Removed leptos_router import - using custom routing system
use leptos::prelude::*;
#[cfg(target_arch = "wasm32")]
use rustelo_core_lib::routing::utils::get_content_type_base_path;

// Import the CSS class helper functions
use crate::{get_active_button_classes, get_inactive_button_classes};

/// Async function to fetch filter data from URL (WASM only)
#[cfg(target_arch = "wasm32")]
async fn fetch_filter_data(url: &str) -> Result<FilterIndex, Box<dyn std::error::Error>> {
    use wasm_bindgen::prelude::*;
    use wasm_bindgen_futures::JsFuture;
    use web_sys::{Request, RequestInit, RequestMode, Response};

    let opts = RequestInit::new();
    opts.set_method("GET");
    opts.set_mode(RequestMode::SameOrigin);

    let request = Request::new_with_str_and_init(url, &opts)
        .map_err(|e| format!("Failed to create request: {:?}", e))?;

    let _window = web_sys::window().ok_or("no global `window` exists")?;
    let resp_value = JsFuture::from(_window.fetch_with_request(&request))
        .await
        .map_err(|e| format!("Fetch failed: {:?}", e))?;
    let resp: Response = resp_value
        .dyn_into()
        .map_err(|e| format!("Response conversion failed: {:?}", e))?;

    if !resp.ok() {
        return Err(format!("HTTP error: {}", resp.status()).into());
    }

    let json = JsFuture::from(
        resp.json()
            .map_err(|e| format!("JSON parsing failed: {:?}", e))?,
    )
    .await
    .map_err(|e| format!("JSON future failed: {:?}", e))?;
    let text = js_sys::JSON::stringify(&json)
        .map_err(|e| format!("JSON stringify failed: {:?}", e))?
        .as_string()
        .ok_or("failed to stringify JSON")?;

    let filter_index: FilterIndex = serde_json::from_str(&text)?;
    Ok(filter_index)
}

/// Unified Content Category Filter Component
///
/// Automatically uses the appropriate implementation based on compilation
/// target:
/// - Server-side: Renders initial HTML structure during SSR
/// - Client-side: Provides interactive functionality after hydration
///
/// Usage: `<CategoryFilter content_type="content_type_key" language="en" />`
#[component]
pub fn CategoryFilter(
    content_type: String,
    language: String,
    #[prop(optional)] all_emoji: Option<String>,
) -> impl IntoView {
    // Use conditional compilation to choose the appropriate implementation
    #[cfg(not(target_arch = "wasm32"))]
    {
        view! {
            <super::ssr::CategoryFilterSSR
                content_type=content_type
                language=language
                all_emoji=all_emoji.unwrap_or_default()
            />
        }
    }

    #[cfg(target_arch = "wasm32")]
    {
        view! {
            <super::client::CategoryFilterClient
                content_type=content_type
                language=language
                all_emoji=all_emoji.unwrap_or_default()
            />
        }
    }
}

/// Enhanced Category and Tag Filter Component that loads from filter-index.json
#[component]
pub fn UnifiedCategoryFilter(
    content_type: String,
    language: String,
    _all_emoji: String,
) -> leptos::prelude::AnyView {
    // Debug: Component instantiation
    #[cfg(target_arch = "wasm32")]
    {
        web_sys::console::log_1(
            &format!(
                "🎯 UnifiedCategoryFilter: Component instantiated with content_type='{}', \
                 language='{}'",
                content_type, language
            )
            .into(),
        );
    }

    let (_filter_data, set_filter_data) = signal(None::<FilterIndex>);
    let current_filter = "All".to_string(); // TODO: Parse from URL when needed

    // Both SSR and WASM: Start with empty data to prevent hydration mismatch
    // Load real data after hydration completes
    set_filter_data.set(Some(FilterIndex {
        generated_at: String::new(),
        content_type: content_type.clone(),
        language: language.clone(),
        total_posts: 0,
        categories: std::collections::HashMap::new(),
        tags: std::collections::HashMap::new(),
    }));

    // Load real data after component is hydrated (client-side only)
    #[cfg(target_arch = "wasm32")]
    {
        let content_type_for_effect = content_type.clone();
        let language_for_effect = language.clone();
        let set_filter_data_for_effect = set_filter_data.clone();

        // Use Effect::new to safely load data after hydration - only on client
        Effect::new(move |_| {
            // Double-check we're actually on the client side
            if !cfg!(target_arch = "wasm32") {
                return;
            }

            // Clone values for the async block
            let content_type_cloned = content_type_for_effect.clone();
            let language_cloned = language_for_effect.clone();
            let set_data_cloned = set_filter_data_for_effect.clone();

            // Only load data on client side after hydration
            wasm_bindgen_futures::spawn_local(async move {
                // CRITICAL: Use target route evaluation to get the correct API path
                // This ensures the API URL matches the target language route
                // For filter API URLs, we always use the content_type directly
                // This ensures consistent API endpoints regardless of language routing
                let filter_url = format!(
                    "/r/{}/{}/filter-index.json",
                    content_type_cloned, language_cloned
                );

                web_sys::console::log_1(
                    &format!("🔄 CLIENT FILTER: Fetching filter data from {}", filter_url).into(),
                );

                match fetch_filter_data(&filter_url).await {
                    Ok(data) => {
                        tracing::debug!(
                            "CLIENT: Async filter index loaded: {} categories, {} tags ",
                            data.categories.len(),
                            data.tags.len()
                        );
                        web_sys::console::log_1(
                            &format!(
                                "✅ CLIENT FILTER: Async loaded {} categories, {} tags ",
                                data.categories.len(),
                                data.tags.len()
                            )
                            .into(),
                        );
                        set_data_cloned.set(Some(data));
                    }
                    Err(e) => {
                        tracing::debug!("CLIENT: Async filter index loading failed: {}", e);
                        web_sys::console::log_1(
                            &format!("❌ CLIENT FILTER: Async loading failed: {}", e).into(),
                        );
                        // Keep the empty data that was already set
                    }
                }
            });
        });
    }

    // Create clones for closures
    let content_type_for_categories = content_type.clone();
    let content_type_for_tags = content_type.clone();
    let current_filter_for_categories = current_filter.clone();
    let current_filter_for_tags = current_filter.clone();

    view! {
        <div class="filter-container space-y-4">
            {
                #[cfg(target_arch = "wasm32")]
                {
                    // Clone variables before moving into Memo closure
                    let content_type_for_memo = content_type.clone();
                    let language_for_memo = language.clone();
                    let filter_memo = Memo::new(move |_| {
                        // Use .with() instead of .with_untracked() to enable reactive tracking
                        _filter_data.with(|data| {
                            if let Some(data) = data {
                                tracing::debug!(
                                    "RENDER: Filter component rendering with {} categories, {} tags. Categories: {:?}, Tags: {:?}",
                                    data.categories.len(),
                                    data.tags.len(),
                                    data.categories,
                                    data.tags
                                );
                                #[cfg(target_arch = "wasm32")]
                                web_sys::console::log_1(
                                    &format!(
                                        "🔄 MEMO UPDATE: Rendering with {} categories, {} items ",
                                        data.categories.len(),
                                        data.tags.len()
                                    )
                                    .into(),
                                );
                                data.clone()
                            } else {
                                #[cfg(target_arch = "wasm32")]
                                web_sys::console::log_1(
                                    &"🔄 MEMO UPDATE: Rendering with empty data ".into(),
                                );
                                FilterIndex {
                                    generated_at: String::new(),
                                    content_type: content_type_for_memo.clone(),
                                    language: language_for_memo.clone(),
                                    total_posts: 0,
                                    categories: std::collections::HashMap::new(),
                                    tags: std::collections::HashMap::new(),
                                }
                            }
                        })
                    });

                    move || {
                        let data = filter_memo.get();
                        let filter_content = {
                            let translator = rustelo_core_lib::SsrTranslator::new(language.clone());
                            rustelo_core_lib::build_page_content_patterns(
                                &translator,
                                &[content_type_for_categories.as_str(), "content"],
                            )
                        };
                        let lbl_categories = filter_content
                            .get("content-filter-categories")
                            .cloned()
                            .unwrap_or_else(|| "Categories".to_string());
                        let lbl_tags = filter_content
                            .get("content-filter-tags")
                            .cloned()
                            .unwrap_or_else(|| "Tags".to_string());
                        let lbl_all = filter_content
                            .get("content-filter-all")
                            .cloned()
                            .unwrap_or_else(|| "All".to_string());
                        let lbl_show_all = filter_content
                            .get("content-filter-show-all")
                            .cloned()
                            .unwrap_or_else(|| "Show All".to_string());
                        view! {
                            <div>
                                // Categories section - only shown when categories exist
                                {if !data.categories.is_empty() {
                                    view! {
                                        <div class="category-filters ">
                                            <h3 class="text-sm font-medium text-gray-700 mb-2">{lbl_categories.clone()}</h3>
                                            <div class="flex flex-wrap gap-2">
                                                // "All" category button
                                                <button
                                                    type="button"
                                                    class={if current_filter_for_categories == "All" {
                                                        get_active_button_classes()
                                                    } else {
                                                        get_inactive_button_classes()
                                                    }}
                                                    data-filter-type="category"
                                                    data-filter-value="All"
                                                    data-content-type={content_type_for_categories.clone()}
                                                    on:click={
                                                        let content_type_for_click = content_type_for_categories.clone();
                                                        let language_for_click = language.clone();
                                                        move |_ev| {
                                                            _ev.prevent_default();
                                                            let filter_url = get_content_type_base_path(&content_type_for_click, &language_for_click).unwrap_or_else(|| "/".to_string());
                                                            if let Some(window) = web_sys::window() {
                                                                let location = window.location();
                                                                let _ = location.set_href(&filter_url);
                                                            }
                                                        }
                                                    }
                                                >
                                                    <span class="filter-button-text ">{format!("🏷️ {} ", lbl_all)}</span>
                                                </button>

                                                // Additional categories from data
                                                {
                                                    data.categories.iter().map(|(category, category_data)| {
                                                    let cat_display = filter_content
                                                        .get(&format!("{}-cat-{}-title", content_type_for_categories, category))
                                                        .cloned()
                                                        .unwrap_or_else(|| category.to_string());
                                                    let category_for_click = category.clone();
                                                    let content_type_for_click = content_type_for_categories.clone();
                                                    let language_for_click = language.clone();
                                                    let is_active = current_filter_for_categories == *category;
                                                    let cat_class = if is_active {
                                                        get_active_button_classes()
                                                    } else {
                                                        get_inactive_button_classes()
                                                    };

                                                    view! {
                                                        <button
                                                            type="button"
                                                            class={cat_class}
                                                            data-filter-type="category"
                                                            data-filter-value={category_for_click.clone()}
                                                            data-content-type={content_type_for_click.clone()}
                                                            on:click=move |_ev| {
                                                                _ev.prevent_default();
                                                                let localized_base_path = get_content_type_base_path(&content_type_for_click, &language_for_click).unwrap_or_else(|| "/".to_string());
                                                                let filter_url = rustelo_core_lib::routing::utils::get_category_url(&localized_base_path, &category_for_click, &language_for_click);
                                                                tracing::debug!("Category filter navigation: {} -> {} -> {}", content_type_for_click, localized_base_path, filter_url);
                                                                if let Some(window) = web_sys::window() {
                                                                    let location = window.location();
                                                                    let _ = location.set_href(&filter_url);
                                                                }
                                                            }
                                                        >
                                                            <span class="filter-button-text ">
                                                                {format!("{} {}", category_data.emoji, cat_display)}
                                                            </span>
                                                        </button>
                                                    }
                                                }).collect_view()
                                                }
                                            </div>
                                        </div>
                                    }.into_any()
                                } else {
                                    view! { <></> }.into_any()
                                }}

                                // Tags section - only shown when tags exist
                                <div class="tag-filters ">
                                    {if !data.tags.is_empty() {
                                        view! {
                                            <div>
                                                <h3 class="text-sm font-medium text-gray-700 mb-2">{lbl_tags.clone()}</h3>
                                                <div class="flex flex-wrap gap-2">
                                                    // Show All button for tags
                                                    <button
                                                        type="button"
                                                        class={format!("{} show-all-filter ", get_active_button_classes())}
                                                        data-filter-type="show-all "
                                                        data-filter-value="all"
                                                        on:click=move |_ev| {
                                                            _ev.prevent_default();
                                                            tracing::debug!("Show All: clearing all tag filters ");
                                                            web_sys::console::log_1(
                                                                &"🏷️ Show All: clearing all tag filters ".into()
                                                            );

                                                            // Clear all tag filters using JavaScript
                                                            let js_code = "window.clearAllTagFilters && window.clearAllTagFilters();";
                                                            let _ = js_sys::eval(&js_code);
                                                        }
                                                    >
                                                        <span class="filter-button-text ">{format!("🔍 {} ", lbl_show_all)}</span>
                                                    </button>

                                                    {data.tags.iter().map(|(tag, tag_data)| {
                                                        let tag_for_click = tag.clone();
                                                        let content_type_for_click = content_type_for_tags.clone();
                                                        let is_active = current_filter_for_tags == *tag;
                                                        let tag_class = if is_active {
                                                            format!("{} tag-filter ", get_active_button_classes())
                                                        } else {
                                                            format!("{} tag-filter ", get_inactive_button_classes())
                                                        };

                                                        view! {
                                                            <button
                                                                type="button"
                                                                class={tag_class}
                                                                data-filter-type="tag"
                                                                data-filter-value={tag_for_click.clone()}
                                                                data-content-type={content_type_for_click.clone()}
                                                                on:click=move |_ev| {
                                                                    _ev.prevent_default();
                                                                    // Tags filter content on current page, not navigate
                                                                    tracing::debug!("Tag filter: filtering by tag {}", tag_for_click);
                                                                    web_sys::console::log_1(
                                                                        &format!("🏷️ Tag filter: filtering posts by tag {}", tag_for_click).into()
                                                                    );

                                                                    // Filter posts by tag using JavaScript
                                                                    let js_code = format!(
                                                                        r#"window.filterPostsByTag && window.filterPostsByTag("{}");"#,
                                                                        tag_for_click
                                                                    );
                                                                    let _ = js_sys::eval(&js_code);
                                                                }
                                                            >
                                                                <span class="filter-button-text ">
                                                                    {format!("{} {}", tag_data.emoji, tag_for_click)}
                                                                </span>
                                                            </button>
                                                        }
                                                    }).collect_view()}
                                                </div>
                                            </div>
                                        }.into_any()
                                    } else {
                                        view! {
                                            <div class="hidden">
                                            </div>
                                        }.into_any()
                                    }}
                                </div>
                            </div>
                        }.into_any()
                    }
                }
                #[cfg(not(target_arch = "wasm32"))]
                {
                    // SSR: Use empty initial data since we can't access signals in SSR context
                    // Create empty FilterIndex for SSR rendering (will be hydrated on client)
                    let empty_data = FilterIndex {
                        generated_at: String::new(),
                        content_type: content_type.clone(),
                        language: language.clone(),
                        total_posts: 0,
                        categories: std::collections::HashMap::new(),
                        tags: std::collections::HashMap::new(),
                    };

                    tracing::debug!(
                        "RENDER: SSR Filter component rendering with empty data for hydration, content_type={}, language={}",
                        empty_data.content_type,
                        empty_data.language
                    );
                    view! {
                        <div>
                            // Categories section - only shown when categories exist
                            {if !empty_data.categories.is_empty() {
                                view! {
                                    <div class="category-filters ">
                                        <h3 class="text-sm font-medium text-gray-700 mb-2">"Categories"</h3>
                                        <div class="flex flex-wrap gap-2">
                                            // "All" category button
                                            <button
                                                type="button"
                                                class={if current_filter_for_categories == "All" {
                                                    get_active_button_classes()
                                                } else {
                                                    get_inactive_button_classes()
                                                }}
                                                data-filter-type="category"
                                                data-filter-value="All"
                                                data-content-type={content_type_for_categories.clone()}
                                                on:click={
                                                    #[cfg(target_arch = "wasm32")]
                                                    let content_type_for_click = content_type_for_categories.clone();
                                                    #[cfg(target_arch = "wasm32")]
                                                    let language_for_click = language.clone();
                                                    move |_ev| {
                                                        _ev.prevent_default();
                                                        #[cfg(target_arch = "wasm32")]
                                                        {
                                                            let filter_url = get_content_type_base_path(&content_type_for_click, &language_for_click).unwrap_or_else(|| "/".to_string());
                                                            if let Some(window) = web_sys::window() {
                                                                let location = window.location();
                                                                let _ = location.set_href(&filter_url);
                                                            }
                                                        }
                                                    }
                                                }
                                            >
                                                <span class="filter-button-text ">{"🏷️ All "}</span>
                                            </button>

                                            // Additional categories from data
                                            {
                                                empty_data.categories.iter().map(|(category, category_data)| {
                                                let category_for_click = category.clone();
                                                let content_type_for_click = content_type_for_categories.clone();
                                                #[cfg(target_arch = "wasm32")]
                                                let language_for_click = language.clone();
                                                let is_active = current_filter_for_categories == *category;
                                                let cat_class = if is_active {
                                                    get_active_button_classes()
                                                } else {
                                                    get_inactive_button_classes()
                                                };

                                                view! {
                                                    <button
                                                        type="button"
                                                        class={cat_class}
                                                        data-filter-type="category"
                                                        data-filter-value={category_for_click.clone()}
                                                        data-content-type={content_type_for_click.clone()}
                                                        on:click=move |_ev| {
                                                            _ev.prevent_default();
                                                            #[cfg(target_arch = "wasm32")]
                                                            {
                                                                let localized_base_path = get_content_type_base_path(&content_type_for_click, &language_for_click).unwrap_or_else(|| "/".to_string());
                                                                let filter_url = rustelo_core_lib::routing::utils::get_category_url(&localized_base_path, &category_for_click, &language_for_click);
                                                                tracing::debug!("Category filter navigation: {} -> {} -> {}", content_type_for_click, localized_base_path, filter_url);
                                                                if let Some(window) = web_sys::window() {
                                                                    let location = window.location();
                                                                    let _ = location.set_href(&filter_url);
                                                                }
                                                            }
                                                        }
                                                    >
                                                        <span class="filter-button-text ">
                                                            {format!("{} {}", category_data.emoji, category_for_click)}
                                                        </span>
                                                    </button>
                                                }
                                            }).collect_view()
                                            }
                                        </div>
                                    </div>
                                }.into_any()
                            } else {
                                view! { <></> }.into_any()
                            }}

                            // Tags section - only shown when tags exist
                            <div class="tag-filters ">
                                {if !empty_data.tags.is_empty() {
                                    view! {
                                        <div>
                                            <h3 class="text-sm font-medium text-gray-700 mb-2">"Tags"</h3>
                                            <div class="flex flex-wrap gap-2">
                                                {empty_data.tags.iter().map(|(tag, tag_data)| {
                                                    let tag_for_click = tag.clone();
                                                    let content_type_for_click = content_type_for_tags.clone();
                                                    #[cfg(target_arch = "wasm32")]
                                                    let language_for_click = language.clone();
                                                    let is_active = current_filter_for_tags == *tag;
                                                    let tag_class = if is_active {
                                                        format!("{} tag-filter ", get_active_button_classes())
                                                    } else {
                                                        format!("{} tag-filter ", get_inactive_button_classes())
                                                    };

                                                    view! {
                                                        <button
                                                            type="button"
                                                            class={tag_class}
                                                            data-filter-type="tag"
                                                            data-filter-value={tag_for_click.clone()}
                                                            data-content-type={content_type_for_click.clone()}
                                                            on:click=move |_ev| {
                                                                _ev.prevent_default();
                                                                #[cfg(target_arch = "wasm32")]
                                                                {
                                                                    // Tags filter content on current page, not navigate
                                                                    tracing::debug!("Tag filter: filtering by tag {}", tag_for_click);
                                                                    web_sys::console::log_1(
                                                                        &format!("🏷️ Tag filter: filtering posts by tag {}", tag_for_click).into()
                                                                    );

                                                                    // Filter posts by tag using JavaScript
                                                                    let js_code = format!(
                                                                        r#"window.filterPostsByTag && window.filterPostsByTag("{}");"#,
                                                                        tag_for_click
                                                                    );
                                                                    let _ = js_sys::eval(&js_code);
                                                                }
                                                            }
                                                        >
                                                            <span class="filter-button-text ">
                                                                {format!("{} {}", tag_data.emoji, tag_for_click)}
                                                            </span>
                                                        </button>
                                                    }
                                                }).collect_view()}
                                            </div>
                                        </div>
                                    }.into_any()
                                } else {
                                    view! {
                                        <div class="hidden"></div>
                                    }.into_any()
                                }}
                            </div>
                        </div>
                    }.into_any()
                }
            }
        </div>
    }.into_any()
}
