use serde::{Deserialize, Serialize};
use serde_json::Value;

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Drop {
  // We don't need id, frequency, etc. for the validation result specifically,
  // as they are added by the SQL wrapper. We just need to conform to the structure.
  // The user said "Validator::validate always needs to return this drop type".
  // So we should match it as closely as possible.
  #[serde(rename = "type")]
  pub type_: String, // "drop"

  #[serde(skip_serializing_if = "Option::is_none")]
  pub response: Option<Value>,

  #[serde(default, skip_serializing_if = "Vec::is_empty")]
  pub errors: Vec<Error>,
}

impl Default for Drop {
  fn default() -> Self {
    Self::new()
  }
}

impl Drop {
  pub fn new() -> Self {
    Self {
      type_: "drop".to_string(),
      response: None,
      errors: vec![],
    }
  }

  pub fn success() -> Self {
    Self {
      type_: "drop".to_string(),
      response: Some(serde_json::json!("success")),
      errors: vec![],
    }
  }

  pub fn success_with_val(val: Value) -> Self {
    Self {
      type_: "drop".to_string(),
      response: Some(val),
      errors: vec![],
    }
  }

  pub fn with_errors(errors: Vec<Error>) -> Self {
    Self {
      type_: "drop".to_string(),
      response: None,
      errors,
    }
  }
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Error {
  pub code: String,
  pub message: String,
  pub details: ErrorDetails,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ErrorDetails {
  pub path: String,
  // Extensions can be added here (package, cause, etc)
  // For now, validator only provides path
}
