use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum MemoryTier {
    Immediate,
    Resonant,
    Crystallized,
    Dormant,
    Phantom,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoFact {
    pub id: Uuid,
    pub tier: MemoryTier,
    pub category: String,
    pub key: String,
    pub value: String,
    pub confidence: f32,
    pub created_at: DateTime<Utc>,
    pub last_accessed: DateTime<Utc>,
    pub access_count: u32,
    pub tags: Vec<String>,
    pub source_session: Option<String>,
    pub supersedes: Option<Uuid>,
}

impl MemoFact {
    pub fn new(
        tier: MemoryTier,
        category: impl Into<String>,
        key: impl Into<String>,
        value: impl Into<String>,
        confidence: f32,
    ) -> Self {
        let now = Utc::now();
        Self {
            id: Uuid::new_v4(),
            tier,
            category: category.into(),
            key: key.into(),
            value: value.into(),
            confidence,
            created_at: now,
            last_accessed: now,
            access_count: 0,
            tags: Vec::new(),
            source_session: None,
            supersedes: None,
        }
    }

    pub fn touch(&mut self) {
        self.last_accessed = Utc::now();
        self.access_count += 1;
    }

    pub fn age_days(&self) -> f64 {
        let dur = Utc::now() - self.created_at;
        dur.num_seconds() as f64 / 86_400.0
    }
}
