use crate::data::{Value, condition::Condition, executable_query::ExecutableQuery};

pub struct UpdateBuilder {
  table: String,
  columns: Vec<String>,
  values: Vec<Value>,
  condition: Option<Condition>,
}

impl UpdateBuilder {
  pub fn new(table: &str) -> Self {
    Self {
      table: table.to_string(),
      columns: Vec::new(),
      values: Vec::new(),
      condition: None,
    }
  }

  pub fn column(mut self, column: &str, value: Value) -> Self {
    self.columns.push(column.to_string());
    self.values.push(value);
    self
  }

  pub fn where_condition(mut self, condition: Condition) -> Self {
    self.condition = Some(condition);
    self
  }
}

impl ExecutableQuery for UpdateBuilder {
  fn build(&self) -> (String, Vec<Value>) {
    if self.columns.is_empty() {
      panic!("Cannot build update query without columns to set");
    }

    // Generate the SET clause
    let set_clause = self
      .columns
      .iter()
      .enumerate()
      .map(|(i, col)| format!("{} = ${}", col, i + 1))
      .collect::<Vec<_>>()
      .join(", ");

    let mut query = format!("UPDATE {} SET {}", self.table, set_clause);
    let mut counter = self.values.len();
    let mut values: Vec<Value> = self.values.clone();

    // Build where clause
    if let Some(condition) = &self.condition {
      let where_condition = condition.to_sql(&mut counter);
      query.push_str(&format!(" WHERE {}", where_condition.0));
      values.extend(where_condition.1);
    }

    (query, values)
  }
}
