use dioxus::prelude::*;
use dioxus_free_icons::icons::bs_icons::{BsMoonStars, BsSun};
use dioxus_free_icons::Icon;

#[cfg(feature = "web")]
const STORAGE_KEY: &str = "compliance-scanner.theme";

/// Sidebar-footer theme toggle. Reads the initial state on mount from
/// localStorage (explicit user choice) or `prefers-color-scheme` (OS default),
/// then writes back to both the `<html data-theme="...">` attribute and
/// localStorage on every click.
#[component]
pub fn ThemeToggle(collapsed: bool) -> Element {
    // `None` until the on-mount effect resolves the real value, so SSR doesn't
    // render the wrong icon for the user's actual theme.
    let mut is_dark = use_signal(|| None::<bool>);

    use_effect(move || {
        let (dark, from_storage) = initial_theme();
        is_dark.set(Some(dark));
        // If the user already made an explicit choice (in localStorage), assert it
        // on the DOM so an OS-vs-stored mismatch can't briefly show the wrong theme.
        if from_storage {
            apply_theme(dark);
        }
    });

    let label = if collapsed {
        ""
    } else if is_dark().unwrap_or(true) {
        "Light mode"
    } else {
        "Dark mode"
    };

    let title = if is_dark().unwrap_or(true) {
        "Switch to light mode"
    } else {
        "Switch to dark mode"
    };

    rsx! {
        button {
            class: "theme-toggle",
            r#type: "button",
            title: "{title}",
            "aria-label": "{title}",
            onclick: move |_| {
                let next_dark = !is_dark().unwrap_or(true);
                is_dark.set(Some(next_dark));
                apply_theme(next_dark);
            },
            if is_dark().unwrap_or(true) {
                Icon { icon: BsSun, width: 16, height: 16 }
            } else {
                Icon { icon: BsMoonStars, width: 16, height: 16 }
            }
            if !collapsed {
                span { class: "theme-toggle-label", "{label}" }
            }
        }
    }
}

/// Returns `(is_dark, from_storage)`. `from_storage` is true when an explicit
/// user choice is in localStorage; false when we fell back to OS preference
/// (or to the dark default).
#[cfg(feature = "web")]
fn initial_theme() -> (bool, bool) {
    if let Some(window) = web_sys::window() {
        if let Ok(Some(storage)) = window.local_storage() {
            if let Ok(Some(value)) = storage.get_item(STORAGE_KEY) {
                return (value == "dark", true);
            }
        }
        if let Ok(Some(mql)) = window.match_media("(prefers-color-scheme: dark)") {
            return (mql.matches(), false);
        }
    }
    (true, false)
}

#[cfg(not(feature = "web"))]
fn initial_theme() -> (bool, bool) {
    (true, false)
}

#[cfg(feature = "web")]
fn apply_theme(dark: bool) {
    let theme = if dark { "dark" } else { "light" };
    if let Some(window) = web_sys::window() {
        if let Some(document) = window.document() {
            if let Some(root) = document.document_element() {
                let _ = root.set_attribute("data-theme", theme);
            }
        }
        if let Ok(Some(storage)) = window.local_storage() {
            let _ = storage.set_item(STORAGE_KEY, theme);
        }
    }
}

#[cfg(not(feature = "web"))]
fn apply_theme(_dark: bool) {}
