#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub enum PyBlockerConfig {
    Exact {
        field: String,
    },
    Phonetic {
        field: String,
        algorithm: String,
    },
    SortedNeighborhood {
        field: String,
        window: usize,
    },
    Qgram {
        field: String,
        q: usize,
        threshold: usize,
    },
    Lsh {
        field: String,
        num_hashes: usize,
        num_bands: usize,
    },
    Canopy {
        field: String,
        t_tight: f64,
        t_loose: f64,
        metric: String,
    },
    Numeric {
        field: String,
        bucket_size: f64,
    },
    DateBlock {
        field: String,
        resolution: String,
    },
    Trie {
        field: String,
        min_prefix_len: usize,
        max_frequency: usize,
    },
    #[serde(skip)]
    Custom {
        name: String,
    },
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub enum PyClusterConfig {
    None,
    ConnectedComponents,
    Hierarchical { linkage: String, threshold: f64 },
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub enum PyComparatorConfig {
    String {
        field: String,
        metric: String,
    },
    Exact {
        field: String,
    },
    Numeric {
        field: String,
        max_diff: f64,
    },
    Date {
        field: String,
    },
    Phonetic {
        field: String,
        algorithm: String,
    },
    #[serde(skip)]
    Custom {
        field: String,
        name: String,
    },
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub enum PyClassifierConfig {
    Threshold {
        threshold: f64,
    },
    Weighted {
        weights: Vec<f64>,
        threshold: f64,
    },
    FellegiSunter {
        m_probs: Vec<f64>,
        u_probs: Vec<f64>,
        upper: f64,
        lower: f64,
    },
    FellegiSunterAuto {
        max_iterations: usize,
        convergence_threshold: f64,
        initial_p_match: f64,
    },
    ThresholdBands {
        upper: f64,
        lower: f64,
    },
    WeightedBands {
        weights: Vec<f64>,
        upper: f64,
        lower: f64,
    },
    #[serde(skip)]
    Custom {
        name: String,
    },
}

/// Complete serializable configuration for a pipeline.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PipelineConfig {
    pub blockers: Vec<PyBlockerConfig>,
    pub comparators: Vec<PyComparatorConfig>,
    pub classifier: Option<PyClassifierConfig>,
    pub cluster: PyClusterConfig,
    pub preprocess_lowercase: Vec<String>,
    pub preprocess_ops: std::collections::BTreeMap<String, Vec<String>>,
    pub numeric_fields: Vec<String>,
    pub date_fields: Vec<String>,
}
