use cannon_core::types::*;
use cannon_core::matching::*;
use cannon_core::blocking::*;
use cannon_core::overrides::*;
use cannon_core::ReconciliationEngine;
use serde::Deserialize;
use std::fs;

#[derive(Deserialize)]
struct TestCase {
    name: String,
    input_entities: Vec<NormalizedEntity>,
    expected_merges: Vec<(String, String)>,
}

#[derive(Deserialize)]
struct GoldenData {
    test_cases: Vec<TestCase>,
}

#[test]
fn test_golden_dataset() {
    let data = fs::read_to_string("tests/fixtures/golden.json").expect("Unable to read golden.json");
    let golden: GoldenData = serde_json::from_str(&data).expect("Unable to parse golden.json");

    let engine = ReconciliationEngine::new(
        vec![
            Box::new(ExactMatch { field: "email".to_string(), weight: 1.0, case_insensitive: true, normalize: true, normalizer: None, rule_name: "email_exact".to_string() }),
            Box::new(FuzzyStringMatch { field: "name".to_string(), threshold: 0.8, weight: 0.5, normalizer: None, rule_name: "name_fuzzy".to_string() }),
            Box::new(DomainMatch { fields: vec!["website".to_string(), "email".to_string()], weight: 0.8, rule_name: "domain_match".to_string() }),
        ],
        vec![
            Box::new(FieldBlocking { fields: vec!["email".to_string(), "website".to_string()] }),
            Box::new(DomainBlocking),
        ],
        0.2, // Lowered from 0.3
        0.1,
    );

    let resolver = OverrideResolver::new(vec![]);

    for case in golden.test_cases {
        let decisions = engine.reconcile(&case.input_entities, &resolver);

        for (expected_a, expected_b) in case.expected_merges {
            let found = decisions.iter().any(|d| {
                d.decision == Decision::Merge &&
                ((d.entity_a_id.to_string() == expected_a && d.entity_b_id.to_string() == expected_b) ||
                 (d.entity_a_id.to_string() == expected_b && d.entity_b_id.to_string() == expected_a))
            });
            assert!(found, "Test case '{}' failed: expected merge between {} and {} not found", case.name, expected_a, expected_b);
        }
    }
}
