//! Staff management page component.

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

use crate::components::{Card, EmptyState, MessageAlertRw, PageHeader, RoleBadge};
use crate::hooks::use_fetch;
use crate::models::StaffMemberSummary;
#[cfg(feature = "hydrate")]
use crate::utils::reload_page;

/// Staff page component.
#[component]
pub fn StaffPage() -> impl IntoView {
    let message = RwSignal::new(Option::<(String, bool)>::None);

    let staff = use_fetch::<Vec<StaffMemberSummary>>(|| "/api/admin/staff".to_string());

    view! {
        <PageHeader title="Server Staff" subtitle="Manage server administrators">
            <AddStaffButton message=message />
        </PageHeader>

        <MessageAlertRw message=message />

        <Card>
            <Suspense fallback=|| view! { <p>"Loading staff..."</p> }>
                {move || {
                    staff.get().map(|maybe_staff| {
                        match maybe_staff {
                            Some(staff_list) if !staff_list.is_empty() => {
                                view! {
                                    <div class="table-container">
                                        <table class="data-table">
                                            <thead>
                                                <tr>
                                                    <th>"Username"</th>
                                                    <th>"Display Name"</th>
                                                    <th>"Email"</th>
                                                    <th>"Role"</th>
                                                    <th>"Appointed"</th>
                                                    <th>"Actions"</th>
                                                </tr>
                                            </thead>
                                            <tbody>
                                                {staff_list.into_iter().map(|member| {
                                                    let user_id = member.user_id.clone();
                                                    view! {
                                                        <tr>
                                                            <td>
                                                                <a href=format!("/admin/users/{}", member.user_id) class="table-link">
                                                                    {member.username}
                                                                </a>
                                                            </td>
                                                            <td>{member.display_name}</td>
                                                            <td>{member.email.unwrap_or_else(|| "-".to_string())}</td>
                                                            <td><RoleBadge role=member.role /></td>
                                                            <td>{member.appointed_at}</td>
                                                            <td>
                                                                <RemoveStaffButton
                                                                    user_id=user_id
                                                                    message=message
                                                                />
                                                            </td>
                                                        </tr>
                                                    }
                                                }).collect_view()}
                                            </tbody>
                                        </table>
                                    </div>
                                }.into_any()
                            }
                            _ => view! {
                                <EmptyState message="No staff members found." />
                            }.into_any()
                        }
                    })
                }}
            </Suspense>
        </Card>
    }
}

#[component]
#[allow(unused_variables)]
fn AddStaffButton(message: RwSignal<Option<(String, bool)>>) -> impl IntoView {
    let (show_modal, set_show_modal) = signal(false);
    let (user_id, set_user_id) = signal(String::new());
    let (role, set_role) = signal("moderator".to_string());
    let (pending, set_pending) = signal(false);

    let on_submit = move |ev: leptos::ev::SubmitEvent| {
        ev.prevent_default();
        set_pending.set(true);

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

            let data = serde_json::json!({
                "user_id": user_id.get(),
                "role": role.get()
            });

            spawn_local(async move {
                let response = Request::post("/api/admin/staff")
                    .json(&data)
                    .unwrap()
                    .send()
                    .await;

                set_pending.set(false);

                match response {
                    Ok(resp) if resp.ok() => {
                        message.set(Some(("Staff member added!".to_string(), true)));
                        set_show_modal.set(false);
                        set_user_id.set(String::new());
                        reload_page();
                    }
                    Ok(_) => {
                        message.set(Some(("Failed to add staff member".to_string(), false)));
                    }
                    Err(_) => {
                        message.set(Some(("Network error".to_string(), false)));
                    }
                }
            });
        }
    };

    view! {
        <button
            type="button"
            class="btn btn-primary"
            on:click=move |_| set_show_modal.set(true)
        >
            "Add Staff Member"
        </button>

        <Show when=move || show_modal.get()>
            <div class="modal-overlay">
                <div class="modal-backdrop" on:click=move |_| set_show_modal.set(false)></div>
                <div class="modal-content">
                    <button
                        type="button"
                        class="modal-close"
                        on:click=move |_| set_show_modal.set(false)
                    >
                        "x"
                    </button>

                    <h3 class="modal-title">"Add Staff Member"</h3>

                    <form on:submit=on_submit>
                        <div class="form-group">
                            <label for="staff_user_id" class="form-label">"User ID"</label>
                            <input
                                type="text"
                                id="staff_user_id"
                                required=true
                                class="form-input"
                                placeholder="UUID of user to make staff"
                                prop:value=move || user_id.get()
                                on:input=move |ev| set_user_id.set(event_target_value(&ev))
                            />
                        </div>

                        <div class="form-group">
                            <label for="staff_role" class="form-label">"Role"</label>
                            <select
                                id="staff_role"
                                class="form-select"
                                on:change=move |ev| set_role.set(event_target_value(&ev))
                            >
                                <option value="moderator" selected=move || role.get() == "moderator">"Moderator"</option>
                                <option value="admin" selected=move || role.get() == "admin">"Admin"</option>
                                <option value="owner" selected=move || role.get() == "owner">"Owner"</option>
                            </select>
                        </div>

                        <div class="modal-actions">
                            <button
                                type="button"
                                class="btn btn-secondary"
                                on:click=move |_| set_show_modal.set(false)
                            >
                                "Cancel"
                            </button>
                            <button
                                type="submit"
                                class="btn btn-primary"
                                disabled=move || pending.get()
                            >
                                {move || if pending.get() { "Adding..." } else { "Add Staff" }}
                            </button>
                        </div>
                    </form>
                </div>
            </div>
        </Show>
    }
}

#[component]
#[allow(unused_variables)]
fn RemoveStaffButton(
    user_id: String,
    message: RwSignal<Option<(String, bool)>>,
) -> impl IntoView {
    let (pending, set_pending) = signal(false);
    #[cfg(feature = "hydrate")]
    let user_id_for_click = user_id.clone();

    let on_click = move |_| {
        #[cfg(feature = "hydrate")]
        {
            use crate::utils::confirm;

            if !confirm("Remove this staff member?") {
                return;
            }
        }

        set_pending.set(true);

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

            let user_id = user_id_for_click.clone();
            spawn_local(async move {
                let response = Request::delete(&format!("/api/admin/staff/{}", user_id))
                    .send()
                    .await;

                set_pending.set(false);

                match response {
                    Ok(resp) if resp.ok() => {
                        message.set(Some(("Staff member removed!".to_string(), true)));
                        reload_page();
                    }
                    _ => {
                        message.set(Some(("Failed to remove staff member".to_string(), false)));
                    }
                }
            });
        }
    };

    view! {
        <button
            type="button"
            class="btn btn-danger btn-sm"
            disabled=move || pending.get()
            on:click=on_click
        >
            {move || if pending.get() { "..." } else { "Remove" }}
        </button>
    }
}
