<?php
/**
 * Condition: Order payment method comparison.
 *
 * Evaluates whether the order's payment gateway matches any of the given values.
 * Supports contains (=) and does-not-contain (!=) operators with multi-select.
 *
 * Maps to the core {payment_method} email tag key for consistency,
 * but compares against the gateway slug (e.g., 'stripe', 'paypal')
 * rather than the human-readable label.
 *
 * @package     EDD\Pro\Emails\ConditionalTags\Conditions
 * @copyright   Copyright (c) 2026, Sandhills Development, LLC
 * @license     https://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       3.6.6
 */

namespace EDD\Pro\Emails\ConditionalTags\Conditions;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore

/**
 * Class PaymentMethod
 *
 * @since 3.6.6
 */
class PaymentMethod extends AbstractCondition {

	/**
	 * Supported operators.
	 *
	 * @since 3.6.6
	 * @var string[]
	 */
	protected $supported_operators = array( '=', '!=' );

	/**
	 * Supported contexts.
	 *
	 * @since 3.6.6
	 * @var string[]
	 */
	protected $supported_contexts = array( 'order' );

	/**
	 * Get the key for this condition.
	 *
	 * @since 3.6.6
	 *
	 * @return string Condition key.
	 */
	public function get_key() {
		return 'payment_method';
	}

	/**
	 * Get the label for this condition.
	 *
	 * @since 3.6.6
	 *
	 * @return string Condition label.
	 */
	public function get_label() {
		return __( 'Payment Method', 'easy-digital-downloads' );
	}

	/**
	 * Get custom operator labels for the UI.
	 *
	 * @since 3.6.6
	 *
	 * @return array<string, string> Operator labels keyed by operator symbol.
	 */
	public function get_operator_labels() {
		return array(
			'='  => __( 'is', 'easy-digital-downloads' ),
			'!=' => __( 'is not', 'easy-digital-downloads' ),
		);
	}

	/**
	 * Get the UI input type descriptor for the value field.
	 *
	 * Returns a multi-select with Chosen styling so users can pick
	 * one or more payment gateways from a pill-tag dropdown.
	 *
	 * @since 3.6.6
	 *
	 * @return array UI input type descriptor.
	 */
	public function get_ui_input_type() {
		$gateways = edd_get_payment_gateways();
		if ( empty( $gateways ) ) {
			return array( 'type' => 'text' );
		}

		$options = array();
		foreach ( $gateways as $slug => $gateway ) {
			$options[] = array(
				'value' => $slug,
				'label' => $gateway['admin_label'],
			);
		}

		return array(
			'type'     => 'select',
			'options'  => $options,
			'multiple' => true,
			'chosen'   => true,
		);
	}

	/**
	 * Evaluate if the order's payment gateway is among the selected values.
	 *
	 * Accepts a comma-separated list of gateway slugs. With the "=" operator
	 * the condition is true when the order's gateway matches any of the
	 * selected values. With "!=" it is true when the gateway matches none.
	 *
	 * @since 3.6.6
	 *
	 * @param int    $object_id  The EDD object ID.
	 * @param object $edd_object The EDD object.
	 * @param object $email      The EDD email object.
	 * @param mixed  $value      Comma-separated gateway slugs (e.g., 'stripe,paypal').
	 * @param string $operator   The comparison operator (= or !=).
	 * @param mixed  $context    Additional contextual data for evaluation.
	 * @return bool
	 */
	public function evaluate( $object_id, $edd_object, $email, $value, $operator = '=', $context = '' ) {
		$value = trim( (string) $value );
		if ( empty( $value ) ) {
			return false;
		}

		if ( ! $this->is_context_allowed( $context ) ) {
			return false;
		}

		if ( ! in_array( $operator, $this->supported_operators, true ) ) {
			return false;
		}

		$actual = $this->get_gateway( $edd_object );
		if ( empty( $actual ) ) {
			return '!=' === $operator;
		}

		$expected  = array_filter( array_map( 'trim', explode( ',', strtolower( $value ) ) ) );
		$has_match = in_array( strtolower( $actual ), $expected, true );

		return '!=' === $operator ? ! $has_match : $has_match;
	}

	/**
	 * Retrieve the gateway from the Order object.
	 *
	 * @since 3.6.6
	 *
	 * @param object $edd_object The EDD object.
	 * @return string The gateway slug, or empty string if not available.
	 */
	private function get_gateway( $edd_object ) {
		if ( ! $edd_object instanceof \EDD\Orders\Order ) {
			return '';
		}

		return (string) $edd_object->gateway;
	}
}
