// SPDX-License-Identifier: Apache-2.0
//! Sharing — who has access to what.
//!
//! RFC 006: each group collapsed by default (summary + count).
//! Grant detail and revoke buttons appear only after expanding.
//! "Stop all sharing" is inside the expanded state, not at page level.

use leptos::prelude::*;

use crate::components::confirm::ConfirmDialog;
use crate::components::icons::IconTrash;
use crate::mock::{ActiveShare, ShareKind, seed_active_shares};
use crate::state::{AppState, ToastKind};

#[component]
pub fn SharingPage() -> impl IntoView {
    let st = AppState::get();
    let shares = RwSignal::new(seed_active_shares());
    let confirm_revoke: RwSignal<Option<&'static str>> = RwSignal::new(None);
    let confirm_stop_all = RwSignal::new(false);

    let active = Memo::new(move |_| shares.with(|v| v.iter().filter(|s| s.is_active).count()));

    let family = Memo::new(move |_| {
        shares.with(|v| {
            v.iter()
                .filter(|s| s.kind == ShareKind::FamilyKey && s.is_active)
                .cloned()
                .collect::<Vec<_>>()
        })
    });
    let links = Memo::new(move |_| {
        shares.with(|v| {
            v.iter()
                .filter(|s| s.kind == ShareKind::PrivateLink && s.is_active)
                .cloned()
                .collect::<Vec<_>>()
        })
    });
    let invites = Memo::new(move |_| {
        shares.with(|v| {
            v.iter()
                .filter(|s| s.kind == ShareKind::Invitation)
                .cloned()
                .collect::<Vec<_>>()
        })
    });

    let do_revoke = Callback::new(move |_| {
        if let Some(id) = confirm_revoke.get() {
            shares.update(|v| {
                if let Some(s) = v.iter_mut().find(|s| s.id == id) {
                    s.is_active = false;
                }
            });
            st.toast("Access revoked.", ToastKind::Success);
        }
        confirm_revoke.set(None);
    });
    let do_stop_all = Callback::new(move |_| {
        shares.update(|v| v.iter_mut().for_each(|s| s.is_active = false));
        st.toast("All sharing stopped.", ToastKind::Neutral);
    });

    view! {
        <Show
            when=move || active.get() == 0
            fallback=|| ()
        >
            <div class="empty">
                <p class="empty__body">"All your albums are private."</p>
            </div>
        </Show>

        // Each group: collapsed summary → expand to see entries + danger action
        <Show when=move || !family.with(Vec::is_empty)>
            <ShareGroup title="Family key" items=family confirm_revoke confirm_stop_all />
        </Show>
        <Show when=move || !links.with(Vec::is_empty)>
            <ShareGroup title="Private links" items=links confirm_revoke confirm_stop_all />
        </Show>
        <Show when=move || !invites.with(Vec::is_empty)>
            <ShareGroup title="Invitations" items=invites confirm_revoke confirm_stop_all />
        </Show>

        <ConfirmDialog
            open=RwSignal::new(confirm_revoke.get().is_some())
            title="Revoke this access?"
            body="The viewer loses access immediately."
            confirm_label="Revoke"
            cancel_label="Keep"
            destructive=true
            on_confirm=do_revoke
        />
        <ConfirmDialog
            open=confirm_stop_all
            title="Stop all sharing?"
            body="Every link, invitation, and family-key grant is revoked immediately."
            confirm_label="Stop all sharing"
            cancel_label="Cancel"
            destructive=true
            on_confirm=do_stop_all
        />
    }
}

// ── Collapsible group ─────────────────────────────────────────────────────────

#[component]
fn ShareGroup(
    title: &'static str,
    items: Memo<Vec<ActiveShare>>,
    confirm_revoke: RwSignal<Option<&'static str>>,
    confirm_stop_all: RwSignal<bool>,
) -> impl IntoView {
    let open = RwSignal::new(false);
    let count = Memo::new(move |_| items.with(Vec::len));

    view! {
        <div class="share-group">
            // Summary line — the only thing visible when collapsed
            <button
                class="share-group__toggle"
                on:click=move |_| open.update(|v| *v = !*v)
                aria-expanded=move || open.get().to_string()
            >
                <span class="share-group__name">{title}</span>
                <span class="share-group__badge">{count}</span>
                <span class="share-group__arrow" aria-hidden="true">
                    {move || if open.get() { "▾" } else { "▸" }}
                </span>
            </button>

            // Detail — only rendered after expand
            <Show when=move || open.get()>
                <ul class="share-group__list" role="list">
                    <For
                        each=move || items.get()
                        key=|s| s.id
                        children=move |share| {
                            let id = share.id;
                            view! {
                                <li class="share-row">
                                    <div class="share-row__label">{share.label}</div>
                                    <div class="share-row__status">{share.status_note}</div>
                                    <button
                                        class="btn btn--ghost btn--sm btn--danger"
                                        on:click=move |_| confirm_revoke.set(Some(id))
                                    >
                                        <IconTrash size=13 />
                                        "Revoke"
                                    </button>
                                </li>
                            }
                        }
                    />
                </ul>
                // "Stop all" is inside expanded state — never visible at page level
                <div class="share-group__footer">
                    <button
                        class="btn--text btn--danger-text"
                        on:click=move |_| confirm_stop_all.set(true)
                    >
                        "Stop all sharing"
                    </button>
                </div>
            </Show>
        </div>
    }
}
