<?php

/**
 * Class EnrollmentCategories
 *
 * This class is responsible for handling the enrollment categories rule for LearnPress
 *
 * @since 1.0.0
 *
 * @package DoubleScale\Pro
 */

namespace DoubleScale\Modules\Automations\Rules\Learnpress;

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- transactional CRM/scheduler/campaign DB ops; persistent caching is impractical for write-heavy or per-request lookups (matches WooCommerce/FluentCRM precedent).


defined( 'ABSPATH' ) || exit;

use DoubleScale\Modules\Automations\Abstracts\Rule;
use DoubleScale\Modules\Automations\Models\AutomationContactModel;
use DoubleScale\Modules\Automations\Services\RulesManager;

/**
 * Enrollment Categories class
 */
class EnrollmentCategories extends Rule {

	/**
	 * Name
	 *
	 * @var string
	 *
	 * @since 1.0.0
	 */
	public $name = 'Enrollment Categories';

	/**
	 * Slug
	 *
	 * @var string
	 *
	 * @since 1.0.0
	 */
	public $slug = 'learnpress_enrollment_categories';

	/**
	 * Group
	 *
	 * @var string
	 *
	 * @since 1.0.0
	 */
	public $group = 'learnpress';

	/**
	 * Type
	 *
	 * @var string
	 *
	 * @since 1.0.0
	 */
	public $type = 'multiselect';

	/**
	 * Has options
	 *
	 * @since 1.0.0
	 *
	 * @return bool
	 */
	public function has_options() {
		return true;
	}

	/**
	 * Get operators
	 *
	 * @since 1.0.0
	 *
	 * @return array
	 */
	public function get_operators() {
		return array(
			'matches_any_of'  => __( 'Matches any of', 'doublescale' ),
			'matches_none_of' => __( 'Matches none of', 'doublescale' ),
			'matches_all_of'  => __( 'Matches all of', 'doublescale' ),
		);
	}

	/**
	 * Get options
	 *
	 * @since 1.0.0
	 *
	 * @return array
	 */
	public function get_options() {
		$categories = get_terms(
			array(
				'taxonomy'   => 'course_category',
				'hide_empty' => false,
			)
		);

		$options = array();
		if ( ! is_wp_error( $categories ) && ! empty( $categories ) ) {
			foreach ( $categories as $category ) {
				if ( isset( $category->term_id ) && isset( $category->name ) ) {
					$options[ $category->term_id ] = wp_kses_post( $category->name );
				}
			}
		}
		return $options;
	}

	/**
	 * Get value
	 *
	 * @since 1.0.0
	 *
	 * @param AutomationContactModel $automation_contact Contact Model.
	 *
	 * @return array Array of category IDs from enrolled courses
	 */
	public function get_value( $automation_contact ) {
		$contact = $automation_contact->contact;

		if ( ! $contact || empty( $contact->email ) ) {
			return array();
		}

		$user = get_user_by( 'email', $contact->email );
		if ( ! $user ) {
			return array();
		}

		$enrolled_course_categories = array();

		global $wpdb;
		$table_name = esc_sql( $wpdb->prefix . 'learnpress_user_items' );

		// Check if table exists.
		$table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) );
		if ( ! $table_exists ) {
			return array();
		}

		// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $table_name is the LearnPress-prefixed user_items table; user id bound via prepare().
		$results = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT item_id FROM {$table_name} WHERE user_id = %d AND item_type = 'lp_course' AND status = 'enrolled'",
				$user->ID
			)
		);
		// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared

		if ( ! empty( $results ) ) {
			foreach ( $results as $row ) {
				$course_categories = get_the_terms( $row->item_id, 'course_category' );

				if ( ! is_wp_error( $course_categories ) && ! empty( $course_categories ) ) {
					foreach ( $course_categories as $category ) {
						if ( isset( $category->term_id ) ) {
							$enrolled_course_categories[] = (int) $category->term_id;
						}
					}
				}
			}
		}

		return array_unique( array_map( 'intval', $enrolled_course_categories ) );
	}

	/**
	 * Is met
	 *
	 * @since 1.0.0
	 *
	 * @param AutomationContactModel $automation_contact Contact Model.
	 * @param array                  $rule Rule.
	 *
	 * @return bool
	 */
	public function is_met( AutomationContactModel $automation_contact, $rule = array() ) {
		$enrolled_categories = $this->get_value( $automation_contact );
		$operator            = $rule['operator'] ?? '';
		$rule_categories     = $rule['value'] ?? array();

		if ( ! is_array( $rule_categories ) ) {
			$rule_categories = array( $rule_categories );
		}

		if ( ! is_array( $enrolled_categories ) ) {
			$enrolled_categories = array();
		}

		$enrolled_categories = array_map( 'intval', $enrolled_categories );
		$rule_categories     = array_map( 'intval', $rule_categories );

		switch ( $operator ) {
			case 'matches_any_of':
				return ! empty( array_intersect( $enrolled_categories, $rule_categories ) );

			case 'matches_none_of':
				return empty( array_intersect( $enrolled_categories, $rule_categories ) );

			case 'matches_all_of':
				return empty( array_diff( $rule_categories, $enrolled_categories ) );

			default:
				return false;
		}
	}
}

add_action(
	'init',
	function () {
		if ( \doublescale_is_plugin_active( 'learnpress/learnpress.php' ) ) {
			RulesManager::instance()->register( new EnrollmentCategories() );
		}
	},
	99
);
