use leptos::*;
use crate::app::MenuHelper;
use crate::backend::data::User;
use crate::backend::user::{get_user, logout};
use crate::components::modal_box::DialogOpener;
use crate::locales::trl;

#[derive(Copy, Clone, Debug)]
pub struct MenuOpener {
    visible: ReadSignal<bool>,
    set_visible: WriteSignal<bool>,
}

impl MenuOpener {
    pub fn new() -> Self {
        let (visible, set_visible) = create_signal(false);
        MenuOpener {
            visible,
            set_visible,
        }
    }

    pub fn visible(&self) -> bool {
        self.visible.get()
    }

    pub fn toggle(self) {
        let visible = self.visible.get();
        self.set_visible.update(|v| *v = !visible);

        let helper = use_context::<MenuHelper>().expect("No menu helper");
        if !visible {
            helper.close();
            helper.set_opened(self);
        } else {
            helper.reset();
        }
    }

    pub fn close(&self) {
        self.set_visible.set(false);
        let helper = use_context::<MenuHelper>().expect("No menu helper");
        helper.reset();
    }
}

#[component]
pub fn UserMenu(
    opener: MenuOpener,
    editor: DialogOpener,
    pw_dialog: DialogOpener,
    user_profile: WriteSignal<User>) -> impl IntoView {
    let user = create_resource(move || opener.visible(), move |_| get_user());

    view! {
        <ul
            class=move || {
                if opener.visible() {
                    "dropdown-menu dropdown-menu-end show"
                } else {
                    "dropdown-menu dropdown-menu-end"
                }
            }
            data-bs-popper="none"
            on:mouseleave=move |_| opener.close()
        >
            <li>
                <a class="dropdown-item" href="#" on:click=move |_| { editor.show() }>
                    <div class="d-flex">
                        <div class="flex-shrink-0 me-3">
                            <i class="bx bxs-user-account"></i>
                        </div>
                        <div class="flex-grow-1">
                            <Suspense fallback=move || {
                                view! { <span>"Loading..."</span> }
                            }>
                                {move || {
                                    user.get()
                                        .map(|u| match u {
                                            Ok(user) => {
                                                let usr = user.unwrap_or(User::default());
                                                user_profile.update(|u| *u = usr.clone());
                                                view! {
                                                    <span class="fw-semibold d-block">
                                                        {usr.full_name}
                                                    </span>
                                                }
                                            }
                                            Err(_) => {
                                                view! {
                                                    // <small class="text-muted">"Admin"</small>
                                                    <span>"Error loading user"</span>
                                                }
                                            }
                                        })
                                }}

                            </Suspense>
                        </div>
                    </div>
                </a>
            </li>
            <li>
                <a class="dropdown-item" href="#" on:click=move |_| { pw_dialog.show() }>
                    <i class="bx bx-lock me-2"></i>
                    <span class="align-middle">{trl("Change password")}</span>
                </a>
            </li>
            <li>
                <div class="dropdown-divider"></div>
            </li>
            <li>
                <a
                    class="dropdown-item"
                    href="/login"
                    on:click=move |_| {
                        spawn_local(async move {
                            let _ = logout().await;
                        });
                    }
                >
                    <i class="bx bx-power-off me-2"></i>
                    <span class="align-middle">{trl("Log Out")}</span>
                </a>
            </li>
        </ul>
    }
}