use leptos::prelude::*;
#[cfg(target_arch = "wasm32")]
use rustelo_core_lib::state::UserInfo;

#[cfg(target_arch = "wasm32")]
use super::otp_service::OtpVerifyResult;
#[cfg(target_arch = "wasm32")]
use super::{code_step::CodeStep, email_step::EmailStep, gdpr_step::GdprStep};

#[cfg(target_arch = "wasm32")]
#[derive(Clone, PartialEq)]
enum LoginStep {
    Email,
    Code { email: String },
    Gdpr { pending_token: String },
}

/// Modal overlay for passwordless OTP login.
/// Renders nothing in SSR — only active in WASM.
#[component]
pub fn LoginModal(show: ReadSignal<bool>, set_show: WriteSignal<bool>) -> impl IntoView {
    #[cfg(target_arch = "wasm32")]
    {
        let lang = rustelo_core_lib::state::use_current_language();
        let close_label = Memo::new(move |_| {
            rustelo_core_lib::i18n::UnifiedI18n::new(&lang.get(), "/").t("auth-modal-close")
        });

        let step = RwSignal::new(LoginStep::Email);
        let error_msg: RwSignal<Option<String>> = RwSignal::new(None);
        let auth_state = use_context::<rustelo_core_lib::state::AuthState>();

        // Lock body scroll while login modal is open
        Effect::new(move |_| {
            if let Some(body) = web_sys::window()
                .and_then(|w| w.document())
                .and_then(|d| d.body())
            {
                let _ = if show.get() {
                    body.style().set_property("overflow", "hidden")
                } else {
                    body.style().remove_property("overflow").map(|_| ())
                };
            }
        });

        let on_email_success = Callback::new(move |email: String| {
            step.set(LoginStep::Code { email });
            error_msg.set(None);
        });

        let set_path = use_context::<WriteSignal<String>>();

        let finalize_login = {
            let auth_state = auth_state.clone();
            let set_path = set_path;
            move |user: UserInfo| {
                if let Some(auth) = auth_state.clone() {
                    auth.set_user(user);
                }
                set_show.set(false);
                step.set(LoginStep::Email);

                let return_url = web_sys::window()
                    .and_then(|w| w.location().search().ok())
                    .and_then(|q| {
                        q.trim_start_matches('?')
                            .split('&')
                            .find_map(|pair| {
                                let (k, v) = pair.split_once('=')?;
                                if k == "return" {
                                    js_sys::decode_uri_component(v).ok()
                                } else {
                                    None
                                }
                            })
                            .map(|s| s.as_string())
                            .flatten()
                    });

                if let Some(url) = return_url {
                    if let Some(sp) = set_path {
                        sp.set(url);
                    }
                }
            }
        };

        let on_code_success = {
            let finalize = finalize_login.clone();
            Callback::new(move |result: OtpVerifyResult| match result {
                OtpVerifyResult::Authenticated { user, .. } => finalize(user),
                OtpVerifyResult::NeedsConsent { pending_token } => {
                    step.set(LoginStep::Gdpr { pending_token });
                    error_msg.set(None);
                }
            })
        };

        let on_gdpr_success = Callback::new(move |user: UserInfo| {
            finalize_login(user);
        });

        let on_back = Callback::new(move |_: ()| {
            step.set(LoginStep::Email);
            error_msg.set(None);
        });

        view! {
            <Show when=move || show.get()>
                // Blocking backdrop — covers full viewport, click outside closes modal
                <div
                    class="fixed inset-0 z-[80] bg-black opacity-75 backdrop-blur-sm"
                    on:click=move |_| set_show.set(false)
                />
                // Modal panel — above the backdrop, below cookie banner (z-[90]/z-[100])
                <div class="fixed inset-0 z-[85] flex items-center justify-center p-4">
                    <div
                        class="relative w-full max-w-md bg-base-100 rounded-2xl shadow-xl p-8"
                        on:click=|ev| ev.stop_propagation()
                    >
                        <button
                            class="absolute top-4 right-4 btn btn-ghost btn-sm btn-circle text-base-content"
                            aria-label=move || close_label.get()
                            title=move || close_label.get()
                            on:click=move |_| {
                                set_show.set(false);
                                step.set(LoginStep::Email);
                            }
                        >"✕"</button>
                        {move || match step.get() {
                            LoginStep::Email => view! {
                                <EmailStep
                                    on_success=on_email_success
                                    error_msg=error_msg
                                />
                            }.into_any(),
                            LoginStep::Code { email } => view! {
                                <CodeStep
                                    email=email
                                    on_success=on_code_success
                                    on_back=on_back
                                    error_msg=error_msg
                                />
                            }.into_any(),
                            LoginStep::Gdpr { pending_token } => view! {
                                <GdprStep
                                    pending_token=pending_token
                                    on_success=on_gdpr_success
                                    error_msg=error_msg
                                />
                            }.into_any(),
                        }}
                    </div>
                </div>
            </Show>
        }
        .into_any()
    }

    // SSR: emit one DynChild `<!--></-->` pair to match the `<Show>` DynChild
    // markers that WASM emits on initial render (show=false → empty content).
    // Without this, the hydration cursor desynchronises at this position.
    #[cfg(not(target_arch = "wasm32"))]
    {
        let _ = (show, set_show);
        view! { {move || ()} }.into_any()
    }
}
