use serde::{Deserialize, Serialize};
use uuid::Uuid;

/// RunDiff compares two reconciliation runs to detect identity changes.
/// Used for shadow mode / A-B testing of spec changes.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RunDiff {
    pub baseline_run_id: String,
    pub candidate_run_id: String,
    pub entity: String,
    pub summary: DiffSummary,
    pub diffs: DiffDetails,
    pub risk_assessment: DiffRiskAssessment,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DiffSummary {
    pub total_records_compared: usize,
    pub identical_identities: usize,
    pub differences_detected: usize,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DiffDetails {
    pub over_merges: Vec<OverMerge>,
    pub under_merges: Vec<UnderMerge>,
    pub survivorship_diffs: Vec<SurvivorshipDiff>,
}

/// Baseline had separate identities, candidate merged them.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OverMerge {
    pub canonical_id: Uuid,
    pub baseline_canonical_ids: Vec<Uuid>,
    pub entity_ids: Vec<Uuid>,
}

/// Baseline had merged identities, candidate kept them separate.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UnderMerge {
    pub baseline_canonical_id: Uuid,
    pub candidate_canonical_ids: Vec<Uuid>,
    pub entity_ids: Vec<Uuid>,
}

/// Field-level difference in golden record survivorship.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SurvivorshipDiff {
    pub canonical_id: Uuid,
    pub field: String,
    pub baseline_value: Option<String>,
    pub candidate_value: Option<String>,
    pub baseline_source: Option<String>,
    pub candidate_source: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DiffRiskAssessment {
    pub over_merge_count: usize,
    pub under_merge_count: usize,
    pub survivorship_change_count: usize,
    pub risk_level: String,
}
