use leptos::prelude::*;
use leptos::task::spawn_local;
use rustelo_components_leptos::auth::{
    server_create_note, server_delete_account, server_delete_note, server_get_bookmarks,
    server_get_messages, server_get_notes, server_get_resources, server_mark_message_read,
    server_remove_bookmark, server_update_display_name, server_update_note, BookmarkInfo,
    UserMessage, UserNote, UserResource,
};
#[cfg(target_arch = "wasm32")]
use rustelo_components_leptos::toast::{push_toast_to, ToastKind};
#[cfg(target_arch = "wasm32")]
use rustelo_core_lib::utils::nav;
use rustelo_core_lib::{i18n::content_helper::create_content_provider_reactive, state::AuthState};

#[derive(Copy, Clone, PartialEq)]
enum ProfileTab {
    Perfil,
    Marcadores,
    Mensajes,
    Notas,
    Recursos,
}

#[component]
pub fn UnifiedUserPage(
    #[prop(default = rustelo_core_lib::config::get_default_language().to_string())]
    _language: String,
    #[prop(optional)] lang_content: Option<std::collections::HashMap<String, String>>,
) -> impl IntoView {
    let content = create_content_provider_reactive(lang_content);
    let auth_state = use_context::<AuthState>();

    // WASM: redirect unauthenticated visitors to login.
    #[cfg(target_arch = "wasm32")]
    {
        use rustelo_core_lib::state::use_current_language;
        let set_path = use_context::<WriteSignal<String>>();
        let lang_signal = use_current_language();
        let auth = auth_state.clone();
        Effect::new(move |_| {
            let authenticated = auth
                .as_ref()
                .map(|a| a.authenticated.get())
                .unwrap_or(false);
            if !authenticated {
                let lang = lang_signal.get_untracked();
                let (login_path, return_path) = if lang == "es" {
                    ("/iniciar-sesion", "/usuario")
                } else {
                    ("/login", "/user")
                };
                let target = format!(
                    "{}?return={}",
                    login_path,
                    js_sys::encode_uri_component(return_path)
                );
                if let Some(sp) = set_path {
                    sp.set(target);
                }
            }
        });
    }

    // SSR: redirect unauthenticated visitors to NotFound (sets HTTP 404).
    #[cfg(feature = "ssr")]
    {
        let is_authed = auth_state
            .as_ref()
            .map(|a| a.authenticated.get_untracked())
            .unwrap_or(false);
        if !is_authed {
            if let Some(resp) = use_context::<leptos_axum::ResponseOptions>() {
                resp.set_status(axum::http::StatusCode::NOT_FOUND);
            }
            let lang = _language.clone();
            return view! {
                <crate::not_found::unified::UnifiedNotFoundPage _language=lang />
            }
            .into_any();
        }
    }

    let _ = _language;

    // ── Reactive auth helpers — Copy signals, safe to capture in many move || ──
    let auth_authenticated: Option<RwSignal<bool>> = auth_state.as_ref().map(|a| a.authenticated);

    // ── Active tab state ───────────────────────────────────────────────────
    let active_tab: RwSignal<ProfileTab> = RwSignal::new(ProfileTab::Perfil);

    // ── Name-edit state ────────────────────────────────────────────────────
    let user_signal: Option<RwSignal<Option<rustelo_core_lib::state::UserInfo>>> =
        auth_state.as_ref().map(|a| a.user);

    let current_name_memo = Memo::new(move |_| {
        user_signal
            .and_then(|sig| {
                #[cfg(target_arch = "wasm32")]
                {
                    sig.get()
                }
                #[cfg(not(target_arch = "wasm32"))]
                {
                    sig.get_untracked()
                }
            })
            .and_then(|u| u.name)
            .unwrap_or_default()
    });

    let editing_name: RwSignal<bool> = RwSignal::new(false);
    let name_input: RwSignal<String> = RwSignal::new(String::new());
    let name_save_error: RwSignal<Option<String>> = RwSignal::new(None);
    let name_save_ok: RwSignal<bool> = RwSignal::new(false);

    // ── Delete account state ───────────────────────────────────────────────
    let delete_error: RwSignal<Option<String>> = RwSignal::new(None);
    let confirm_delete: RwSignal<bool> = RwSignal::new(false);
    // Copy signals to inline clear_auth() without capturing non-Copy
    // Option<AuthState>
    let auth_permissions_signal: Option<RwSignal<Vec<String>>> =
        auth_state.as_ref().map(|a| a.permissions);
    let auth_error_signal: Option<RwSignal<Option<String>>> = auth_state.as_ref().map(|a| a.error);
    let set_path_delete = use_context::<WriteSignal<String>>();

    // ── Data resources — each Resource gets its own move || capturing the Copy
    // signal ──
    let bookmarks = Resource::new(
        move || auth_authenticated.map(|s| s.get()).unwrap_or(false),
        |authenticated| async move {
            if authenticated {
                server_get_bookmarks().await
            } else {
                Ok(vec![])
            }
        },
    );

    let messages = Resource::new(
        move || auth_authenticated.map(|s| s.get()).unwrap_or(false),
        |authenticated| async move {
            if authenticated {
                server_get_messages().await
            } else {
                Ok(vec![])
            }
        },
    );

    let notes = Resource::new(
        move || auth_authenticated.map(|s| s.get()).unwrap_or(false),
        |authenticated| async move {
            if authenticated {
                server_get_notes().await
            } else {
                Ok(vec![])
            }
        },
    );

    let resources = Resource::new(
        move || auth_authenticated.map(|s| s.get()).unwrap_or(false),
        |authenticated| async move {
            if authenticated {
                server_get_resources().await
            } else {
                Ok(vec![])
            }
        },
    );

    // ── Notes editing state ────────────────────────────────────────────────
    let editing_note: RwSignal<Option<String>> = RwSignal::new(None);
    let note_title: RwSignal<String> = RwSignal::new(String::new());
    let note_body: RwSignal<String> = RwSignal::new(String::new());
    let note_save_ok: RwSignal<bool> = RwSignal::new(false);
    let creating_note: RwSignal<bool> = RwSignal::new(false);

    // Reset note editing state when leaving Notas tab.
    Effect::new(move |_| {
        let tab = {
            #[cfg(target_arch = "wasm32")]
            {
                active_tab.get()
            }
            #[cfg(not(target_arch = "wasm32"))]
            {
                active_tab.get_untracked()
            }
        };
        if tab != ProfileTab::Notas {
            editing_note.set(None);
            creating_note.set(false);
            note_save_ok.set(false);
        }
    });

    // ── Transactional toast feedback ───────────────────────────────────────
    #[cfg(target_arch = "wasm32")]
    {
        // Capture toast signal once (Copy) so Effects can call push_toast_to.
        let ts =
            use_context::<RwSignal<Vec<rustelo_components_leptos::toast::ToastNotification>>>();
        Effect::new(move |_| {
            if note_save_ok.get() {
                if let Some(sig) = ts {
                    push_toast_to(sig, ToastKind::Info, "Note saved");
                }
                // Auto-clear — prevent re-trigger on reactive re-runs.
                note_save_ok.set(false);
            }
        });
    }

    // ── Unread count badge ─────────────────────────────────────────────────
    let unread_count = Memo::new(move |_| {
        messages
            .get()
            .and_then(|r| r.ok())
            .map(|msgs| msgs.iter().filter(|m: &&UserMessage| !m.is_read).count())
            .unwrap_or(0)
    });

    // ── Pre-computed labels ────────────────────────────────────────────────
    // Tab buttons
    let lbl_tab_profile = content.t("user-tab-profile");
    let lbl_tab_bookmarks = content.t("user-tab-bookmarks");
    let lbl_tab_messages = content.t("user-tab-messages");
    let lbl_tab_notes = content.t("user-tab-notes");
    let lbl_tab_resources = content.t("user-tab-resources");
    // Perfil tab
    let lbl_profile_info = content.t("user-profile-info");
    let lbl_name = content.t("user-name");
    let lbl_save_changes = content.t("user-save-changes");
    let lbl_cancel = content.t("user-cancel");
    let lbl_edit = content.t("user-edit");
    let lbl_profile_updated = content.t("user-profile-updated");
    let lbl_email = content.t("user-email");
    let lbl_role = content.t("user-role");
    let lbl_loading = content.t("user-loading");
    let lbl_danger_zone = content.t("user-danger-zone");
    let lbl_acct_security = content.t("user-account-security");
    let lbl_try_again = content.t("user-please-try-again");
    let lbl_delete = content.t("user-delete");
    let lbl_delete_account = content.t("user-delete-account");
    // Bookmarks tab
    let lbl_bm_empty = content.t("user-bookmarks-empty");
    // Messages tab
    let lbl_msg_empty = content.t("user-messages-empty");
    let lbl_msg_subject = content.t("user-messages-subject");
    let lbl_msg_from = content.t("user-messages-from");
    let lbl_msg_mark_read = content.t("user-messages-mark-read");
    let lbl_msg_unread = content.t("user-messages-unread");
    // Notes tab
    let lbl_notes_empty = content.t("user-notes-empty");
    let lbl_notes_create = content.t("user-notes-create");
    let lbl_notes_title_ph = content.t("user-notes-title-ph");
    let lbl_notes_body_ph = content.t("user-notes-body-ph");
    let lbl_notes_save = content.t("user-notes-save");
    let lbl_notes_delete = content.t("user-notes-delete");
    let lbl_notes_saved = content.t("user-notes-saved");
    // Resources tab
    let lbl_res_empty = content.t("user-resources-empty");
    let lbl_res_open = content.t("user-resources-open");
    // Section headings — sidebar closure takes the originals; content panel gets
    // clones.
    let lbl_section_bookmarks = lbl_tab_bookmarks.clone();
    let lbl_section_messages = lbl_tab_messages.clone();
    let lbl_section_notes = lbl_tab_notes.clone();
    let lbl_section_resources = lbl_tab_resources.clone();

    view! {
        <div class="ds-bg-page min-h-screen py-4 md:py-12">
            <div class="max-w-5xl mx-auto px-3 md:px-4 py-4 md:py-8">
                <div class="flex flex-col md:flex-row gap-6">

                    // ── Sidebar navigation ────────────────────────────────────
                    <nav class="flex flex-col gap-0.5 md:w-48 md:flex-shrink-0">
                        {move || {
                            let tab = {
                                #[cfg(target_arch = "wasm32")] { active_tab.get() }
                                #[cfg(not(target_arch = "wasm32"))] { active_tab.get_untracked() }
                            };
                            let unread = {
                                #[cfg(target_arch = "wasm32")] { unread_count.get() }
                                #[cfg(not(target_arch = "wasm32"))] { unread_count.get_untracked() }
                            };
                            let active_cls = "ds-nav-item-active";
                            let idle_cls   = "ds-nav-item";
                            view! {
                                <button
                                    class={if tab == ProfileTab::Perfil { active_cls } else { idle_cls }}
                                    on:click=move |_| active_tab.set(ProfileTab::Perfil)
                                >{lbl_tab_profile.clone()}</button>
                                <button
                                    class={if tab == ProfileTab::Marcadores { active_cls } else { idle_cls }}
                                    on:click=move |_| active_tab.set(ProfileTab::Marcadores)
                                >{lbl_tab_bookmarks.clone()}</button>
                                <button
                                    class={if tab == ProfileTab::Mensajes { active_cls } else { idle_cls }}
                                    on:click=move |_| active_tab.set(ProfileTab::Mensajes)
                                >
                                    {lbl_tab_messages.clone()}
                                    {(unread > 0).then(|| view! {
                                        <span class="badge badge-error badge-sm ml-1">{unread.to_string()}</span>
                                    })}
                                </button>
                                <button
                                    class={if tab == ProfileTab::Notas { active_cls } else { idle_cls }}
                                    on:click=move |_| active_tab.set(ProfileTab::Notas)
                                >{lbl_tab_notes.clone()}</button>
                                <button
                                    class={if tab == ProfileTab::Recursos { active_cls } else { idle_cls }}
                                    on:click=move |_| active_tab.set(ProfileTab::Recursos)
                                >{lbl_tab_resources.clone()}</button>
                            }
                        }}
                    </nav>

                    // ── Content panel ─────────────────────────────────────────
                    <div class="flex-1 min-w-0 min-h-[480px]">
                        {move || {
                            let tab = {
                                #[cfg(target_arch = "wasm32")] { active_tab.get() }
                                #[cfg(not(target_arch = "wasm32"))] { active_tab.get_untracked() }
                            };
                            match tab {
                                ProfileTab::Perfil => {
                                    // ── Perfil tab ─────────────────────────────
                                    let lpi = lbl_profile_info.clone();
                                    let lnm = lbl_name.clone();
                                    let lsc = lbl_save_changes.clone();
                                    let lca = lbl_cancel.clone();
                                    let lca_dz = lbl_cancel.clone(); // for danger zone cancel
                                    let led = lbl_edit.clone();
                                    let lpu = lbl_profile_updated.clone();
                                    let lem = lbl_email.clone();
                                    let lrl = lbl_role.clone();
                                    let llo = lbl_loading.clone();
                                    let ldz = lbl_danger_zone.clone();
                                    let las = lbl_acct_security.clone();
                                    let lta = lbl_try_again.clone();
                                    let lde = lbl_delete.clone();
                                    let lda = lbl_delete_account.clone();
                                    view! {
                                        <div class="space-y-6">
                                            // Profile card
                                            {move || {
                                                let is_authed = {
                                                    #[cfg(target_arch = "wasm32")]
                                                    { auth_authenticated.map(|s| s.get()).unwrap_or(false) }
                                                    #[cfg(not(target_arch = "wasm32"))]
                                                    { auth_authenticated.map(|s| s.get_untracked()).unwrap_or(false) }
                                                };
                                                if is_authed {
                                                    match user_signal.and_then(|s| {
                                                        #[cfg(target_arch = "wasm32")] { s.get() }
                                                        #[cfg(not(target_arch = "wasm32"))] { s.get_untracked() }
                                                    }) {
                                                        Some(u) => {
                                                            let email = u.email.clone();
                                                            let roles = u.roles.clone();
                                                            let save_c = lsc.clone();
                                                            let cancel = lca.clone();
                                                            let edit_b = led.clone();
                                                            let prof_u = lpu.clone();
                                                            view! {
                                                                <section class="bg-base-100 rounded-2xl shadow-md p-4 md:p-8">
                                                                    <h1 class="text-2xl font-bold ds-text mb-6">
                                                                        {lpi.clone()}
                                                                    </h1>
                                                                    <dl class="space-y-4">
                                                                        // Name row (editable)
                                                                        <div class="flex items-center gap-3">
                                                                            <dt class="font-medium ds-text w-24 shrink-0">{lnm.clone()}</dt>
                                                                            <dd class="flex-1">
                                                                                {move || {
                                                                                    let current = current_name_memo.get();
                                                                                    if editing_name.get() {
                                                                                        let sv = save_c.clone();
                                                                                        let ca = cancel.clone();
                                                                                        view! {
                                                                                            <div class="flex flex-wrap items-center gap-2">
                                                                                                <input
                                                                                                    type="text"
                                                                                                    class="input input-bordered input-sm flex-1 max-w-xs ds-text"
                                                                                                    prop:value=move || name_input.get()
                                                                                                    on:input=move |ev| { name_input.set(event_target_value(&ev)); }
                                                                                                />
                                                                                                <button
                                                                                                    class="btn btn-primary btn-sm"
                                                                                                    on:click=move |_| {
                                                                                                        let name = name_input.get_untracked();
                                                                                                        name_save_error.set(None);
                                                                                                        name_save_ok.set(false);
                                                                                                        spawn_local(async move {
                                                                                                            match server_update_display_name(name.clone()).await {
                                                                                                                Ok(()) => {
                                                                                                                    if let Some(sig) = user_signal {
                                                                                                                        sig.update(|u| {
                                                                                                                            if let Some(info) = u {
                                                                                                                                info.name = if name.is_empty() { None } else { Some(name.clone()) };
                                                                                                                            }
                                                                                                                        });
                                                                                                                    }
                                                                                                                    editing_name.set(false);
                                                                                                                    name_save_ok.set(true);
                                                                                                                }
                                                                                                                Err(e) => { name_save_error.set(Some(e.to_string())); }
                                                                                                            }
                                                                                                        });
                                                                                                    }
                                                                                                >{sv}</button>
                                                                                                <button
                                                                                                    class="btn btn-ghost btn-sm"
                                                                                                    on:click=move |_| { editing_name.set(false); name_save_error.set(None); }
                                                                                                >{ca}</button>
                                                                                            </div>
                                                                                        }.into_any()
                                                                                    } else {
                                                                                        let display = if current.is_empty() { "—".to_string() } else { current.clone() };
                                                                                        let eb = edit_b.clone();
                                                                                        view! {
                                                                                            <div class="flex items-center gap-3">
                                                                                                <span class="ds-text-secondary">{display}</span>
                                                                                                <button
                                                                                                    class="btn btn-ghost btn-xs ds-text-secondary"
                                                                                                    on:click=move |_| {
                                                                                                        name_input.set(current.clone());
                                                                                                        name_save_error.set(None);
                                                                                                        name_save_ok.set(false);
                                                                                                        editing_name.set(true);
                                                                                                    }
                                                                                                >{eb}</button>
                                                                                            </div>
                                                                                        }.into_any()
                                                                                    }
                                                                                }}
                                                                            </dd>
                                                                        </div>
                                                                        // Feedback
                                                                        {move || name_save_error.get().map(|e| view! { <p class="text-error text-sm">{e}</p> })}
                                                                        {move || name_save_ok.get().then(|| view! { <p class="text-success text-sm">{prof_u.clone()}</p> })}
                                                                        // Email row
                                                                        <div class="flex gap-3">
                                                                            <dt class="font-medium ds-text w-24">{lem.clone()}</dt>
                                                                            <dd class="ds-text-secondary">{email}</dd>
                                                                        </div>
                                                                        // Role row
                                                                        <div class="flex gap-3">
                                                                            <dt class="font-medium ds-text w-24">{lrl.clone()}</dt>
                                                                            <dd class="flex flex-wrap gap-1">
                                                                                {roles.into_iter().map(|r| view! {
                                                                                    <span class="badge badge-primary badge-sm">{r}</span>
                                                                                }).collect::<Vec<_>>()}
                                                                            </dd>
                                                                        </div>
                                                                    </dl>
                                                                </section>
                                                            }.into_any()
                                                        }
                                                        None => view! {
                                                            <div class="text-center py-16">
                                                                <p class="ds-text-secondary">{llo.clone()}</p>
                                                            </div>
                                                        }.into_any(),
                                                    }
                                                } else {
                                                    view! { <div /> }.into_any()
                                                }
                                            }}
                                            // Danger zone (bottom of Perfil tab)
                                            <section class="bg-base-100 rounded-2xl shadow-md p-4 md:p-8 border border-error/20">
                                                <h2 class="text-xl font-bold text-error mb-4">{ldz}</h2>
                                                <p class="ds-text-secondary text-sm mb-4">{las}</p>
                                                {move || {
                                                    #[cfg(target_arch = "wasm32")]
                                                    let err = delete_error.get();
                                                    #[cfg(not(target_arch = "wasm32"))]
                                                    let err = delete_error.get_untracked();
                                                    err.map(|e| view! { <p class="text-error text-sm mb-3">{e}</p> })
                                                }}
                                                {move || {
                                                    #[cfg(target_arch = "wasm32")]
                                                    let confirmed = confirm_delete.get();
                                                    #[cfg(not(target_arch = "wasm32"))]
                                                    let confirmed = confirm_delete.get_untracked();
                                                    if confirmed {
                                                        let sp_del = set_path_delete;
                                                        let lta2 = lta.clone();
                                                        let lde2 = lde.clone();
                                                        view! {
                                                            <div class="flex gap-3 items-center">
                                                                <span class="text-sm ds-text-secondary">{lta2}</span>
                                                                <button
                                                                    class="btn btn-error btn-sm"
                                                                    on:click=move |_| {
                                                                        let sp = sp_del;
                                                                        spawn_local(async move {
                                                                            match server_delete_account().await {
                                                                                Ok(()) => {
                                                                                    // Inline clear_auth() using Copy signals
                                                                                    if let Some(s) = auth_authenticated { s.set(false); }
                                                                                    if let Some(s) = user_signal { s.set(None); }
                                                                                    if let Some(s) = auth_permissions_signal { s.set(Vec::new()); }
                                                                                    if let Some(s) = auth_error_signal { s.set(None); }
                                                                                    if let Some(nav_sp) = sp { nav_sp.set("/".to_string()); }
                                                                                }
                                                                                Err(e) => delete_error.set(Some(e.to_string())),
                                                                            }
                                                                        });
                                                                    }
                                                                >{lde2}</button>
                                                                <button
                                                                    class="btn btn-ghost btn-sm"
                                                                    on:click=move |_| confirm_delete.set(false)
                                                                >{lca_dz.clone()}</button>
                                                            </div>
                                                        }.into_any()
                                                    } else {
                                                        let lda2 = lda.clone();
                                                        view! {
                                                            <button
                                                                class="btn btn-outline btn-error btn-sm"
                                                                on:click=move |_| confirm_delete.set(true)
                                                            >{lda2}</button>
                                                        }.into_any()
                                                    }
                                                }}
                                            </section>
                                        </div>
                                    }.into_any()
                                }

                                ProfileTab::Marcadores => {
                                    // ── Marcadores tab ─────────────────────────
                                    let lbe = lbl_bm_empty.clone();
                                    let lde = lbl_delete.clone();
                                    let llo = lbl_loading.clone();
                                    view! {
                                        <section class="bg-base-100 rounded-2xl shadow-md p-4 md:p-8">
                                            <h2 class="text-xl font-bold ds-text mb-4">{lbl_section_bookmarks.clone()}</h2>
                                            <Suspense fallback=move || view! {
                                                <p class="ds-text-secondary text-sm">{llo.clone()}</p>
                                            }>
                                                {move || bookmarks.get().map(|result| {
                                                    let lbe2 = lbe.clone();
                                                    let lde2 = lde.clone();
                                                    match result {
                                                        Err(e) => view! {
                                                            <p class="text-error text-sm">{e.to_string()}</p>
                                                        }.into_any(),
                                                        Ok(items) if items.is_empty() => view! {
                                                            <p class="ds-text-secondary text-sm">{lbe2}</p>
                                                        }.into_any(),
                                                        Ok(items) => {
                                                            let rows = items.into_iter().map(|bm| {
                                                                let BookmarkInfo { id, content_title, content_url, .. } = bm;
                                                                let bm_id = id.clone();
                                                                let href = content_url.as_ref().filter(|u| !u.is_empty()).cloned();
                                                                let display = content_title
                                                                    .or_else(|| content_url.clone())
                                                                    .unwrap_or_else(|| id.clone());
                                                                let lde3 = lde2.clone();
                                                                let remove = move |_| {
                                                                    let id2 = bm_id.clone();
                                                                    spawn_local(async move {
                                                                        let _ = server_remove_bookmark(id2).await;
                                                                        bookmarks.refetch();
                                                                    });
                                                                };
                                                                let display_node = if let Some(url) = href {
                                                                    #[allow(unused_variables)]
                                                                    let url_nav = url.clone();
                                                                    #[allow(unused_variables)]
                                                                    let url_copy = url.clone();
                                                                    let on_nav = move |_ev: leptos::ev::MouseEvent| {
                                                                        #[cfg(target_arch = "wasm32")]
                                                                        {
                                                                            if let Some(set_path) = use_context::<WriteSignal<String>>() {
                                                                                _ev.prevent_default();
                                                                                nav::anchor_navigate(set_path, &url_nav);
                                                                                rustelo_core_lib::utils::doc_scroll_to_top(100);
                                                                            }
                                                                        }
                                                                    };
                                                                    let on_copy = move |_ev: leptos::ev::MouseEvent| {
                                                                        #[cfg(target_arch = "wasm32")]
                                                                        {
                                                                            let u = url_copy.clone();
                                                                            spawn_local(async move {
                                                                                if let Some(w) = web_sys::window() {
                                                                                    let full_url = if u.starts_with('/') {
                                                                                        w.location().origin().ok().map(|o| format!("{o}{u}")).unwrap_or(u)
                                                                                    } else { u };
                                                                                    let _ = wasm_bindgen_futures::JsFuture::from(
                                                                                        w.navigator().clipboard().write_text(&full_url),
                                                                                    ).await;
                                                                                }
                                                                            });
                                                                        }
                                                                    };
                                                                    view! {
                                                                        <div class="flex items-center gap-2 min-w-0 flex-1">
                                                                            <a
                                                                                href=url
                                                                                class="ds-text text-sm truncate hover:underline flex-1 min-w-0"
                                                                                on:click=on_nav
                                                                            >{display}</a>
                                                                            <button
                                                                                type="button"
                                                                                title="Copy URL"
                                                                                class="btn btn-ghost btn-xs opacity-40 hover:opacity-100 flex-shrink-0"
                                                                                on:click=on_copy
                                                                            >"📋"</button>
                                                                        </div>
                                                                    }.into_any()
                                                                } else {
                                                                    view! { <span class="ds-text text-sm truncate">{display}</span> }.into_any()
                                                                };
                                                                view! {
                                                                    <li class="flex items-center justify-between gap-3 py-2 border-b border-base-200 last:border-0 min-w-0">
                                                                        {display_node}
                                                                        <button class="btn btn-ghost btn-xs text-error flex-shrink-0" on:click=remove>
                                                                            {lde3}
                                                                        </button>
                                                                    </li>
                                                                }
                                                            }).collect::<Vec<_>>();
                                                            view! { <ul class="space-y-2 min-w-0 overflow-hidden">{rows}</ul> }.into_any()
                                                        }
                                                    }
                                                })}
                                            </Suspense>
                                        </section>
                                    }.into_any()
                                }

                                ProfileTab::Mensajes => {
                                    // ── Mensajes tab ───────────────────────────
                                    let lme = lbl_msg_empty.clone();
                                    let lms = lbl_msg_subject.clone();
                                    let lmf = lbl_msg_from.clone();
                                    let lmr = lbl_msg_mark_read.clone();
                                    let lmu = lbl_msg_unread.clone();
                                    let llo = lbl_loading.clone();
                                    view! {
                                        <section class="bg-base-100 rounded-2xl shadow-md p-4 md:p-8">
                                            <h2 class="text-xl font-bold ds-text mb-4">{lbl_section_messages.clone()}</h2>
                                            <Suspense fallback=move || view! {
                                                <p class="ds-text-secondary text-sm">{llo.clone()}</p>
                                            }>
                                                {move || messages.get().map(|result| {
                                                    let lme2 = lme.clone();
                                                    let lms2 = lms.clone();
                                                    let lmf2 = lmf.clone();
                                                    let lmr2 = lmr.clone();
                                                    let lmu2 = lmu.clone();
                                                    match result {
                                                        Err(e) => view! {
                                                            <p class="text-error text-sm">{e.to_string()}</p>
                                                        }.into_any(),
                                                        Ok(msgs) if msgs.is_empty() => view! {
                                                            <p class="ds-text-secondary text-sm">{lme2}</p>
                                                        }.into_any(),
                                                        Ok(msgs) => {
                                                            let rows = msgs.into_iter().map(|msg: UserMessage| {
                                                                let msg_id = msg.id.clone();
                                                                let is_read = msg.is_read;
                                                                let subject = msg.subject.clone();
                                                                let from = msg.sender_email.clone();
                                                                let lmr3 = lmr2.clone();
                                                                let lmu3 = lmu2.clone();
                                                                let lms3 = lms2.clone();
                                                                let lmf3 = lmf2.clone();
                                                                view! {
                                                                    <li class={format!(
                                                                        "flex flex-col gap-1 py-3 border-b border-base-200 last:border-0 {}",
                                                                        if is_read { "" } else { "font-semibold" }
                                                                    )}>
                                                                        <div class="flex items-start justify-between gap-2">
                                                                            <div class="flex flex-col gap-0.5 min-w-0">
                                                                                <span class="text-xs ds-text-secondary">{lmf3}: {from}</span>
                                                                                <span class="ds-text text-sm">{lms3}: {subject}</span>
                                                                            </div>
                                                                            {(!is_read).then(|| {
                                                                                let mid = msg_id.clone();
                                                                                let lmr4 = lmr3.clone();
                                                                                view! {
                                                                                    <div class="flex items-center gap-2 flex-shrink-0">
                                                                                        <span class="badge badge-warning badge-sm">{lmu3}</span>
                                                                                        <button
                                                                                            class="btn btn-ghost btn-xs"
                                                                                            on:click=move |_| {
                                                                                                let id = mid.clone();
                                                                                                spawn_local(async move {
                                                                                                    let _ = server_mark_message_read(id).await;
                                                                                                    messages.refetch();
                                                                                                });
                                                                                            }
                                                                                        >{lmr4}</button>
                                                                                    </div>
                                                                                }
                                                                            })}
                                                                        </div>
                                                                        <p class="ds-text-secondary text-sm mt-1">{msg.body}</p>
                                                                    </li>
                                                                }
                                                            }).collect::<Vec<_>>();
                                                            view! { <ul>{rows}</ul> }.into_any()
                                                        }
                                                    }
                                                })}
                                            </Suspense>
                                        </section>
                                    }.into_any()
                                }

                                ProfileTab::Notas => {
                                    // ── Notas tab ──────────────────────────────
                                    let lne = lbl_notes_empty.clone();
                                    let lnc = lbl_notes_create.clone();
                                    let lnt = lbl_notes_title_ph.clone();
                                    let lnb = lbl_notes_body_ph.clone();
                                    let lns = lbl_notes_save.clone();
                                    let lnd = lbl_notes_delete.clone();
                                    let lnk = lbl_notes_saved.clone();
                                    let llo = lbl_loading.clone();
                                    let lca_notas = lbl_cancel.clone(); // local clone for inner reactive
                                    let led_notas = lbl_edit.clone(); // local clone for note list
                                    view! {
                                        <section class="bg-base-100 rounded-2xl shadow-md p-4 md:p-8">
                                            <div class="flex items-center justify-between mb-4">
                                                <h2 class="text-xl font-bold ds-text">{lbl_section_notes.clone()}</h2>
                                                {move || {
                                                    let creating = {
                                                        #[cfg(target_arch = "wasm32")] { creating_note.get() }
                                                        #[cfg(not(target_arch = "wasm32"))] { creating_note.get_untracked() }
                                                    };
                                                    let lnc2 = lnc.clone();
                                                    if !creating {
                                                        view! {
                                                            <button
                                                                class="btn btn-primary btn-sm"
                                                                on:click=move |_| {
                                                                    note_title.set(String::new());
                                                                    note_body.set(String::new());
                                                                    editing_note.set(None);
                                                                    note_save_ok.set(false);
                                                                    creating_note.set(true);
                                                                }
                                                            >{lnc2}</button>
                                                        }.into_any()
                                                    } else {
                                                        view! { <span /> }.into_any()
                                                    }
                                                }}
                                            </div>

                                            // Create / edit form
                                            {move || {
                                                let show_form = {
                                                    #[cfg(target_arch = "wasm32")] {
                                                        creating_note.get() || editing_note.get().is_some()
                                                    }
                                                    #[cfg(not(target_arch = "wasm32"))] {
                                                        creating_note.get_untracked() || editing_note.get_untracked().is_some()
                                                    }
                                                };
                                                if show_form {
                                                    let lnt2 = lnt.clone();
                                                    let lnb2 = lnb.clone();
                                                    let lns2 = lns.clone();
                                                    let lca2 = lca_notas.clone();
                                                    let lnk2 = lnk.clone();
                                                    view! {
                                                        <div class="mb-6 p-4 border border-base-300 rounded-xl space-y-3">
                                                            <input
                                                                type="text"
                                                                class="input input-bordered w-full input-sm ds-text"
                                                                placeholder=lnt2
                                                                prop:value=move || note_title.get()
                                                                on:input=move |ev| { note_title.set(event_target_value(&ev)); }
                                                            />
                                                            <textarea
                                                                class="textarea textarea-bordered w-full text-sm ds-text min-h-[100px]"
                                                                placeholder=lnb2
                                                                prop:value=move || note_body.get()
                                                                on:input=move |ev| { note_body.set(event_target_value(&ev)); }
                                                            />
                                                            {move || note_save_ok.get().then(|| view! {
                                                                <p class="text-success text-xs">{lnk2.clone()}</p>
                                                            })}
                                                            <div class="flex gap-2">
                                                                <button
                                                                    class="btn btn-primary btn-sm"
                                                                    on:click=move |_| {
                                                                        let title = note_title.get_untracked();
                                                                        let body  = note_body.get_untracked();
                                                                        let edit_id = editing_note.get_untracked();
                                                                        note_save_ok.set(false);
                                                                        spawn_local(async move {
                                                                            let result = if let Some(nid) = edit_id {
                                                                                server_update_note(nid, title, body).await.map(|_| ())
                                                                            } else {
                                                                                server_create_note(title, body).await.map(|_| ())
                                                                            };
                                                                            match result {
                                                                                Ok(()) => {
                                                                                    note_save_ok.set(true);
                                                                                    creating_note.set(false);
                                                                                    editing_note.set(None);
                                                                                    notes.refetch();
                                                                                }
                                                                                Err(_) => {}
                                                                            }
                                                                        });
                                                                    }
                                                                >{lns2}</button>
                                                                <button
                                                                    class="btn btn-ghost btn-sm"
                                                                    on:click=move |_| {
                                                                        creating_note.set(false);
                                                                        editing_note.set(None);
                                                                        note_save_ok.set(false);
                                                                    }
                                                                >{lca2}</button>
                                                            </div>
                                                        </div>
                                                    }.into_any()
                                                } else {
                                                    view! { <span /> }.into_any()
                                                }
                                            }}

                                            // Note list
                                            <Suspense fallback=move || view! {
                                                <p class="ds-text-secondary text-sm">{llo.clone()}</p>
                                            }>
                                                {move || notes.get().map(|result| {
                                                    let lne2 = lne.clone();
                                                    let lnd2 = lnd.clone();
                                                    let led2 = led_notas.clone();
                                                    match result {
                                                        Err(e) => view! {
                                                            <p class="text-error text-sm">{e.to_string()}</p>
                                                        }.into_any(),
                                                        Ok(items) if items.is_empty() => view! {
                                                            <p class="ds-text-secondary text-sm">{lne2}</p>
                                                        }.into_any(),
                                                        Ok(items) => {
                                                            let rows = items.into_iter().map(|note: UserNote| {
                                                                let nid = note.id.clone();
                                                                let nid2 = note.id.clone();
                                                                let title = note.title.clone();
                                                                let body  = note.content.clone();
                                                                let lnd3 = lnd2.clone();
                                                                let led3 = led2.clone();
                                                                view! {
                                                                    <li class="flex items-start justify-between gap-3 py-3 border-b border-base-200 last:border-0">
                                                                        <div class="flex-1 min-w-0">
                                                                            <p class="ds-text text-sm font-medium truncate">{title.clone()}</p>
                                                                            <p class="ds-text-secondary text-xs mt-1 line-clamp-2">{body.clone()}</p>
                                                                        </div>
                                                                        <div class="flex gap-1 flex-shrink-0">
                                                                            <button
                                                                                class="btn btn-outline btn-xs ds-text"
                                                                                on:click=move |_| {
                                                                                    note_title.set(title.clone());
                                                                                    note_body.set(body.clone());
                                                                                    creating_note.set(false);
                                                                                    note_save_ok.set(false);
                                                                                    editing_note.set(Some(nid.clone()));
                                                                                }
                                                                            >{led3}</button>
                                                                            <button
                                                                                class="btn btn-ghost btn-xs text-error"
                                                                                on:click=move |_| {
                                                                                    let id = nid2.clone();
                                                                                    spawn_local(async move {
                                                                                        let _ = server_delete_note(id).await;
                                                                                        notes.refetch();
                                                                                    });
                                                                                }
                                                                            >{lnd3}</button>
                                                                        </div>
                                                                    </li>
                                                                }
                                                            }).collect::<Vec<_>>();
                                                            view! { <ul>{rows}</ul> }.into_any()
                                                        }
                                                    }
                                                })}
                                            </Suspense>
                                        </section>
                                    }.into_any()
                                }

                                ProfileTab::Recursos => {
                                    // ── Recursos tab ───────────────────────────
                                    let lre = lbl_res_empty.clone();
                                    let lro = lbl_res_open.clone();
                                    let llo = lbl_loading.clone();
                                    view! {
                                        <section class="bg-base-100 rounded-2xl shadow-md p-4 md:p-8">
                                            <h2 class="text-xl font-bold ds-text mb-4">{lbl_section_resources.clone()}</h2>
                                            <Suspense fallback=move || view! {
                                                <p class="ds-text-secondary text-sm">{llo.clone()}</p>
                                            }>
                                                {move || resources.get().map(|result| {
                                                    let lre2 = lre.clone();
                                                    let lro2 = lro.clone();
                                                    match result {
                                                        Err(e) => view! {
                                                            <p class="text-error text-sm">{e.to_string()}</p>
                                                        }.into_any(),
                                                        Ok(items) if items.is_empty() => view! {
                                                            <p class="ds-text-secondary text-sm">{lre2}</p>
                                                        }.into_any(),
                                                        Ok(items) => {
                                                            let rows = items.into_iter().map(|res: UserResource| {
                                                                let name = res.name.clone();
                                                                let desc = res.description.clone();
                                                                let url  = res.url.clone();
                                                                let lro3 = lro2.clone();
                                                                view! {
                                                                    <li class="flex items-start justify-between gap-3 py-3 border-b border-base-200 last:border-0">
                                                                        <div class="flex-1 min-w-0">
                                                                            <p class="ds-text text-sm font-medium">{name}</p>
                                                                            {desc.map(|d| view! {
                                                                                <p class="ds-text-secondary text-xs mt-0.5">{d}</p>
                                                                            })}
                                                                        </div>
                                                                        {url.map(|u| {
                                                                            let lro4 = lro3.clone();
                                                                            view! {
                                                                                <a
                                                                                    href=u
                                                                                    target="_blank"
                                                                                    rel="noopener noreferrer"
                                                                                    class="btn btn-ghost btn-xs flex-shrink-0"
                                                                                >{lro4}</a>
                                                                            }
                                                                        })}
                                                                    </li>
                                                                }
                                                            }).collect::<Vec<_>>();
                                                            view! { <ul>{rows}</ul> }.into_any()
                                                        }
                                                    }
                                                })}
                                            </Suspense>
                                        </section>
                                    }.into_any()
                                }
                            }
                        }}
                    </div>
                </div>
            </div>
        </div>
    }
    .into_any()
}
