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

#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum OverrideType {
    Merge,
    Split,
    Lock,
    Field,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ManualOverride {
    pub tenant_id: Uuid,
    pub override_type: OverrideType,
    pub entity_a_id: Option<Uuid>, 
    pub entity_b_id: Option<Uuid>, 
    pub canonical_id: Option<Uuid>, 
    pub override_data: serde_json::Value,
}

pub struct OverrideResolver {
    pub overrides: Vec<ManualOverride>,
}

impl OverrideResolver {
    pub fn new(overrides: Vec<ManualOverride>) -> Self {
        Self { overrides }
    }

    pub fn is_split(&self, id_a: Uuid, id_b: Uuid) -> bool {
        self.overrides.iter().any(|o| {
            matches!(o.override_type, OverrideType::Split) &&
            ((o.entity_a_id == Some(id_a) && o.entity_b_id == Some(id_b)) ||
             (o.entity_a_id == Some(id_b) && o.entity_b_id == Some(id_a)))
        })
    }

    pub fn is_forced_merge(&self, id_a: Uuid, id_b: Uuid) -> bool {
        self.overrides.iter().any(|o| {
            matches!(o.override_type, OverrideType::Merge) &&
            ((o.entity_a_id == Some(id_a) && o.entity_b_id == Some(id_b)) ||
             (o.entity_a_id == Some(id_b) && o.entity_b_id == Some(id_a)))
        })
    }

    pub fn is_locked(&self, id_a: Uuid, id_b: Uuid) -> bool {
        self.overrides.iter().any(|o| {
            matches!(o.override_type, OverrideType::Lock) &&
            ((o.entity_a_id == Some(id_a) && o.entity_b_id == Some(id_b)) ||
             (o.entity_a_id == Some(id_b) && o.entity_b_id == Some(id_a)))
        })
    }

    pub fn get_field_override(&self, canonical_id: Uuid, field: &str) -> Option<serde_json::Value> {
        self.overrides.iter()
            .find(|o| {
                matches!(o.override_type, OverrideType::Field) &&
                o.canonical_id == Some(canonical_id) &&
                o.override_data.get(field).is_some()
            })
            .and_then(|o| o.override_data.get(field).cloned())
    }
}
