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

/// Record of an agent task execution in the knowledge graph
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ExecutionRecord {
    pub id: String,
    pub task_id: String,
    pub agent_id: String,
    pub agent_role: Option<String>,
    pub task_type: String,
    pub description: String,
    pub root_cause: Option<String>,
    pub solution: Option<String>,
    pub duration_ms: u64,
    pub input_tokens: u64,
    pub output_tokens: u64,
    pub cost_cents: u32,
    pub provider: String,
    pub success: bool,
    pub error: Option<String>,
    pub timestamp: DateTime<Utc>,
}

/// Recommendation based on historical data
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Recommendation {
    pub solution: String,
    pub confidence: f64,
    pub estimated_duration_ms: u64,
    pub source_record_id: String,
    pub source_agent_id: String,
    pub reasoning: String,
}

/// Relationship between execution records
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ExecutionRelation {
    /// Record A caused/led to record B
    CausedBy { from_id: String, to_id: String },
    /// Record A is similar to record B
    SimilarTo {
        record_a_id: String,
        record_b_id: String,
        similarity_score: f64,
    },
    /// Record A resolved problem from record B
    ResolvedBy {
        problem_id: String,
        solution_id: String,
    },
}

/// Query result with ranking
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SimilarityResult {
    pub record: ExecutionRecord,
    pub similarity_score: f64,
    pub rank: usize,
}

/// Temporal graph statistics
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct GraphStatistics {
    pub total_records: u64,
    pub total_successful: u64,
    pub total_failed: u64,
    pub avg_duration_ms: f64,
    pub distinct_task_types: u32,
    pub distinct_agents: u32,
    pub success_rate: f64,
}

/// Agent learning profile
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AgentProfile {
    pub agent_id: String,
    pub total_tasks: u64,
    pub success_count: u64,
    pub avg_duration_ms: f64,
    pub primary_task_types: Vec<String>,
    pub expertise_score: f64,
    pub learning_curve: Vec<f64>,
}

/// Causal relationship for reasoning
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CausalRelationship {
    pub cause: String,
    pub effect: String,
    pub confidence: f64,
    pub frequency: u32,
}

/// Provider analytics data
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProviderAnalytics {
    pub provider: String,
    pub total_cost_cents: u32,
    pub total_tasks: u64,
    pub successful_tasks: u64,
    pub failed_tasks: u64,
    pub success_rate: f64,
    pub avg_cost_per_task_cents: f64,
    pub total_input_tokens: u64,
    pub total_output_tokens: u64,
    pub cost_per_1m_tokens: f64,
}

/// Provider efficiency ranking
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProviderEfficiency {
    pub provider: String,
    pub quality_score: f64,
    pub cost_score: f64,
    pub efficiency_ratio: f64,
    pub rank: u32,
}

/// Provider performance by task type
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProviderTaskTypeMetrics {
    pub provider: String,
    pub task_type: String,
    pub total_cost_cents: u32,
    pub task_count: u64,
    pub success_rate: f64,
    pub avg_duration_ms: f64,
}

/// Result from hybrid search combining HNSW semantic and BM25 lexical retrieval
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HybridSearchResult {
    pub execution: crate::persistence::PersistedExecution,
    /// Cosine similarity score from HNSW vector search [0.0, 1.0]
    pub semantic_score: f64,
    /// BM25 relevance score from full-text search (unnormalized, higher = more
    /// relevant)
    pub lexical_score: f64,
    /// RRF fused score: sum of 1/(60 + rank) across both methods
    pub hybrid_score: f64,
    /// 1-indexed position in the semantic ranked list (0 if absent)
    pub semantic_rank: usize,
    /// 1-indexed position in the lexical ranked list (0 if absent)
    pub lexical_rank: usize,
}

/// Provider cost forecast
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProviderCostForecast {
    pub provider: String,
    pub current_daily_cost_cents: u32,
    pub projected_weekly_cost_cents: u32,
    pub projected_monthly_cost_cents: u32,
    pub trend: String,
    pub confidence: f64,
}
