use chrono::{DateTime, Utc};
use nostr_rs_types::types::Id;

/// Creates a secondary index for a given event ID. The secondary index is
/// sorted by created time in a descendent order, meaning that newer events will
/// be first.
///
/// This is useful to leverage natural sorting of the database, and to be able
/// to create secondary indexes to find by author, kind, tag, etc, and have that
/// result sorted by date naturally
pub struct SecondaryIndex<'a> {
    entry_id: &'a Id,
    sort_by: [u8; 8],
}

impl<'a> SecondaryIndex<'a> {
    pub fn new(entry_id: &'a Id, date_time: DateTime<Utc>) -> Self {
        // We need to reverse the number, to sort it. Otherwise, the first is
        // going to be the oldest entry, instead of the newest.
        let reversed_order_by = u64::MAX
            .checked_sub(date_time.timestamp() as u64)
            .unwrap_or_default()
            .to_be_bytes();
        Self {
            entry_id,
            sort_by: reversed_order_by,
        }
    }

    pub fn index_by<T: AsRef<[u8]>>(&self, index_by: T) -> Vec<u8> {
        let mut new_id = index_by.as_ref().to_vec();
        new_id.extend_from_slice(&self.sort_by);
        new_id.extend_from_slice(self.entry_id.as_ref());
        new_id
    }
}
