nonce_action = $nonce_action;
		$this->set_default_attributes();
	}
	/**
	 * Set default form attributes
	 */
	private function set_default_attributes() {
		$this->form_attrs = array(
			'method' => 'post',
			'action' => '',
			'id' => '',
			'class' => 'hvac-form',
			'enctype' => 'application/x-www-form-urlencoded',
		);
	}
	/**
	 * Set form attributes
	 *
	 * @param array $attrs Form attributes
	 * @return self
	 */
	public function set_attributes( $attrs ) {
		$this->form_attrs = array_merge( $this->form_attrs, $attrs );
		return $this;
	}
	/**
	 * Add a field to the form
	 *
	 * @param array $field Field configuration
	 * @return self
	 */
	public function add_field( $field ) {
		$defaults = array(
			'type' => 'text',
			'name' => '',
			'label' => '',
			'value' => '',
			'required' => false,
			'placeholder' => '',
			'class' => '',
			'id' => '',
			'options' => array(),
			'sanitize' => 'text',
			'validate' => array(),
			'description' => '',
			'wrapper_class' => 'form-row',
		);
		$field = wp_parse_args( $field, $defaults );
		
		// Auto-generate ID if not provided
		if ( empty( $field['id'] ) && ! empty( $field['name'] ) ) {
			$field['id'] = sanitize_html_class( $field['name'] );
		}
		$this->fields[] = $field;
		return $this;
	}
	/**
	 * Set form data
	 *
	 * @param array $data Form data
	 * @return self
	 */
	public function set_data( $data ) {
		$this->data = $data;
		return $this;
	}
	/**
	 * Set form errors
	 *
	 * @param array $errors Form errors
	 * @return self
	 */
	public function set_errors( $errors ) {
		$this->errors = $errors;
		return $this;
	}
	/**
	 * Render the form
	 *
	 * @return string
	 */
	public function render() {
		ob_start();
		?>
		
		form_attrs as $key => $value ) {
			if ( ! empty( $value ) ) {
				$attrs[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) );
			}
		}
		return implode( ' ', $attrs );
	}
	/**
	 * Render a single field
	 *
	 * @param array $field Field configuration
	 * @return string
	 */
	private function render_field( $field ) {
		$output = sprintf( '', esc_attr( $field['wrapper_class'] ) );
		
		// Label
		if ( ! empty( $field['label'] ) ) {
			$output .= sprintf(
				'',
				esc_attr( $field['id'] ),
				esc_html( $field['label'] ),
				$field['required'] ? ' *' : ''
			);
		}
		// Field
		switch ( $field['type'] ) {
			case 'select':
				$output .= $this->render_select( $field );
				break;
			case 'textarea':
				$output .= $this->render_textarea( $field );
				break;
			case 'checkbox':
				$output .= $this->render_checkbox( $field );
				break;
			case 'radio':
				$output .= $this->render_radio( $field );
				break;
			case 'file':
				$output .= $this->render_file( $field );
				break;
			default:
				$output .= $this->render_input( $field );
		}
		// Description
		if ( ! empty( $field['description'] ) ) {
			$output .= sprintf( '%s', esc_html( $field['description'] ) );
		}
		// Error
		if ( isset( $this->errors[ $field['name'] ] ) ) {
			$output .= sprintf( 
				'%s', 
				esc_html( $this->errors[ $field['name'] ] ) 
			);
		}
		$output .= '
';
		return $output;
	}
	/**
	 * Render input field
	 *
	 * @param array $field Field configuration
	 * @return string
	 */
	private function render_input( $field ) {
		$value = $this->get_field_value( $field['name'], $field['value'] );
		
		return sprintf(
			'',
			esc_attr( $field['type'] ),
			esc_attr( $field['name'] ),
			esc_attr( $field['id'] ),
			esc_attr( $value ),
			esc_attr( $field['class'] ),
			$field['required'] ? 'required' : '',
			! empty( $field['placeholder'] ) ? 'placeholder="' . esc_attr( $field['placeholder'] ) . '"' : ''
		);
	}
	/**
	 * Render select field
	 *
	 * @param array $field Field configuration
	 * @return string
	 */
	private function render_select( $field ) {
		$value = $this->get_field_value( $field['name'], $field['value'] );
		
		$output = sprintf(
			'';
		return $output;
	}
	/**
	 * Render textarea field
	 *
	 * @param array $field Field configuration
	 * @return string
	 */
	private function render_textarea( $field ) {
		$value = $this->get_field_value( $field['name'], $field['value'] );
		
		return sprintf(
			'',
			esc_attr( $field['name'] ),
			esc_attr( $field['id'] ),
			esc_attr( $field['class'] ),
			$field['required'] ? 'required' : '',
			! empty( $field['placeholder'] ) ? 'placeholder="' . esc_attr( $field['placeholder'] ) . '"' : '',
			esc_textarea( $value )
		);
	}
	/**
	 * Render checkbox field
	 *
	 * @param array $field Field configuration
	 * @return string
	 */
	private function render_checkbox( $field ) {
		$value = $this->get_field_value( $field['name'], $field['value'] );
		$is_checked = ! empty( $value );
		
		return sprintf(
			'',
			esc_attr( $field['name'] ),
			esc_attr( $field['id'] ),
			esc_attr( $field['class'] ),
			checked( $is_checked, true, false )
		);
	}
	/**
	 * Render radio field group
	 *
	 * @param array $field Field configuration
	 * @return string
	 */
	private function render_radio( $field ) {
		$value = $this->get_field_value( $field['name'], $field['value'] );
		$output = '';
		foreach ( $field['options'] as $option_value => $option_label ) {
			$output .= sprintf(
				'',
				esc_attr( $field['name'] ),
				esc_attr( $option_value ),
				checked( $value, $option_value, false ),
				esc_html( $option_label )
			);
		}
		$output .= '
';
		return $output;
	}
	/**
	 * Render file field
	 *
	 * @param array $field Field configuration
	 * @return string
	 */
	private function render_file( $field ) {
		// Ensure form has proper enctype
		$this->form_attrs['enctype'] = 'multipart/form-data';
		
		return sprintf(
			'',
			esc_attr( $field['name'] ),
			esc_attr( $field['id'] ),
			esc_attr( $field['class'] ),
			$field['required'] ? 'required' : ''
		);
	}
	/**
	 * Get field value from data or default
	 *
	 * @param string $name Field name
	 * @param mixed  $default Default value
	 * @return mixed
	 */
	private function get_field_value( $name, $default = '' ) {
		return isset( $this->data[ $name ] ) ? $this->data[ $name ] : $default;
	}
	/**
	 * Validate form data
	 *
	 * @param array $data Form data to validate
	 * @return array Validation errors
	 */
	public function validate( $data ) {
		$errors = array();
		foreach ( $this->fields as $field ) {
			$value = isset( $data[ $field['name'] ] ) ? $data[ $field['name'] ] : '';
			// Required field check
			if ( $field['required'] && empty( $value ) ) {
				$errors[ $field['name'] ] = sprintf( '%s is required.', $field['label'] );
				continue;
			}
			// Custom validation rules
			if ( ! empty( $field['validate'] ) && ! empty( $value ) ) {
				foreach ( $field['validate'] as $rule => $params ) {
					$error = $this->apply_validation_rule( $value, $rule, $params, $field );
					if ( $error ) {
						$errors[ $field['name'] ] = $error;
						break;
					}
				}
			}
		}
		return $errors;
	}
	/**
	 * Apply validation rule
	 *
	 * @param mixed  $value  Value to validate
	 * @param string $rule   Validation rule
	 * @param mixed  $params Rule parameters
	 * @param array  $field  Field configuration
	 * @return string|false Error message or false if valid
	 */
	private function apply_validation_rule( $value, $rule, $params, $field ) {
		switch ( $rule ) {
			case 'email':
				if ( ! is_email( $value ) ) {
					return sprintf( '%s must be a valid email address.', $field['label'] );
				}
				break;
			case 'url':
				if ( ! filter_var( $value, FILTER_VALIDATE_URL ) ) {
					return sprintf( '%s must be a valid URL.', $field['label'] );
				}
				break;
			case 'min_length':
				if ( strlen( $value ) < $params ) {
					return sprintf( '%s must be at least %d characters long.', $field['label'], $params );
				}
				break;
			case 'max_length':
				if ( strlen( $value ) > $params ) {
					return sprintf( '%s must not exceed %d characters.', $field['label'], $params );
				}
				break;
			case 'pattern':
				if ( ! preg_match( $params, $value ) ) {
					return sprintf( '%s has an invalid format.', $field['label'] );
				}
				break;
		}
		return false;
	}
	/**
	 * Sanitize form data
	 *
	 * @param array $data Raw form data
	 * @return array Sanitized data
	 */
	public function sanitize( $data ) {
		$sanitized = array();
		foreach ( $this->fields as $field ) {
			if ( ! isset( $data[ $field['name'] ] ) ) {
				continue;
			}
			$value = $data[ $field['name'] ];
			switch ( $field['sanitize'] ) {
				case 'email':
					$sanitized[ $field['name'] ] = sanitize_email( $value );
					break;
				case 'url':
					$sanitized[ $field['name'] ] = esc_url_raw( $value );
					break;
				case 'textarea':
					$sanitized[ $field['name'] ] = sanitize_textarea_field( $value );
					break;
				case 'int':
					$sanitized[ $field['name'] ] = intval( $value );
					break;
				case 'float':
					$sanitized[ $field['name'] ] = floatval( $value );
					break;
				case 'none':
					$sanitized[ $field['name'] ] = $value;
					break;
				default:
					$sanitized[ $field['name'] ] = sanitize_text_field( $value );
			}
		}
		return $sanitized;
	}
}