/*
    This file is part of jellything (https://codeberg.org/metamuffin/jellything)
    which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
    Copyright (C) 2026 metamuffin <metamuffin.org>
*/

use crate::{request_info::RequestInfo, routes::error::MyResult};
use anyhow::anyhow;
use base64::{Engine, prelude::BASE64_URL_SAFE};
use jellycommon::{
    jellyobject::{EMPTY, Path},
    *,
};
use jellydb::{Filter, MultiBehaviour, Query, Sort, SortOrder, ValueSort};
use jellyui::components::items::Items;
use rocket::{get, response::content::RawHtml};
use std::borrow::Cow;

#[get("/items?<cont>")]
pub fn r_items(ri: RequestInfo, cont: Option<&str>) -> MyResult<RawHtml<String>> {
    let cont_in = cont
        .map(|s| BASE64_URL_SAFE.decode(s))
        .transpose()
        .map_err(|_| anyhow!("invalid contination token"))?;

    let mut items = Vec::new();
    let mut cont_out = None;
    ri.state.database.transaction(&mut |txn| {
        let rows = txn
            .query(Query {
                filter: Filter::All(vec![
                    Filter::Match(Path(vec![NO_KIND.0]), KIND_VIDEO.into()),
                    Filter::Match(Path(vec![NO_VISIBILITY.0]), VISI_VISIBLE.into()),
                ]),
                sort: Sort::Value(ValueSort {
                    path: Path(vec![NO_RELEASEDATE.0]),
                    multi: MultiBehaviour::First,
                    order: SortOrder::Descending,
                    offset: None,
                }),
                continuation: cont_in.clone(),
                ..Default::default()
            })?
            .take(64)
            .collect::<Result<Vec<_>, _>>()?;

        items.clear();
        cont_out = None;
        for (r, is) in rows {
            let node = txn.get(r)?.unwrap();
            items.push(node);
            cont_out = Some(is)
        }
        Ok(())
    })?;

    Ok(ri.respond_ui(&Items {
        ri: &ri.render_info(),
        items: &items
            .iter()
            .map(|node| Nku {
                node: Cow::Borrowed(&node),
                userdata: Cow::Borrowed(EMPTY),
                role: None,
            })
            .collect::<Vec<_>>(),
        cont: cont_out.map(|x| BASE64_URL_SAFE.encode(x)),
    }))
}
