use dioxus::prelude::*;
use dioxus_free_icons::icons::bs_icons::{
    BsBoxArrowRight, BsBuilding, BsChatDots, BsCloudArrowUp, BsCodeSlash, BsGithub, BsGlobe2,
    BsGrid, BsHouseDoor, BsMoonFill, BsShieldCheck, BsSunFill,
};
use dioxus_free_icons::Icon;

use crate::i18n::{t, Locale};
use crate::Route;

/// Destination for a sidebar link: either an internal route or an external URL.
enum NavTarget {
    /// Internal Dioxus route (rendered as `Link { to: route }`).
    Internal(Route),
    /// External URL opened in a new tab (rendered as `<a href>`).
    External(String),
}

/// Navigation entry for the sidebar.
///
/// `key` is a stable identifier used for active-route detection and never
/// changes across locales. `label` is the translated display string.
struct NavItem {
    key: &'static str,
    label: String,
    target: NavTarget,
    /// Bootstrap icon element rendered beside the label.
    icon: Element,
}

/// Fixed left sidebar containing header, navigation, logout, and footer.
///
/// # Arguments
///
/// * `name` - User display name (shown in header if non-empty).
/// * `email` - Email address displayed beneath the avatar placeholder.
/// * `avatar_url` - URL for the avatar image (unused placeholder for now).
/// * `class` - CSS class override (e.g. to add `sidebar--open` on mobile).
/// * `on_nav` - Callback fired when a nav link is clicked (used to close
///   the mobile menu).
#[component]
pub fn Sidebar(
    name: String,
    email: String,
    avatar_url: String,
    #[props(default = "http://localhost:3080".to_string())] librechat_url: String,
    #[props(default)] compliance_scanner_url: String,
    #[props(default = "sidebar".to_string())] class: String,
    #[props(default)] on_nav: EventHandler<()>,
) -> Element {
    let locale = use_context::<Signal<Locale>>();
    let locale_val = *locale.read();

    let mut nav_items: Vec<NavItem> = vec![
        NavItem {
            key: "dashboard",
            label: t(locale_val, "nav.dashboard"),
            target: NavTarget::Internal(Route::DashboardPage {}),
            icon: rsx! { Icon { icon: BsHouseDoor, width: 18, height: 18 } },
        },
        NavItem {
            key: "providers",
            label: t(locale_val, "nav.providers"),
            target: NavTarget::Internal(Route::ProvidersPage {}),
            icon: rsx! { Icon { icon: BsCloudArrowUp, width: 18, height: 18 } },
        },
        NavItem {
            key: "chat",
            label: t(locale_val, "nav.chat"),
            // Opens LibreChat in a new tab; SSO via shared Keycloak realm.
            target: NavTarget::External(librechat_url.clone()),
            icon: rsx! { Icon { icon: BsChatDots, width: 18, height: 18 } },
        },
        NavItem {
            key: "developer",
            label: t(locale_val, "nav.developer"),
            target: NavTarget::Internal(Route::AgentsPage {}),
            icon: rsx! { Icon { icon: BsCodeSlash, width: 18, height: 18 } },
        },
        NavItem {
            key: "organization",
            label: t(locale_val, "nav.organization"),
            target: NavTarget::Internal(Route::OrgPricingPage {}),
            icon: rsx! { Icon { icon: BsBuilding, width: 18, height: 18 } },
        },
    ];

    // Only show the compliance scanner link when a URL is configured.
    if !compliance_scanner_url.is_empty() {
        nav_items.push(NavItem {
            key: "compliance",
            label: t(locale_val, "nav.compliance"),
            target: NavTarget::External(compliance_scanner_url.clone()),
            icon: rsx! { Icon { icon: BsShieldCheck, width: 18, height: 18 } },
        });
    }

    // Determine current path to highlight the active nav link.
    let current_route = use_route::<Route>();
    let logout_label = t(locale_val, "common.logout");

    rsx! {
        aside { class: "{class}",
            div { class: "sidebar-top-row",
                SidebarHeader { name, email: email.clone(), avatar_url }
                LocalePicker {}
            }

            nav { class: "sidebar-nav",
                for item in nav_items {
                    {
                        match &item.target {
                            NavTarget::Internal(route) => {
                                // Active detection for nested routes: highlight the parent
                                // nav item when any child route within the nested shell
                                // is active.
                                let is_active = match &current_route {
                                    Route::AgentsPage {} | Route::FlowPage {} | Route::AnalyticsPage {} => {
                                        item.key == "developer"
                                    }
                                    Route::OrgPricingPage {} | Route::OrgDashboardPage {} => {
                                        item.key == "organization"
                                    }
                                    _ => *route == current_route,
                                };
                                let cls = if is_active { "sidebar-link active" } else { "sidebar-link" };
                                let route = route.clone();
                                rsx! {
                                    Link {
                                        to: route,
                                        class: cls,
                                        onclick: move |_| on_nav.call(()),
                                        {item.icon}
                                        span { "{item.label}" }
                                    }
                                }
                            }
                            NavTarget::External(url) => {
                                let url = url.clone();
                                rsx! {
                                    a {
                                        href: url,
                                        target: "_blank",
                                        rel: "noopener noreferrer",
                                        class: "sidebar-link",
                                        onclick: move |_| on_nav.call(()),
                                        {item.icon}
                                        span { "{item.label}" }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            div { class: "sidebar-bottom-actions",
                Link {
                    to: NavigationTarget::<Route>::External("/logout".into()),
                    class: "sidebar-link logout-btn",
                    Icon { icon: BsBoxArrowRight, width: 18, height: 18 }
                    span { "{logout_label}" }
                }
                ThemeToggle {}
            }

            SidebarFooter {}
        }
    }
}

/// Avatar circle, name, and email display at the top of the sidebar.
///
/// # Arguments
///
/// * `name` - User display name. If non-empty, shown above the email.
/// * `email` - User email to display.
/// * `avatar_url` - Placeholder for future avatar image URL.
#[component]
fn SidebarHeader(name: String, email: String, avatar_url: String) -> Element {
    // Derive initials: prefer name words, fall back to email prefix.
    let initials: String = if name.is_empty() {
        email
            .split('@')
            .next()
            .unwrap_or("U")
            .chars()
            .take(2)
            .collect::<String>()
            .to_uppercase()
    } else {
        name.split_whitespace()
            .filter_map(|w| w.chars().next())
            .take(2)
            .collect::<String>()
            .to_uppercase()
    };

    rsx! {
        div { class: "sidebar-header",
            div { class: "avatar-circle",
                span { class: "avatar-initials", "{initials}" }
            }
            div { class: "sidebar-user-info",
                if !name.is_empty() {
                    p { class: "sidebar-name", "{name}" }
                }
                p { class: "sidebar-email", "{email}" }
            }
        }
    }
}

/// Toggle button that switches between dark and light themes.
///
/// Sets `data-theme` on the `<html>` element and persists the choice
/// in `localStorage` so it survives page reloads.
#[component]
fn ThemeToggle() -> Element {
    let locale = use_context::<Signal<Locale>>();

    let mut is_dark = use_signal(|| {
        // Read persisted preference from localStorage on first render.
        #[cfg(feature = "web")]
        {
            web_sys::window()
                .and_then(|w| w.local_storage().ok().flatten())
                .and_then(|s| s.get_item("theme").ok().flatten())
                .is_none_or(|v| v != "certifai-light")
        }
        #[cfg(not(feature = "web"))]
        {
            true
        }
    });

    // Apply the persisted theme to the DOM on first render so the
    // page doesn't flash dark if the user previously chose light.
    #[cfg(feature = "web")]
    {
        let dark = *is_dark.read();
        use_effect(move || {
            let theme = if dark {
                "certifai-dark"
            } else {
                "certifai-light"
            };
            if let Some(doc) = web_sys::window().and_then(|w| w.document()) {
                if let Some(el) = doc.document_element() {
                    let _ = el.set_attribute("data-theme", theme);
                }
            }
        });
    }

    let toggle = move |_| {
        let new_dark = !*is_dark.read();
        is_dark.set(new_dark);

        #[cfg(feature = "web")]
        {
            let theme = if new_dark {
                "certifai-dark"
            } else {
                "certifai-light"
            };
            if let Some(doc) = web_sys::window().and_then(|w| w.document()) {
                if let Some(el) = doc.document_element() {
                    let _ = el.set_attribute("data-theme", theme);
                }
            }
            if let Some(storage) = web_sys::window().and_then(|w| w.local_storage().ok().flatten())
            {
                let _ = storage.set_item("theme", theme);
            }
        }
    };

    let dark = *is_dark.read();
    let locale_val = *locale.read();
    let title = if dark {
        t(locale_val, "nav.switch_light")
    } else {
        t(locale_val, "nav.switch_dark")
    };

    rsx! {
        button {
            class: "theme-toggle-btn",
            title: "{title}",
            onclick: toggle,
            if dark {
                Icon { icon: BsSunFill, width: 16, height: 16 }
            } else {
                Icon { icon: BsMoonFill, width: 16, height: 16 }
            }
        }
    }
}

/// Compact language picker with globe icon and ISO 3166-1 alpha-2 code.
///
/// Renders a button showing a globe icon and the current locale's two-letter
/// country code (e.g. "EN", "DE"). Clicking toggles a dropdown overlay with
/// all available locales. Persists the selection to `localStorage`.
#[component]
fn LocalePicker() -> Element {
    let mut locale = use_context::<Signal<Locale>>();
    let current = *locale.read();
    let mut open = use_signal(|| false);

    let mut select_locale = move |new_locale: Locale| {
        locale.set(new_locale);
        open.set(false);

        #[cfg(feature = "web")]
        {
            if let Some(storage) = web_sys::window().and_then(|w| w.local_storage().ok().flatten())
            {
                let _ = storage.set_item("certifai_locale", new_locale.code());
            }
        }
    };

    let code_upper = current.code().to_uppercase();

    rsx! {
        div { class: "locale-picker",
            button {
                class: "locale-picker-btn",
                title: current.label(),
                onclick: move |_| {
                    let cur = *open.read();
                    open.set(!cur);
                },
                Icon { icon: BsGlobe2, width: 14, height: 14 }
                span { class: "locale-picker-code", "{code_upper}" }
            }
            if *open.read() {
                // Invisible backdrop to close dropdown on outside click
                div {
                    class: "locale-picker-backdrop",
                    onclick: move |_| open.set(false),
                }
                div { class: "locale-picker-dropdown",
                    for loc in Locale::all() {
                        {
                            let is_active = *loc == current;
                            let cls = if is_active {
                                "locale-picker-item locale-picker-item--active"
                            } else {
                                "locale-picker-item"
                            };
                            let loc_copy = *loc;
                            rsx! {
                                button {
                                    class: "{cls}",
                                    onclick: move |_| select_locale(loc_copy),
                                    span { class: "locale-picker-item-code",
                                        "{loc_copy.code().to_uppercase()}"
                                    }
                                    span { class: "locale-picker-item-label",
                                        "{loc_copy.label()}"
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

/// Footer section with version string and placeholder social links.
#[component]
fn SidebarFooter() -> Element {
    let locale = use_context::<Signal<Locale>>();
    let locale_val = *locale.read();
    let version = env!("CARGO_PKG_VERSION");

    let github_title = t(locale_val, "nav.github");
    let impressum_title = t(locale_val, "common.impressum");
    let privacy_label = t(locale_val, "common.privacy_policy");
    let impressum_label = t(locale_val, "common.impressum");

    rsx! {
        footer { class: "sidebar-footer",
            div { class: "sidebar-social",
                a { href: "#", class: "social-link", title: "{github_title}",
                    Icon { icon: BsGithub, width: 16, height: 16 }
                }
                a { href: "#", class: "social-link", title: "{impressum_title}",
                    Icon { icon: BsGrid, width: 16, height: 16 }
                }
            }
            div { class: "sidebar-legal",
                Link { to: Route::PrivacyPage {}, class: "legal-link", "{privacy_label}" }
                span { class: "legal-sep", "|" }
                Link { to: Route::ImpressumPage {}, class: "legal-link", "{impressum_label}" }
            }
            p { class: "sidebar-version", "v{version}" }
        }
    }
}
