//! Materialized view data structures for O(1) reads.

use rkyv::{Archive, Deserialize, Serialize};

use crate::types::Assertion;

/// A pre-computed resolution stored at `MV:{subject}:{predicate}`.
///
/// The Materializer writes these to enable O(1) reads for standard lenses.
/// Each view captures the winning assertion plus resolution metadata for provenance.
#[derive(Archive, Deserialize, Serialize, Debug, Clone, PartialEq)]
#[archive(check_bytes)]
pub struct MaterializedView {
    /// The winning assertion from lens resolution.
    pub winner: Assertion,
    /// Which lens produced this result (e.g., "VoteAwareConsensus").
    pub lens_name: String,
    /// Confidence in the resolution (0.0 to 1.0).
    pub resolution_confidence: f32,
    /// Degree of disagreement among candidates (0.0 = full agreement, 1.0 = max conflict).
    /// See `stemedb_lens::compute_conflict_score()` for the canonical algorithm.
    pub conflict_score: f32,
    /// Number of candidate assertions that were considered.
    pub candidates_count: usize,
    /// Unix timestamp when this view was last materialized.
    pub materialized_at: u64,
}

/// A changelog entry recording when a materialized view's winner changed.
///
/// Stored at `MVC:{subject}:{predicate}:{timestamp}` to enable efficient
/// "what changed since timestamp T?" queries for incremental updates.
///
/// # Storage Key Pattern
/// `MVC:Semaglutide:muscle_effect:1704067200` -> serialized ChangeEntry
///
/// # Example
/// When the Materializer re-resolves `Semaglutide:muscle_effect` and the
/// winner changes from assertion A to assertion B, it writes a ChangeEntry
/// recording both the previous and new winner hashes.
#[derive(Archive, Deserialize, Serialize, Debug, Clone, PartialEq)]
#[archive(check_bytes)]
pub struct ChangeEntry {
    /// Unix timestamp when this change was recorded.
    pub timestamp: u64,

    /// Hash of the previous winner assertion (None if this was the first MV).
    pub previous_winner_hash: Option<[u8; 32]>,

    /// Hash of the new winner assertion.
    pub new_winner_hash: [u8; 32],

    /// Subject of the changed pair.
    pub subject: String,

    /// Predicate of the changed pair.
    pub predicate: String,

    /// Which lens was used for resolution.
    pub lens_name: String,
}
