<?php
/**
 * Email tag helper utilities.
 *
 * @package     EDD\Pro\Emails\ConditionalTags\Utilities
 * @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\Utilities;

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

/**
 * Class Tags
 *
 * @since 3.6.6
 */
class Tags {

	/**
	 * Get an EDD email tag definition by key and context.
	 *
	 * @since 3.6.6
	 *
	 * @param string $key     The tag key (e.g., 'username').
	 * @param mixed  $context The email context.
	 * @return array|null     The tag definition array or null if not found.
	 */
	public static function get_tag_by_name( $key, $context = '' ) {
		$context = self::normalize_context( $context );
		$tags    = (array) edd_get_email_tags( $context );
		foreach ( $tags as $tag ) {
			if ( isset( $tag['tag'] ) && $tag['tag'] === $key ) {
				return $tag;
			}
		}

		return null;
	}

	/**
	 * Safely invoke an email tag callback.
	 *
	 * @since 3.6.6
	 *
	 * @param array  $tag         Tag definition array.
	 * @param int    $object_id   Object ID.
	 * @param object $edd_object  Object instance.
	 * @param mixed  $context_arg Context or email parameter to pass.
	 * @return mixed|null
	 */
	public static function do_tag( $tag, $object_id, $edd_object, $context_arg ) {
		if ( empty( $tag ) || empty( $tag['func'] ) ) {
			return null;
		}

		if ( ! is_callable( $tag['func'] ) ) {
			return null;
		}

		// The callback is registered by code via edd_add_email_tag; not user input.
		// nosemgrep: php.lang.security.audit.dangerous-function-call.dangerous-function-call.
		return call_user_func( $tag['func'], $object_id, $edd_object, $context_arg );
	}

	/**
	 * Normalize the email context value.
	 *
	 * @since 3.6.6
	 *
	 * @param mixed $context Email context.
	 * @return string
	 */
	public static function normalize_context( $context ) {
		if ( $context instanceof \EDD\Emails\Types\Email ) {
			return (string) $context->get_context();
		}

		if ( is_array( $context ) ) {
			if ( isset( $context['context'] ) ) {
				return (string) $context['context'];
			}
			if ( isset( $context[0] ) ) {
				return (string) $context[0];
			}
		}

		return (string) $context;
	}
}
