use dioxus::prelude::*;

use crate::components::layout::icons;
use crate::util::model::{member::Member, session::Session, user::User};

#[component]
pub fn Settings() -> Element {
    rsx! {
        div {
            class: "w-full max-w-2xl space-y-3",
            Account {},
            Password {},
            Members {},
        }
    }
}

fn Account() -> Element {
    let user_state = use_context::<Signal<Option<User>>>();
    let user = user_state().unwrap();

    let mut is_open = use_signal(|| false);
    let mut input_email = use_signal(|| user.email);

    let mut loading = use_signal(|| false);

    let submit = move |_| async move {
        loading.set(true);
        if let Ok(_) = change_email(input_email()).await {
            tracing::info!("User email changed");
        };
        loading.set(false);
    };

    rsx! {
        div {
            class: "collapse collapse-arrow bg-base-200",
            class: if is_open() { "collapse-open" },
            div {
                class: "collapse-title text-lg font-medium hover:cursor-pointer select-none",
                onclick: move |_| is_open.toggle(),
                "Account",
            },
            div {
                class: "collapse-content",
                div {
                    class: "pl-2 flex flex-col gap-3",
                    label {
                        class: "form-control w-full",
                        div {
                            class: "label",
                            span { class: "label-text", "Account ID" }
                        }
                        b { "{user.id}" },
                    }
                    label {
                        class: "form-control w-full",
                        div {
                            class: "label",
                            span { class: "label-text", "Email" }
                        }
                        input {
                            r#type: "text",
                            class: "input input-bordered w-full",
                            oninput: move |event| input_email.set(event.value()),
                            value: "{input_email}",
                        }
                    }
                    div {
                        class: "w-full flex mt-5",
                        button {
                            class: "btn btn-outline btn-error",
                            onclick: move |_| async move {
                                loading.set(true);
                                if let Ok(_) = logout().await {
                                    let window = web_sys::window().expect("Could not find window");
                                    window.location().reload().expect("Could not reload window");
                                }
                                loading.set(false);
                            },
                            disabled: loading(),
                            if loading() {
                                span { class: "loading loading-spinner" }
                            }
                            "Uitloggen",
                        }
                        button {
                            class: "ml-auto btn btn-primary",
                            onclick: submit,
                            disabled: loading(),
                            if loading() {
                                span { class: "loading loading-spinner" }
                            }
                            "Opslaan",
                        }
                    }
                }
            },
        },
    }
}

#[server]
async fn logout() -> Result<(), ServerFnError> {
    let session_token = Session::get_token_from_cookie().await?;
    Session::delete_session(session_token).await?;
    Session::delete_cookie().await?;

    Ok(())
}

#[server]
async fn change_email(new_email: String) -> Result<(), ServerFnError> {
    let user = Session::fetch_current_user().await?;

    user.change_email(new_email).await?;

    Ok(())
}

fn Password() -> Element {
    let mut is_open = use_signal(|| false);

    let mut input_old_password = use_signal(|| "".to_string());
    let mut input_new_password = use_signal(|| "".to_string());
    let mut input_new_password_repeat = use_signal(|| "".to_string());

    let mut loading = use_signal(|| false);

    let submit = move |_| async move {
        loading.set(true);
        if let Ok(_) = change_password(input_old_password(), input_new_password()).await {
            tracing::info!("User password changed");
        };
        loading.set(false);
    };

    rsx! {
        div {
            class: "collapse collapse-arrow bg-base-200",
            class: if is_open() { "collapse-open" },
            div {
                class: "collapse-title text-lg font-medium hover:cursor-pointer select-none",
                onclick: move |_| is_open.toggle(),
                "Wachtwoord",
            },
            div {
                class: "collapse-content",
                div {
                    class: "pl-2 flex flex-col gap-3",
                    label {
                        class: "form-control w-full",
                        div {
                            class: "label",
                            span { class: "label-text", "Huidig wachtwoord" }
                        }
                        input {
                            r#type: "password",
                            class: "input input-bordered w-full",
                            oninput: move |event| input_old_password.set(event.value()),
                            value: "{input_old_password}",
                        }
                    }
                    label {
                        class: "form-control w-full",
                        div {
                            class: "label",
                            span { class: "label-text", "Nieuw wachtwoord" }
                        }
                        input {
                            r#type: "password",
                            class: "input input-bordered w-full",
                            oninput: move |event| input_new_password.set(event.value()),
                            value: "{input_new_password}",
                        }
                    }
                    label {
                        class: "form-control w-full",
                        div {
                            class: "label",
                            span { class: "label-text", "Herhaal nieuw wachtwoord" }
                        }
                        input {
                            r#type: "password",
                            class: "input input-bordered w-full",
                            oninput: move |event| input_new_password_repeat.set(event.value()),
                            value: "{input_new_password_repeat}",
                        }
                    }
                    div {
                        class: "w-full flex mt-5",
                        button {
                            class: "ml-auto btn btn-primary",
                            onclick: submit,
                            disabled: loading(),
                            if loading() {
                                span { class: "loading loading-spinner" }
                            }
                            "Opslaan",
                        }
                    }
                }
            },
        },
    }
}

