use crate::domain::types::{
Contradiction, CorrelationScore, Entity, GraphEdge, GraphStats, Neighborhood, UserEntity,
};
use std::collections::HashMap;
pub trait GraphRepository: Send + Sync {
fn get_entity(&self, id: &str) -> Option<&Entity>;
fn get_entities_batch(&self, ids: &[&str]) -> HashMap<String, &Entity>;
fn get_neighbors(&self, entity_id: &str, relation_type: Option<&str>) -> Vec<String>;
fn get_all_edges(&self, entity_id: &str) -> Vec<GraphEdge>;
fn get_neighborhood(&self, id: &str) -> Option<Neighborhood>;
fn find_shortest_path(
&self,
from_id: &str,
to_id: &str,
max_depth: usize,
) -> Option<Vec<String>>;
fn find_similar_entities(&self, entity_id: &str, threshold: f64) -> Vec<(String, f64)>;
fn find_contradictions(&self) -> Vec<Contradiction>;
fn stats(&self) -> GraphStats;
fn all_entity_ids(&self) -> Vec<String>;
}
pub trait MutableGraphRepository: Send + Sync {
fn add_entity(&self, entity: UserEntity) -> Result<(), String>;
fn update_entity(&self, id: &str, entity: UserEntity) -> Result<(), String>;
fn remove_entity(&self, id: &str) -> Result<(), String>;
fn add_relation(&self, from: &str, relation: &str, to: &str) -> Result<(), String>;
fn remove_relation(&self, from: &str, relation: &str, to: &str) -> Result<(), String>;
fn get_user_entity(&self, id: &str) -> Option<UserEntity>;
fn all_user_entity_ids(&self) -> Vec<String>;
fn get_user_neighbors(&self, entity_id: &str, relation_type: Option<&str>) -> Vec<String>;
fn get_user_all_edges(&self, entity_id: &str) -> Vec<GraphEdge>;
fn search_user_entities(&self, query: &str, limit: usize) -> Vec<UserEntity>;
fn all_user_entities(&self) -> Vec<UserEntity>;
fn compute_correlations(&self, insight_id: &str) -> Vec<CorrelationScore>;
fn store_embedding(&self, entity_id: &str, embedding: &[f32]) -> Result<(), String>;
fn get_embedding(&self, entity_id: &str) -> Option<Vec<f32>>;
fn user_entity_count(&self) -> usize;
fn next_insight_id(&self) -> Result<String, String> {
let ids = self.all_user_entity_ids();
let max_num = ids
.iter()
.filter_map(|id| id.strip_prefix("TK-").and_then(|n| n.parse::<u32>().ok()))
.max()
.unwrap_or(0);
Ok(format!("TK-{:03}", max_num + 1))
}
}