/*
    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::{DATABASE, session::Session};
use anyhow::Result;
use jellycommon::{
    Node, NodeKind, Visibility,
    api::{ApiStatsResponse, StatsBin},
};
use std::collections::BTreeMap;

pub fn stats(session: &Session) -> Result<ApiStatsResponse> {
    let mut items = DATABASE.list_nodes_with_udata(session.user.name.as_str())?;
    items.retain(|(n, _)| n.visibility >= Visibility::Reduced);

    trait BinExt {
        fn update(&mut self, node: &Node);
    }
    impl BinExt for StatsBin {
        fn update(&mut self, node: &Node) {
            self.count += 1;
            self.size += node.storage_size;
            if node.storage_size > self.max_size.0 {
                self.max_size = (node.storage_size, node.slug.clone())
            }
            if let Some(m) = &node.media {
                self.runtime += m.duration;
                if m.duration > self.max_runtime.0 {
                    self.max_runtime = (m.duration, node.slug.clone())
                }
            }
        }
    }

    let mut total = StatsBin::default();
    let mut kinds = BTreeMap::<NodeKind, StatsBin>::new();
    for (i, _) in items {
        total.update(&i);
        kinds.entry(i.kind).or_default().update(&i);
    }

    Ok(ApiStatsResponse { kinds, total })
}
