use std::sync::Arc;
use std::time::Duration;

use crate::config::AppConfig;
use crate::events::{Consolidator, EventStore, Pruner};
use crate::llm_runtime::SharedLlmRuntime;
use crate::memory::embeddings::EmbeddingService;
use crate::memory::manager::MemoryManager;
use crate::plans::PlanStore;
use crate::state::SqliteStateStore;

pub struct MemoryPipelineBundle {
    pub consolidator: Arc<Consolidator>,
    pub pruner: Arc<Pruner>,
    pub memory_manager: Arc<MemoryManager>,
}

pub fn build_memory_pipeline(
    config: &AppConfig,
    state: Arc<SqliteStateStore>,
    event_store: Arc<EventStore>,
    plan_store: Arc<PlanStore>,
    llm_runtime: SharedLlmRuntime,
    embedding_service: Arc<EmbeddingService>,
) -> MemoryPipelineBundle {
    let consolidator = Arc::new(
        Consolidator::new(
            event_store.clone(),
            plan_store,
            state.pool(),
            Some(llm_runtime.clone()),
            Some(embedding_service.clone()),
        )
        .with_state(state.clone())
        .with_learning_evidence_gate(config.policy.learning_evidence_gate_enforce),
    );

    let pruner = Arc::new(Pruner::new(
        event_store.clone(),
        consolidator.clone(),
        7, // 7-day retention
    ));

    let consolidation_interval =
        Duration::from_secs(config.state.consolidation_interval_hours * 3600);
    let memory_manager = Arc::new(
        MemoryManager::new(
            state.pool(),
            embedding_service,
            llm_runtime,
            consolidation_interval,
            Some(consolidator.clone()),
        )
        .with_event_store(event_store)
        .with_state(state)
        .with_people_config(config.people.clone()),
    );

    MemoryPipelineBundle {
        consolidator,
        pruner,
        memory_manager,
    }
}
