//! Decision Threshold Tests
//! Tests DEC-001 thru DEC-004

use std::collections::HashMap;
use uuid::Uuid;
use chrono::Utc;
use cannon_core::types::{NormalizedEntity, Decision};
use cannon_core::matching::{MatchRule, ExactMatch};
use cannon_core::overrides::{OverrideResolver, ManualOverride, OverrideType};
use cannon_core::ReconciliationEngine;

// Helper to create a normalized entity
fn create_entity(data: Vec<(&str, &str)>) -> NormalizedEntity {
    let mut map = HashMap::new();
    for (k, v) in data {
        map.insert(k.to_string(), v.to_string());
    }
    NormalizedEntity {
        id: Uuid::new_v4(),
        tenant_id: Uuid::new_v4(),
        external_id: "ext".to_string(),
        entity_type: "customer".to_string(),
        data: map,
        source_name: "test".to_string(),
        valid_from: None,
        valid_to: None,
        last_updated: Utc::now(),
    }
}

// Helper to setup a basic engine
fn setup_engine(merge: f64, review: f64) -> ReconciliationEngine {
    let rule = Box::new(ExactMatch {
        field: "email".to_string(),
        weight: 1.0,
        case_insensitive: true,
        normalize: true,
        normalizer: None,
        rule_name: "email_exact".to_string(),
    });
    ReconciliationEngine::new(vec![rule], vec![], merge, review)
}

// ============================================================================
// DEC-001: Automatic Merge
// ============================================================================
#[test]
fn dec_001_automatic_merge() {
    let engine = setup_engine(0.9, 0.7);
    let a = create_entity(vec![("email", "test@example.com")]);
    let b = create_entity(vec![("email", "test@example.com")]);
    let resolver = OverrideResolver::new(vec![]);
    
    let decision = engine.evaluate_pair(&a, &b, &resolver, 1.0);
    assert_eq!(decision.decision, Decision::Merge);
    assert_eq!(decision.confidence, 1.0);
}

// ============================================================================
// DEC-002: Review Required
// ============================================================================
#[test]
fn dec_002_review_required() {
    let engine = setup_engine(0.9, 0.7);
    let a = create_entity(vec![("email", "test@example.com")]);
    let b = create_entity(vec![("email", "mismatch@example.com")]);
    let resolver = OverrideResolver::new(vec![]);
    
    // We need a rule that yields a score between 0.7 and 0.9.
    // Let's create a custom similarity rule for this.
    use cannon_core::matching::LevenshteinMatch;
    let sim_rule = Box::new(LevenshteinMatch {
        field: "name".to_string(),
        threshold: 0.5, // low threshold to ensure it "matches" but returns actual score
        weight: 1.0,
        normalizer: None,
        rule_name: "name_levenshtein".to_string(),
    });
    let engine = ReconciliationEngine::new(vec![sim_rule], vec![], 0.95, 0.5);
    
    let a = create_entity(vec![("name", "Johnathan")]);
    let b = create_entity(vec![("name", "Jonathan")]); // Score should be high but < 1.0
    
    let decision = engine.evaluate_pair(&a, &b, &resolver, 1.0);
    assert_eq!(decision.decision, Decision::Review);
    assert!(decision.confidence >= 0.5 && decision.confidence < 0.95);
}

// ============================================================================
// DEC-003: No Merge
// ============================================================================
#[test]
fn dec_003_no_merge() {
    let engine = setup_engine(0.9, 0.7);
    let a = create_entity(vec![("email", "test@example.com")]);
    let b = create_entity(vec![("email", "mismatch@example.com")]);
    let resolver = OverrideResolver::new(vec![]);
    
    let decision = engine.evaluate_pair(&a, &b, &resolver, 1.0);
    assert_eq!(decision.decision, Decision::NoMerge);
    assert_eq!(decision.confidence, 0.0);
}

// ============================================================================
// DEC-004: Manual Override Priority
// ============================================================================
#[test]
fn dec_004_manual_override_priority() {
    let engine = setup_engine(0.9, 0.7);
    let a = create_entity(vec![("email", "test@example.com")]);
    let b = create_entity(vec![("email", "test@example.com")]); // Normal merge
    
    // Force a Split
    let manual = ManualOverride {
        tenant_id: a.tenant_id,
        override_type: OverrideType::Split,
        entity_a_id: Some(a.id),
        entity_b_id: Some(b.id),
        canonical_id: None,
        override_data: serde_json::json!({}),
    };
    let resolver = OverrideResolver::new(vec![manual]);
    
    let decision = engine.evaluate_pair(&a, &b, &resolver, 1.0);
    assert_eq!(decision.decision, Decision::NoMerge); // Split priority
    assert!(decision.matched_on.contains(&"MANUAL_SPLIT".to_string()));
}
