//! Internal helpers shared across the research subsystem.

use std::sync::atomic::{AtomicU64, Ordering};

use chrono::Utc;
use sha2::{Digest, Sha256};

static NEXT_ID: AtomicU64 = AtomicU64::new(1);

#[must_use]
pub(crate) fn now_rfc3339() -> String {
    Utc::now().to_rfc3339()
}

#[must_use]
pub(crate) fn now_timestamp() -> i64 {
    Utc::now().timestamp()
}

#[must_use]
pub(crate) fn generate_id(prefix: &str) -> String {
    format!(
        "{prefix}-{}-{}",
        now_timestamp(),
        NEXT_ID.fetch_add(1, Ordering::Relaxed)
    )
}

#[must_use]
pub(crate) fn sha256_hex(input: impl AsRef<[u8]>) -> String {
    let mut hasher = Sha256::new();
    hasher.update(input.as_ref());
    format!("{:x}", hasher.finalize())
}

#[must_use]
pub(crate) fn normalize_text(input: &str) -> String {
    input.split_whitespace().collect::<Vec<_>>().join(" ")
}

#[must_use]
pub(crate) fn clean_title(input: &str, max_len: usize) -> String {
    let normalized = normalize_text(input);
    if normalized.chars().count() <= max_len {
        return normalized;
    }

    let mut shortened = normalized
        .chars()
        .take(max_len.saturating_sub(1))
        .collect::<String>();
    shortened.push('…');
    shortened
}
