//! Login page component.

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

use crate::components::Card;

/// Login page component.
#[component]
pub fn LoginPage() -> impl IntoView {
    let (username, set_username) = signal(String::new());
    let (password, set_password) = signal(String::new());
    let (error, set_error) = signal(Option::<String>::None);
    let (pending, set_pending) = signal(false);

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

        let uname = username.get();
        let pwd = password.get();

        if uname.is_empty() || pwd.is_empty() {
            set_error.set(Some("Username and password are required".to_string()));
            return;
        }

        set_pending.set(true);

        #[cfg(feature = "hydrate")]
        {
            use gloo_net::http::Request;

            spawn_local(async move {
                let response = Request::post("/api/admin/auth/login")
                    .json(&serde_json::json!({
                        "username": uname,
                        "password": pwd
                    }))
                    .unwrap()
                    .send()
                    .await;

                set_pending.set(false);

                match response {
                    Ok(resp) if resp.ok() => {
                        // Redirect to dashboard
                        if let Some(window) = web_sys::window() {
                            let _ = window.location().set_href("/admin");
                        }
                    }
                    Ok(resp) => {
                        #[derive(serde::Deserialize)]
                        struct ErrorResp {
                            error: String,
                        }
                        if let Ok(err) = resp.json::<ErrorResp>().await {
                            set_error.set(Some(err.error));
                        } else {
                            set_error.set(Some("Invalid username or password".to_string()));
                        }
                    }
                    Err(_) => {
                        set_error.set(Some("Network error. Please try again.".to_string()));
                    }
                }
            });
        }
    };

    view! {
        <div class="login-container">
            <div class="login-header">
                <h1>"Chattyness"</h1>
                <span class="login-badge">"Admin Panel"</span>
                <p>"Administration interface"</p>
            </div>

            <Card class="login-card">
                <form on:submit=on_submit class="login-form">
                    <div class="form-group">
                        <label for="username" class="form-label">
                            "Username"
                            <span class="required">"*"</span>
                        </label>
                        <input
                            type="text"
                            id="username"
                            name="username"
                            required=true
                            autocomplete="username"
                            placeholder="Enter your username"
                            class="form-input"
                            prop:value=move || username.get()
                            on:input=move |ev| set_username.set(event_target_value(&ev))
                        />
                    </div>

                    <div class="form-group">
                        <label for="password" class="form-label">
                            "Password"
                            <span class="required">"*"</span>
                        </label>
                        <input
                            type="password"
                            id="password"
                            name="password"
                            required=true
                            autocomplete="current-password"
                            placeholder="Enter your password"
                            class="form-input"
                            prop:value=move || password.get()
                            on:input=move |ev| set_password.set(event_target_value(&ev))
                        />
                    </div>

                    <Show when=move || error.get().is_some()>
                        <div class="alert alert-error" role="alert">
                            <p>{move || error.get().unwrap_or_default()}</p>
                        </div>
                    </Show>

                    <button
                        type="submit"
                        class="btn btn-primary btn-full"
                        disabled=move || pending.get()
                    >
                        {move || if pending.get() { "Signing in..." } else { "Sign In" }}
                    </button>
                </form>
            </Card>
        </div>
    }
}
