//! `space.polymodel.graph.getList` read endpoint handler.
//!
//! Hydrates a list's thing subjects from the `listitems` projection. Non-thing
//! subjects (listitems may reference any record) are filtered out with debug
//! logging rather than failing the whole list.

use axum::extract::State;
use jacquard::identity::PublicResolver;
use jacquard_axum::oauth::OptionalBrowserOAuthSession;
use jacquard_axum::{ExtractXrpc, XrpcResponse};
use jacquard_common::deps::smol_str::SmolStr;
use polymodel_api::space_polymodel::graph::get_list::{GetListOutput, GetListRequest};

use super::error::{AppResult, clamp_limit};
use super::state::AppState;
use super::views;
use super::views::viewer_did;
use crate::oauth::SqliteAuthStore;

pub(super) async fn get_list(
    State(state): State<AppState>,
    OptionalBrowserOAuthSession(session): OptionalBrowserOAuthSession<
        PublicResolver,
        SqliteAuthStore,
    >,
    ExtractXrpc(req): ExtractXrpc<GetListRequest>,
) -> AppResult<XrpcResponse<GetListRequest>> {
    let viewer_owned = viewer_did(session.as_ref()).await;
    let viewer = viewer_owned.as_ref().map(|d| d.borrow());
    let (items, cursor) = views::list_things(
        &state,
        req.list.as_ref(),
        clamp_limit(req.limit),
        req.cursor.as_deref(),
        viewer,
    )
    .await?;
    Ok(XrpcResponse(GetListOutput {
        items,
        cursor: cursor.map(SmolStr::from),
        extra_data: None,
    }))
}
