<?php
/**
 * AbstractRule — base class for conditional rules applied to workflows.
 *
 * @package CartCue\Rules
 */

namespace CartCue\Rules;

defined( 'ABSPATH' ) || exit;

abstract class AbstractRule {

	/** Unique slug. */
	abstract public function get_slug(): string;

	/** Human-readable label for the workflow editor. */
	abstract public function get_label(): string;

	/**
	 * Evaluate whether this rule passes for the given context.
	 *
	 * @param array $config  Rule config from the workflow (includes 'operator', 'value', etc.).
	 * @param array $data    Trigger context data.
	 * @return bool  True = rule passes, workflow may continue. False = skip workflow.
	 */
	abstract public function evaluate( array $config, array $data ): bool;

	/**
	 * Return available operators for the rule editor.
	 *
	 * @return array  key => label.
	 */
	public function get_operators(): array {
		return [
			'greater_than' => __( 'is greater than', 'cartcue-sales-automation' ),
			'less_than'    => __( 'is less than', 'cartcue-sales-automation' ),
			'equals'       => __( 'equals', 'cartcue-sales-automation' ),
		];
	}

	/**
	 * Value field type used in the rule editor ('text', 'number', 'select').
	 */
	public function get_value_type(): string {
		return 'text';
	}

	/**
	 * Options for select-type value fields.
	 *
	 * @return array  key => label.
	 */
	public function get_value_options(): array {
		return [];
	}

	/**
	 * Source key for async value pickers in the editor.
	 */
	public function get_value_source(): string {
		return '';
	}

	/**
	 * Whether async picker accepts multiple comma-separated values.
	 */
	public function is_value_multiple(): bool {
		return false;
	}

	/**
	 * Optional placeholder for the value control in the editor.
	 */
	public function get_value_placeholder(): string {
		return '';
	}

	/** True when rule is Pro-only (ghost on free plan). */
	public function is_pro_only(): bool {
		return false;
	}

	// -------------------------------------------------------------------------
	// Comparison helpers
	// -------------------------------------------------------------------------

	protected function compare( $actual, string $operator, $expected ): bool {
		switch ( $operator ) {
			case 'greater_than':
				return (float) $actual > (float) $expected;
			case 'less_than':
				return (float) $actual < (float) $expected;
			case 'equals':
			case 'is':
				return (string) $actual === (string) $expected;
			case 'is_not':
				return (string) $actual !== (string) $expected;
			case 'contains':
				return false !== stripos( (string) $actual, (string) $expected );
			default:
				return false;
		}
	}
}
