//! Client-side SPA link component
//!
//! Reactive implementation of SPA-aware links for client-side navigation.

use leptos::ev::MouseEvent;
use leptos::prelude::*;

/// Client-side SPA-aware link component
#[component]
pub fn SpaLink(
    /// The target URL
    href: String,
    /// Link content/children
    children: Children,
    /// CSS class
    #[prop(optional)]
    class: Option<String>,
    /// Whether this is an external link
    #[prop(default = false)]
    external: bool,
    /// Target attribute for external links
    #[prop(optional)]
    target: Option<String>,
    /// Rel attribute for external links
    #[prop(optional)]
    rel: Option<String>,
    /// ARIA label
    #[prop(optional)]
    aria_label: Option<String>,
    /// Title attribute
    #[prop(optional)]
    title: Option<String>,
) -> impl IntoView {
    if external
        || href.starts_with("http")
        || href.starts_with("mailto:")
        || href.starts_with("tel:")
    {
        // External link with proper attributes
        view! {
            <ExternalLink
                href=href
                class=class
                target=target
                rel=rel
                aria_label=aria_label
                title=title
            >
                {children()}
            </ExternalLink>
        }
        .into_any()
    } else {
        // Internal SPA link
        view! {
            <InternalSpaLink
                href=href
                class=class
                aria_label=aria_label
                title=title
            >
                {children()}
            </InternalSpaLink>
        }
        .into_any()
    }
}

/// Component for external links
#[component]
fn ExternalLink(
    href: String,
    children: Children,
    class: Option<String>,
    target: Option<String>,
    rel: Option<String>,
    aria_label: Option<String>,
    title: Option<String>,
) -> impl IntoView {
    let class_attr = class.unwrap_or_default();
    let target_attr = target.unwrap_or_else(|| "_blank".to_string());
    let rel_attr = rel.unwrap_or_else(|| "noopener noreferrer".to_string());

    view! {
        <a
            href=href
            class=class_attr
            target=target_attr
            rel=rel_attr
            aria-label=aria_label
            title=title
        >
            {children()}
        </a>
    }
}

/// Component for internal SPA links
#[component]
fn InternalSpaLink(
    href: String,
    children: Children,
    class: Option<String>,
    aria_label: Option<String>,
    title: Option<String>,
) -> impl IntoView {
    #[cfg(target_arch = "wasm32")]
    let href_for_click = href.clone();

    // TODO: Use proper navigation context from the app
    // For now, we'll use a simple page navigation
    let handle_click = move |e: MouseEvent| {
        e.prevent_default();
        #[cfg(target_arch = "wasm32")]
        {
            if let Some(window) = web_sys::window() {
                if let Some(history) = window.history().ok() {
                    let _ = history.push_state_with_url(
                        &wasm_bindgen::JsValue::NULL,
                        "",
                        Some(&href_for_click),
                    );
                    // Dispatch a popstate event to trigger route handling
                    if let Ok(event) = web_sys::CustomEvent::new("popstate") {
                        let _ = window.dispatch_event(&event);
                    }
                }
            }
        }
    };

    let class_attr = class.unwrap_or_default();

    view! {
        <a
            href=href
            class=class_attr
            on:click=handle_click
            aria-label=aria_label
            title=title
        >
            {children()}
        </a>
    }
}
