<?php
// phpcs:disable WordPress.DB.DirectDatabaseQuery,WordPress.NamingConventions.PrefixAllGlobals -- Extension API uses plugin-owned tables and established public hooks.
/**
 * Extension API for Instant Popup Builder
 *
 * Provides a generic, decoupled way for extensions to register triggers,
 * settings, and frontend functionality without core plugin knowing
 * specific extension details.
 *
 * @link       https://instantpopupbuilder.com
 * @since      1.1.4
 * @package    Instant_Popup_Builder
 * @subpackage Instant_Popup_Builder/includes
 */

/**
 * Extension API Class
 *
 * Manages extension registration, settings, and data flow between
 * core plugin and extensions through WordPress hooks/filters.
 *
 * @since      1.1.4
 * @package    Instant_Popup_Builder
 * @subpackage Instant_Popup_Builder/includes
 */
class Instant_Popup_Builder_Extension_API {

	/**
	 * Registered extension triggers
	 *
	 * @var array
	 */
	private static $registered_triggers = [];

	/**
	 * Register an extension trigger
	 *
	 * Allows extensions to register their trigger type with the core plugin.
	 *
	 * @since 1.1.4
	 * @param string $trigger_id   Unique trigger identifier (e.g., 'adblock-trigger')
	 * @param array  $trigger_args {
	 *     Optional. Array of trigger arguments.
	 *
	 *     @type string $label         Display label for the trigger
	 *     @type string $description   Description of the trigger
	 *     @type bool   $has_settings  Whether trigger has custom settings
	 *     @type array  $capabilities  Required capabilities to use trigger
	 * }
	 * @return bool True if registered successfully, false if already registered
	 */
	public static function register_trigger( $trigger_id, $trigger_args = [] ) {
	if ( isset( self::$registered_triggers[ $trigger_id ] ) ) {
		return false;
	}

	// Normalize trigger_id to string for PHP 8.1+ compatibility
	$safe_trigger_id = (string) ( $trigger_id ?? '' );

	$defaults = [
		'label'        => ucfirst( str_replace( '-', ' ', $safe_trigger_id ) ),
		'description'  => '',
		'has_settings' => false,
		'capabilities' => 'manage_options',
	];

		self::$registered_triggers[ $trigger_id ] = wp_parse_args( $trigger_args, $defaults );

		return true;
	}

	/**
	 * Get all registered triggers
	 *
	 * @since 1.1.4
	 * @return array Registered triggers
	 */
	public static function get_registered_triggers() {
		return self::$registered_triggers;
	}

	/**
	 * Check if a trigger is registered
	 *
	 * @since 1.1.4
	 * @param string $trigger_id Trigger ID to check
	 * @return bool True if registered, false otherwise
	 */
	public static function is_trigger_registered( $trigger_id ) {
		return isset( self::$registered_triggers[ $trigger_id ] );
	}

	/**
	 * Process extension trigger settings from POST data
	 *
	 * Allows extensions to hook in and process their own settings
	 * during popup save/update operations.
	 *
	 * @since 1.1.4
	 * @param string $trigger_id Selected trigger ID
	 * @param array  $post_data  POST data array
	 * @return array Processed trigger settings
	 */
	public static function process_trigger_settings( $trigger_id, $post_data ) {
		/**
		 * Filter to process extension trigger settings
		 *
		 * Extensions should hook into this filter to process their settings
		 * and return them in a structured array.
		 *
		 * @since 1.1.4
		 * @param array  $settings   Empty array to be populated by extension
		 * @param string $trigger_id Trigger ID being processed
		 * @param array  $post_data  Raw POST data
		 */
		$settings = apply_filters( 'ipb_process_trigger_settings', [], $trigger_id, $post_data );

		/**
		 * Filter for specific trigger ID
		 *
		 * Allows extensions to hook into their specific trigger.
		 *
		 * @since 1.1.4
		 * @param array $settings  Settings array
		 * @param array $post_data Raw POST data
		 */
		$settings = apply_filters( "ipb_process_trigger_settings_{$trigger_id}", $settings, $post_data );

		return $settings;
	}

	/**
	 * Save extension trigger data
	 *
	 * Allows extensions to save additional data (transients, options, etc.)
	 * when a popup is saved.
	 *
	 * @since 1.1.4
	 * @param int    $popup_id   Popup ID
	 * @param string $trigger_id Selected trigger ID
	 * @param array  $settings   Trigger settings
	 */
	public static function save_trigger_data( $popup_id, $trigger_id, $settings ) {
		/**
		 * Action fired when extension trigger data is saved
		 *
		 * Extensions can hook into this to save transients, options,
		 * or perform other save operations.
		 *
		 * @since 1.1.4
		 * @param int    $popup_id   Popup ID
		 * @param string $trigger_id Trigger ID
		 * @param array  $settings   Trigger settings
		 */
		do_action( 'ipb_save_trigger_data', $popup_id, $trigger_id, $settings );

		/**
		 * Action for specific trigger ID
		 *
		 * @since 1.1.4
		 * @param int   $popup_id Popup ID
		 * @param array $settings Trigger settings
		 */
		do_action( "ipb_save_trigger_data_{$trigger_id}", $popup_id, $settings );
	}

