//! Thing - The Consensus Council (Raft).
//!
//! Named after the Nordic governing assembly, the Thing ensures all
//! nodes in the Yggdrasil cluster agree on the state of the well.

use crate::wal::Saga;
use crate::event_bus::EventBus;
use crate::signal::MemorySignal;
use mimirs_core::{MimirError, AgentId};

/// ThingNode - A node in the consensus cluster.
pub struct ThingNode {
    /// Local log of changes.
    pub saga: Saga,
    /// Current term in the consensus process.
    pub term: u64,
    /// Reference to the event bus for cluster coordination.
    pub bus: EventBus,
    /// Local agent identifier.
    pub agent_id: AgentId,
}

impl ThingNode {
    /// Opna - Creates a new Thing node.
    pub fn new(agent_id: AgentId, bus: EventBus) -> Self {
        Self {
            saga: Saga::new(),
            term: 0,
            bus,
            agent_id,
        }
    }

    /// Samykki - Propose and reach consensus on a change.
    pub async fn samykki(&mut self, change: Vec<u8>) -> Result<(), MimirError> {
        self.term += 1;
        tracing::info!(term = self.term, "Proposing change to the Thing council");
        
        // Emit consensus reached signal
        let _ = self.bus.broadcast(MemorySignal::ConsensusReached {
            agent_id: self.agent_id,
            term: self.term,
        });

        // Deserialize change into SagaEntry
        let entry: crate::wal::SagaEntry = bincode::deserialize(&change)
            .map_err(|e| MimirError::Serialization(e.to_string()))?;
            
        // Record in WAL (Saga)
        self.saga.skrifa(entry)?;

        // In a real system, this would involve RPCs to other nodes.
        // For this implementation, we broadcast the consensus through the event bus.
        tracing::info!(term = self.term, "Consensus reached by majority");
        Ok(())
    }
}

