<?php
/**
 * The cart recovery email registry.
 *
 * @since 3.6.5
 * @package EDD\Pro\CartRecovery\Emails
 */

namespace EDD\Pro\CartRecovery\Emails;

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

use EDD\EventManagement\SubscriberInterface;

/**
 * The cart recovery email registry.
 *
 * @since 3.6.5
 * @package EDD\Pro\CartRecovery\Emails
 */
class Registry implements SubscriberInterface {

	/**
	 * Gets the subscribed events.
	 *
	 * @since 3.6.5
	 * @return array
	 */
	public static function get_subscribed_events(): array {
		return array(
			'edd_email_registered_templates' => 'register_templates',
			'edd_email_registered_types'     => 'register_types',
			'edd_email_contexts'             => 'register_context',
			'edd_email_list_table_emails'    => 'exclude_acr_emails',
		);
	}

	/**
	 * Adds ACR templates to the registered templates array.
	 *
	 * @since 3.6.5
	 * @param array $templates Existing registered templates.
	 * @return array Modified templates array with ACR templates added.
	 */
	public function register_templates( array $templates ): array {
		return array_merge( $templates, self::get_templates() );
	}

	/**
	 * Returns the recovery email templates.
	 *
	 * @return array
	 */
	public static function get_templates(): array {
		// Only add templates if ACR is enabled.
		if ( ! edd_get_option( 'acr_enabled', false ) ) {
			return array();
		}

		$acr_templates = self::get_recovery_email_templates();
		$custom_emails = self::get_custom_emails();

		// Add dynamic custom emails from the database.
		if ( ! empty( $custom_emails ) ) {
			foreach ( $custom_emails as $custom_email ) {
				$acr_templates[ $custom_email->email_id ] = Templates\Custom::class;
			}
		}
		$acr_templates['acr-custom-new'] = Templates\Custom::class;

		return $acr_templates;
	}

	/**
	 * Registers email type classes with the EDD email registry.
	 *
	 * @since 3.6.5
	 * @param array $types Existing registered types.
	 * @return array Modified types array with ACR types added.
	 */
	public function register_types( $types ): array {
		$types['edd-pro-acr-ir'] = Types\ImmediateRecovery::class;
		$types['edd-pro-acr-vr'] = Types\ValueReinforcement::class;
		$types['edd-pro-acr-fa'] = Types\FinalAttempt::class;

		// Register dynamic custom email types.
		$custom_emails = self::get_custom_emails();
		if ( ! empty( $custom_emails ) ) {
			foreach ( $custom_emails as $custom_email ) {
				$email_id           = $custom_email->email_id;
				$types[ $email_id ] = Types\Custom::class;
			}
		}

		return $types;
	}

	/**
	 * Adds the ACR "abandoned_cart" context label to the Emails UI.
	 *
	 * @param array $contexts Existing context labels.
	 * @return array Modified contexts with ACR entry.
	 */
	public function register_context( array $contexts ): array {
		if ( ! edd_get_option( 'acr_enabled', false ) ) {
			return $contexts;
		}

		$page = filter_input( INPUT_GET, 'page', FILTER_SANITIZE_SPECIAL_CHARS );
		if ( 'edd-emails' === $page ) {
			return $contexts;
		}

		$contexts['abandoned_cart'] = __( 'Abandoned Cart', 'easy-digital-downloads' );

		return $contexts;
	}

	/**
	 * Excludes ACR emails from the base emails list table.
	 *
	 * @since 3.6.5
	 * @param array $emails Array of email IDs and class names.
	 * @return array Filtered array of emails.
	 */
	public function exclude_acr_emails( $emails ) {
		if ( 'edd-cart-recovery' === filter_input( INPUT_GET, 'page', FILTER_SANITIZE_SPECIAL_CHARS ) ) {
			return $emails;
		}

		$acr_templates = array_keys( self::get_recovery_email_templates() );

		foreach ( $acr_templates as $template ) {
			if ( isset( $emails[ $template ] ) ) {
				unset( $emails[ $template ] );
			}
		}

		return $emails;
	}

	/**
	 * Returns the recovery email templates.
	 *
	 * @return array
	 */
	private static function get_recovery_email_templates(): array {
		$templates = array(
			'edd-pro-acr-ir' => Templates\ImmediateRecovery::class,
			'edd-pro-acr-vr' => Templates\ValueReinforcement::class,
			'edd-pro-acr-fa' => Templates\FinalAttempt::class,
		);

		$custom_emails = self::get_custom_emails();
		if ( ! empty( $custom_emails ) ) {
			foreach ( $custom_emails as $custom_email ) {
				$templates[ $custom_email->email_id ] = Templates\Custom::class;
			}
		}

		return $templates;
	}

	/**
	 * Returns the custom emails.
	 *
	 * @since 3.6.5
	 * @return array
	 */
	private static function get_custom_emails(): array {
		return edd_get_emails(
			array(
				'sender'     => 'edd',
				'context'    => 'abandoned_cart',
				'meta_query' => array(
					array(
						'key'     => 'type',
						'value'   => 'custom',
						'compare' => '=',
					),
				),
				'orderby'    => 'date_created',
				'order'      => 'DESC',
			)
		);
	}
}