	/**
	 * Get extension trigger data for frontend
	 *
	 * Allows extensions to add data attributes or other data
	 * to popup markup on the frontend.
	 *
	 * @since 1.1.4
	 * @param int    $popup_id   Popup ID
	 * @param string $trigger_id Selected trigger ID
	 * @return array Data to be added to popup (attributes, scripts, etc.)
	 */
	public static function get_trigger_frontend_data( $popup_id, $trigger_id ) {
		$data = [
			'attributes' => [],
			'inline_script' => '',
		];

		/**
		 * Filter to get extension trigger frontend data
		 *
		 * Extensions should return an array with:
		 * - 'attributes': array of data attributes
		 * - 'inline_script': inline JavaScript code
		 *
		 * @since 1.1.4
		 * @param array  $data       Empty data array
		 * @param int    $popup_id   Popup ID
		 * @param string $trigger_id Trigger ID
		 */
		$data = apply_filters( 'ipb_trigger_frontend_data', $data, $popup_id, $trigger_id );

		/**
		 * Filter for specific trigger ID
		 *
		 * @since 1.1.4
		 * @param array $data     Data array
		 * @param int   $popup_id Popup ID
		 */
		$data = apply_filters( "ipb_trigger_frontend_data_{$trigger_id}", $data, $popup_id );

		return $data;
	}

	/**
	 * Load extension trigger data from database
	 *
	 * Retrieves saved trigger settings for use in admin edit forms.
	 *
	 * @since 1.1.4
	 * @param int    $popup_id   Popup ID
	 * @param string $trigger_id Trigger ID
	 * @return array Trigger settings
	 */
	public static function load_trigger_data( $popup_id, $trigger_id ) {
		global $wpdb;

		$row = $wpdb->get_results(
			$wpdb->prepare( "SELECT ipb_trigger FROM {$wpdb->prefix}instant_popup_builder WHERE id=%d", $popup_id )
		);

		if ( empty( $row ) || ! isset( $row[0]->ipb_trigger ) ) {
			return [];
		}

	$trigger_data = json_decode( $row[0]->ipb_trigger, true );

	// Normalize trigger_id to string for PHP 8.1+ compatibility
	$safe_trigger_id = (string) ( $trigger_id ?? '' );

	// Get settings key based on trigger ID (e.g., 'adblock_trigger_settings')
	$settings_key = str_replace( '-', '_', $safe_trigger_id ) . '_settings';

		if ( isset( $trigger_data[ $settings_key ] ) ) {
			return (array) $trigger_data[ $settings_key ];
		}

		return [];
	}

	/**
	 * Render extension-specific admin settings HTML
	 *
	 * Allows extensions to output their admin settings UI.
	 *
	 * @since 1.1.4
	 * @param string $trigger_id Trigger ID
	 * @param array  $settings   Current settings (for edit mode)
	 * @param string $context    Context: 'create' or 'edit'
	 */
	public static function render_trigger_settings( $trigger_id, $settings = [], $context = 'create' ) {
		/**
		 * Action to render extension trigger settings
		 *
		 * Extensions should hook into this to output their settings HTML.
		 *
		 * @since 1.1.4
		 * @param string $trigger_id Trigger ID
		 * @param array  $settings   Current settings
		 * @param string $context    'create' or 'edit'
		 */
		do_action( 'ipb_render_trigger_settings', $trigger_id, $settings, $context );

		/**
		 * Action for specific trigger ID
		 *
		 * @since 1.1.4
		 * @param array  $settings Current settings
		 * @param string $context  'create' or 'edit'
		 */
		do_action( "ipb_render_trigger_settings_{$trigger_id}", $settings, $context );
	}

	/**
	 * Check if extension trigger is active
	 *
	 * Verifies if an extension trigger is both registered and licensed/enabled.
	 *
	 * @since 1.1.4
	 * @param string $trigger_id Trigger ID to check
	 * @return bool True if active, false otherwise
	 */
	public static function is_trigger_active( $trigger_id ) {
		if ( ! self::is_trigger_registered( $trigger_id ) ) {
			return false;
		}

		/**
		 * Filter to check if extension trigger is active
		 *
		 * Extensions should return true if their license is active
		 * or if no license is required.
		 *
		 * @since 1.1.4
		 * @param bool   $is_active  Default false
		 * @param string $trigger_id Trigger ID
		 */
		$is_active = apply_filters( 'ipb_is_trigger_active', false, $trigger_id );
		$is_active = apply_filters( "ipb_is_trigger_active_{$trigger_id}", $is_active );

		return $is_active;
	}

	/**
	 * Delete extension trigger data
	 *
	 * Cleanup trigger-specific data when popup is deleted.
	 *
	 * @since 1.1.4
	 * @param int    $popup_id   Popup ID
	 * @param string $trigger_id Trigger ID
	 */
	public static function delete_trigger_data( $popup_id, $trigger_id ) {
		/**
		 * Action fired when extension trigger data should be deleted
		 *
		 * @since 1.1.4
		 * @param int    $popup_id   Popup ID
		 * @param string $trigger_id Trigger ID
		 */
		do_action( 'ipb_delete_trigger_data', $popup_id, $trigger_id );
		do_action( "ipb_delete_trigger_data_{$trigger_id}", $popup_id );
	}
}

