
use leptos::*;
use leptos_router::*;

use crate::domain::api::prelude::*;
use super::auth_base::AuthBase;

use crate::domain::leptos::app::components::alert::Alert as AlertView;

#[server]
async fn login_action(email: String, password: String) -> Result<(), ServerFnError<String>> {
    use crate::domain::api::prelude::*;

    let app = use_context::<AppService>().unwrap();
    let session = use_context::<Session>().unwrap();

    let email = email.try_into().map_err(|e| format!("{}", e))?;

    let user = match app.user_login(UserLoginRequest::new(email, password)).await {
        Ok(u) => u,
        Err(_) => return Err(ServerFnError::WrappedServerError("Username or password incorrect".into())),
    };

    session.set("user", user.id());

    Ok(())
}

/// Renders the home page of your application.
#[component]
pub fn LoginPage(trigger_signal: RwSignal<bool>, direct_signal: RwSignal<Option<String>>) -> impl IntoView {
    let submit = Action::<LoginAction, _>::server();
    let response = submit.value().read_only();


    let callback = move || {
        let query = use_query_map();
        let Some(c) = query.with(|q| q.get("c").cloned()) else {
            return Some("/".to_string());
        };

        use base64::prelude::*;
        let dec = BASE64_URL_SAFE_NO_PAD.decode(c).unwrap_or_default();
        let c = String::from_utf8_lossy(&dec);
        Some(c.to_string())
    };

    create_effect(move |_| {
        if response.get().is_some() {
            trigger_signal.set(!trigger_signal.get_untracked());
            direct_signal.set(callback());
        }
    });

    let flash = create_resource(
        || (),
        move |_| async move {
            use crate::domain::leptos::get_flash;
            
            get_flash("login".to_string()).await.unwrap()
        },
    );

    view! {
            <AuthBase>

                <Suspense>
                    <Show when=move || response.get().is_some_and(|e| e.is_err())>
                        <AlertView alert={Alert::Error}>
                            { move || if let Some(Err(e)) = response.get() {
                                {format!("{}", e)}.into_view()
                            } else {
                                ().into_view()
                            }}
                        </AlertView>
                    </Show>
                </Suspense>

                <Suspense>
                    <Show when=move || flash().is_some_and(|u| u.is_some())>

                        <AlertView alert={ flash().unwrap().unwrap().alert() }>
                            { flash().unwrap().unwrap().message() }
                        </AlertView>

                    </Show>
                </Suspense>

                <ActionForm action=submit class="w-full">
                    <div class="flex flex-col gap-2">
                        <label class="input input-bordered flex items-center gap-2">
                            <i class="fas fa-envelope"></i>
                            <input type="text" placeholder="E-mail" name="email" class="grow" />
                        </label>

                        <label class="input input-bordered flex items-center gap-2">
                            <i class="fas fa-lock"></i>
                            <input type="password" placeholder="●●●●●●●●" name="password" class="grow" on:input=move |_| submit.value().set(None) />
                        </label>

                        <div>
                            <input type="submit" value="Login" class="btn btn-primary btn-block" />
                        </div>

                        <div class="text-center text-sm">
                            "New Account? Sign up "<a href="/auth/register" class="link">"here"</a>"!"
                        </div>
                        <div class="text-center text-sm">
                            <a href="/auth/forgot" class="link">"Forgot password"</a>
                        </div>
                    </div>
                    
                </ActionForm>

            </AuthBase>

    }
    .into_view()
}