#[server]
async fn change_password(old_password: String, new_password: String) -> Result<(), ServerFnError> {
    let user = Session::fetch_current_user().await?;

    user.change_password(old_password, new_password).await?;

    Ok(())
}

fn Members() -> Element {
    let mut members = use_resource(fetch_members);

    let mut is_open = use_signal(|| false);
    let mut input_registration_token = use_signal(|| "".to_string());

    rsx! {
        div {
            class: "collapse collapse-arrow bg-base-200",
            class: if is_open() { "collapse-open" },
            div {
                class: "collapse-title text-lg font-medium hover:cursor-pointer select-none",
                onclick: move |_| is_open.toggle(),
                "Leden",
            },
            div {
                class: "collapse-content",
                div {
                    class: "pl-2 flex flex-col gap-3",
                    match &*members.read() {
                        Some(Ok(res)) => {
                            let members_state = res.to_owned();

                            rsx! {
                                for member in members_state {
                                    div {
                                        class: "flex items-center",
                                        div {
                                            class: "flex flex-col",
                                            div {
                                                class: "",
                                                span { class: "font-bold", "{member.name.full}", }
                                                span { class: "mx-1.5", "•" }
                                                span { "{member.id}" }
                                            }
                                            div {
                                                class: "",
                                                span { "LS2" },
                                                span { class: "mx-1.5", "•" }
                                                span { "A1, B2" }
                                            }
                                        },
                                        div {
                                            class: "ml-auto mr-3 h-full text-error hover:cursor-pointer",
                                            onclick: move |_| {
                                                let id = member.id.clone();
                                                async move {
                                                    if let Ok(_res) = delete_member_relation(id).await {
                                                        members.restart();
                                                    }
                                                }
                                            },
                                            icons::Trash {}
                                        }
                                    }
                                    div { class: "divider my-0" }
                                }
                                div {
                                    class: "w-full join",
                                    input {
                                        r#type: "text",
                                        class: "input input-bordered w-full join-item",
                                        value: "{input_registration_token}",
                                        oninput: move |event| input_registration_token.set(event.value())
                                    },
                                    button {
                                        class: "btn join-item btn-neutral",
                                        onclick: move |_| async move {
                                            if let Ok(_res) = relate_member(input_registration_token()).await {
                                                members.restart();
                                                input_registration_token.set("".to_string());
                                            }
                                        },
                                        icons::UserPlus {},
                                        "Toevoegen",
                                    }
                                }
                            }
                        },
                        Some(Err(_)) => rsx! {
                            "Error"
                        },
                        None => rsx! { div { "Loading..." } },
                    }
                }
            },
        },
    }
}

#[server]
async fn fetch_members() -> Result<Vec<Member>, ServerFnError> {
    let user = Session::fetch_current_user().await?;

    let members = Member::fetch_from_user(user.id).await?;

    Ok(members)
}

#[server]
async fn relate_member(registration_token: String) -> Result<(), ServerFnError> {
    let user = Session::fetch_current_user().await?;
    let member_id = Member::fetch_from_registration_token(registration_token).await?;

    user.relate_member(member_id.id).await?;
    Ok(())
}

#[server]
async fn delete_member_relation(member_id: String) -> Result<(), ServerFnError> {
    let user = Session::fetch_current_user().await?;

    user.remove_relation(member_id).await?;
    Ok(())
}