//! Password reset page for users with force_pw_reset flag.

use leptos::ev::SubmitEvent;
use leptos::prelude::*;
#[cfg(feature = "hydrate")]
use leptos::task::spawn_local;
#[cfg(feature = "hydrate")]
use leptos_router::hooks::use_navigate;

use crate::components::{Card, CenteredLayout, ErrorAlert, SubmitButton};

/// Password reset page component.
#[component]
pub fn PasswordResetPage() -> impl IntoView {
    #[cfg(feature = "hydrate")]
    let navigate = use_navigate();

    let (new_password, set_new_password) = signal(String::new());
    let (confirm_password, set_confirm_password) = signal(String::new());
    let (error, set_error) = signal(Option::<String>::None);
    let (pending, set_pending) = signal(false);

    let password_valid = Signal::derive(move || new_password.get().len() >= 8);

    let passwords_match = Signal::derive(move || {
        let pwd = new_password.get();
        let confirm = confirm_password.get();
        !pwd.is_empty() && pwd == confirm
    });

    let on_submit = move |ev: SubmitEvent| {
        ev.prevent_default();
        set_error.set(None);

        let pwd = new_password.get();
        let confirm = confirm_password.get();

        if pwd.len() < 8 {
            set_error.set(Some("Password must be at least 8 characters".to_string()));
            return;
        }

        if pwd != confirm {
            set_error.set(Some("Passwords do not match".to_string()));
            return;
        }

        set_pending.set(true);

        #[cfg(feature = "hydrate")]
        {
            use chattyness_db::models::{PasswordResetRequest, PasswordResetResponse};
            use gloo_net::http::Request;

            let navigate = navigate.clone();
            spawn_local(async move {
                let request = PasswordResetRequest {
                    new_password: pwd,
                    confirm_password: confirm,
                };

                let response = Request::post("/api/auth/reset-password")
                    .json(&request)
                    .unwrap()
                    .send()
                    .await;

                set_pending.set(false);

                match response {
                    Ok(resp) if resp.ok() => {
                        if let Ok(reset_resp) = resp.json::<PasswordResetResponse>().await {
                            navigate(&reset_resp.redirect_url, Default::default());
                        }
                    }
                    Ok(resp) => {
                        let status = resp.status();
                        if status == 401 {
                            set_error.set(Some("Session expired. Please log in again.".to_string()));
                        } else if status == 400 {
                            set_error.set(Some("Invalid password. Please try again.".to_string()));
                        } else {
                            set_error.set(Some(
                                "Failed to reset password. Please try again.".to_string(),
                            ));
                        }
                    }
                    Err(_) => {
                        set_error.set(Some(
                            "Network error. Please check your connection.".to_string(),
                        ));
                    }
                }
            });
        }
    };

    view! {
        <CenteredLayout>
            <div class="w-full max-w-md">
                <Card class="p-6">
                    <div class="text-center mb-6">
                        <div class="mx-auto w-16 h-16 rounded-full bg-yellow-600/20 flex items-center justify-center mb-4">
                            <img src="/icons/key.svg" alt="" class="w-8 h-8" aria-hidden="true" />
                        </div>
                        <h1 class="text-2xl font-bold text-white mb-2">"Reset Your Password"</h1>
                        <p class="text-gray-400">"Please create a new password to continue"</p>
                    </div>

                    <form on:submit=on_submit class="space-y-6">
                        <div>
                            <label
                                for="new-password"
                                class="block text-sm font-medium text-gray-300 mb-2"
                            >
                                "New Password"
                                <span class="text-red-400" aria-hidden="true">"*"</span>
                            </label>
                            <input
                                type="password"
                                id="new-password"
                                name="new_password"
                                required=true
                                minlength=8
                                autocomplete="new-password"
                                class="input-base"
                                prop:value=move || new_password.get()
                                on:input=move |ev| set_new_password.set(event_target_value(&ev))
                            />
                            <div class="mt-2 flex items-center space-x-2">
                                <div class=move || {
                                    let base = "h-1 flex-1 rounded";
                                    if password_valid.get() {
                                        format!("{} bg-green-500", base)
                                    } else if new_password.get().len() >= 4 {
                                        format!("{} bg-yellow-500", base)
                                    } else {
                                        format!("{} bg-gray-600", base)
                                    }
                                } />
                            </div>
                            <p class=move || {
                                let base = "text-sm mt-1";
                                if password_valid.get() {
                                    format!("{} text-green-400", base)
                                } else {
                                    format!("{} text-gray-400", base)
                                }
                            }>
                                {move || {
                                    if password_valid.get() {
                                        "Password meets requirements"
                                    } else {
                                        "Minimum 8 characters"
                                    }
                                }}
                            </p>
                        </div>

                        <div>
                            <label
                                for="confirm-password"
                                class="block text-sm font-medium text-gray-300 mb-2"
                            >
                                "Confirm Password"
                                <span class="text-red-400" aria-hidden="true">"*"</span>
                            </label>
                            <input
                                type="password"
                                id="confirm-password"
                                name="confirm_password"
                                required=true
                                autocomplete="new-password"
                                class="input-base"
                                prop:value=move || confirm_password.get()
                                on:input=move |ev| set_confirm_password.set(event_target_value(&ev))
                            />
                            {move || {
                                let confirm = confirm_password.get();
                                if !confirm.is_empty() {
                                    if passwords_match.get() {
                                        view! {
                                            <p class="text-sm text-green-400 mt-1">"Passwords match"</p>
                                        }
                                            .into_any()
                                    } else {
                                        view! {
                                            <p class="text-sm text-red-400 mt-1">
                                                "Passwords do not match"
                                            </p>
                                        }
                                            .into_any()
                                    }
                                } else {
                                    view! {}.into_any()
                                }
                            }}
                        </div>

                        <ErrorAlert message=Signal::derive(move || error.get()) />

                        <SubmitButton
                            text="Reset Password"
                            loading_text="Resetting..."
                            pending=Signal::derive(move || pending.get())
                        />
                    </form>

                    <p class="text-sm text-gray-500 text-center mt-6">
                        "After resetting your password, you'll be redirected to your destination."
                    </p>
                </Card>
            </div>
        </CenteredLayout>
    }
}
