#![allow(unused)]
#![warn(unused_must_use)]

use leptos::html::Input;
use leptos::prelude::*;

#[cfg(feature = "hydrate")]
use wasm_bindgen::prelude::*;
#[cfg(feature = "hydrate")]
use web_sys::{Storage, window};

use crate::command_line::CommandLine;

#[derive(Clone, Copy, PartialEq)]
pub enum Theme {
    Light,
    Dark,
}

impl Theme {
    fn as_str(&self) -> &'static str {
        match self {
            Theme::Light => "light",
            Theme::Dark => "dark",
        }
    }

    fn from_str(s: &str) -> Self {
        match s {
            "light" => Theme::Light,
            "dark" => Theme::Dark,
            _ => unreachable!()
        }
    }
}

#[cfg(feature = "hydrate")]
fn get_stored_theme() -> Theme {
    if let Some(window) = window()
        && let Ok(Some(storage)) = window.local_storage()
        && let Ok(Some(theme_str)) = storage.get_item("theme")
    {
        return Theme::from_str(&theme_str);
    }
    Theme::Dark
}

#[cfg(not(feature = "hydrate"))]
fn get_stored_theme() -> Theme {
    Theme::Dark
}

#[cfg(feature = "hydrate")]
fn set_stored_theme(theme: Theme) {
    if let Some(window) = window()
        && let Ok(Some(storage)) = window.local_storage()
    {
        let _ = storage.set_item("theme", theme.as_str());
    }
}

#[cfg(not(feature = "hydrate"))]
fn set_stored_theme(_theme: Theme) {
    // No-op on server side
}

#[cfg(feature = "hydrate")]
fn apply_theme(theme: Theme) {
    if let Some(window) = window()
        && let Some(document) = window.document()
        && let Some(html) = document.document_element()
    {
        let class_list = html.class_list();
        let _ = class_list.remove_2("light", "dark");
        match theme {
            Theme::Light => {
                let _ = class_list.add_1("light");
            }
            Theme::Dark => {
                let _ = class_list.add_1("dark");
            }
            Theme::Dark => {}
        }
    }
}

#[cfg(not(feature = "hydrate"))]
fn apply_theme(_theme: Theme) {
    // No-op on server side
}

#[component]
pub fn ThemeSwitcher() -> impl IntoView {
    let (current_theme, set_current_theme) = signal(Theme::Dark);
    let (dropdown_open, set_dropdown_open) = signal(false);

    // Load theme from localStorage and apply it on client side only
    Effect::new(move |_| {
        #[cfg(feature = "hydrate")]
        {
            let stored_theme = get_stored_theme();
            set_current_theme.set(stored_theme);
            apply_theme(stored_theme);
        }
    });

    // Apply theme when it changes (client side only)
    Effect::new(move |_| {
        #[cfg(feature = "hydrate")]
        {
            let theme = current_theme.get();
            apply_theme(theme);
        }
    });

    let toggle_dropdown = move |_| {
        set_dropdown_open.update(|open| *open = !*open);
    };

    let select_theme = move |theme: Theme| {
        set_current_theme.set(theme);
        #[cfg(feature = "hydrate")]
        set_stored_theme(theme);
        set_dropdown_open.set(false);
    };

    let theme_icon = move || match current_theme.get() {
        Theme::Light => "☀️",
        Theme::Dark => "🌙",
    };

    view! {
        <div class="theme-switcher">
            <button class="theme-button" on:click=toggle_dropdown>
                {theme_icon}
            </button>
            <div class="theme-dropdown" class:hidden=move || !dropdown_open.get()>
                <button
                    class="theme-option"
                    class:active=move || current_theme.get() == Theme::Light
                    on:click=move |_| select_theme(Theme::Light)
                >
                    "Light"
                </button>
                <button
                    class="theme-option"
                    class:active=move || current_theme.get() == Theme::Dark
                    on:click=move |_| select_theme(Theme::Dark)
                >
                    "Dark"
                </button>
            </div>
        </div>
    }
}

#[component]
pub fn SiteHeader() -> impl IntoView {
    view! {
        <header class="site-header">
            <CommandLine />
            <ThemeSwitcher />
        </header>
    }
}
