<?php
// DESCRIPTION: Evaluates conditional logic rules against resolved field values.
// Returns true (sync) or false (skip) based on rule match results.

namespace SheetWise\Conditions;

class RuleEvaluator {

    /**
     * Valid operators for rule evaluation
     *
     * @since SWISE_SINCE
     *
     * @var array
     */
    const VALID_OPERATORS = [
        'equals',
        'not_equals',
        'contains',
        'not_contains',
        'greater_than',
        'less_than',
        'is_empty',
        'is_not_empty',
    ];

    /**
     * Evaluate conditions against resolved field values
     *
     * @since SWISE_SINCE
     *
     * @param array $conditions   The conditions config from integration JSON
     * @param array $field_values Associative array: field_key => resolved_value
     *
     * @return bool true = sync, false = skip
     */
    public function evaluate( array $conditions, array $field_values ) {
        if ( empty( $conditions['rules'] ) ) {
            return true;
        }

        $match   = isset( $conditions['match'] ) ? $conditions['match'] : 'all';
        $results = [];

        foreach ( $conditions['rules'] as $index => $rule ) {
            $result    = $this->evaluate_rule( $rule, $field_values );
            $results[] = $result;
        }

        if ( $match === 'all' ) {
            $final = ! in_array( false, $results, true );

            return $final;
        }

        // 'any' — at least one rule must pass
        $final = in_array( true, $results, true );
        
        return $final;
    }

    /**
     * Evaluate a single rule against field values
     *
     * @since SWISE_SINCE
     *
     * @param array $rule         Rule with field, operator, value keys
     * @param array $field_values Associative array: field_key => resolved_value
     *
     * @return bool
     */
    private function evaluate_rule( array $rule, array $field_values ) {
        $field    = isset( $rule['field'] ) ? $rule['field'] : '';
        $operator = isset( $rule['operator'] ) ? $rule['operator'] : '';
        $value    = isset( $rule['value'] ) ? $rule['value'] : '';

        if ( empty( $field ) || empty( $operator ) ) {
            return true;
        }

        if ( ! in_array( $operator, self::VALID_OPERATORS, true ) ) {
            return true;
        }

        $actual = isset( $field_values[ $field ] ) ? $field_values[ $field ] : '';

        switch ( $operator ) {
            case 'equals':
                return $actual == $value;

            case 'not_equals':
                return $actual != $value;

            case 'contains':
                return stripos( (string) $actual, (string) $value ) !== false;

            case 'not_contains':
                return stripos( (string) $actual, (string) $value ) === false;

            case 'greater_than':
                return (float) $actual > (float) $value;

            case 'less_than':
                return (float) $actual < (float) $value;

            case 'is_empty':
                return $actual === '' || $actual === null;

            case 'is_not_empty':
                return $actual !== '' && $actual !== null;

            default:
                return true;
        }
    }
}
