<?php
/**
 * Dynamic Tags Module for Captain Widgets Kit.
 *
 * Registers all Elementor Dynamic Tag groups and individual tag classes.
 * Loaded conditionally based on the 'Captwiki_Dynamic_Tags' extension setting.
 *
 * Groups  : Post, Site, User, Archive, DC (Dynamic Categories), WooCommerce, ACF
 * Text    : 28 tags
 * Image   : 8 tags
 * URL     : 8 tags
 * Gallery : 1 tag (ACF Gallery)
 *
 * Sub-groups (categories) can be toggled independently via:
 * captwiki_settings['dynamic_tags_groups']
 *
 * @since      1.2.0
 * @package    captain-widgets-kit
 * @subpackage captain-widgets-kit/includes/elementor/dynamic-tags
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

if ( ! class_exists( 'Captwiki_Dynamic_Tags' ) ) {

	/**
	 * Class Captwiki_Dynamic_Tags
	 *
	 * Boots the full dynamic tag system for Captain Widgets Kit.
	 *
	 * @since 1.2.0
	 */
	class Captwiki_Dynamic_Tags {

		/**
		 * Singleton instance.
		 *
		 * @var Captwiki_Dynamic_Tags|null
		 */
		private static $instance = null;

		/**
		 * Enabled sub-groups from settings.
		 *
		 * @var array
		 */
		private $enabled_groups = array();

		/**
		 * Text tags: slug => class.
		 *
		 * @since 1.2.0
		 * @var   array<string,string>
		 */
		private $text_tags = array(
			// Post.
			'post-id'                => array(
				'class' => 'Captwiki_Tag_Post_ID',
				'group' => 'post',
			),
			'post-title'             => array(
				'class' => 'Captwiki_Tag_Post_Title',
				'group' => 'post',
			),
			'post-excerpt'           => array(
				'class' => 'Captwiki_Tag_Post_Excerpt',
				'group' => 'post',
			),
			'post-content'           => array(
				'class' => 'Captwiki_Tag_Post_Content',
				'group' => 'post',
			),
			'post-category'          => array(
				'class' => 'Captwiki_Tag_Post_Category',
				'group' => 'post',
			),
			'post-tag'               => array(
				'class' => 'Captwiki_Tag_Post_Tags',
				'group' => 'post',
			),
			'post-author'            => array(
				'class' => 'Captwiki_Tag_Post_Author',
				'group' => 'author',
			),
			'post-slug'              => array(
				'class' => 'Captwiki_Tag_Post_Slug',
				'group' => 'post',
			),
			'post-date'              => array(
				'class' => 'Captwiki_Tag_Post_Date',
				'group' => 'post',
			),
			'post-time'              => array(
				'class' => 'Captwiki_Tag_Post_Time',
				'group' => 'post',
			),
			'post-terms'             => array(
				'class' => 'Captwiki_Tag_Post_Terms',
				'group' => 'post',
			),
			'post-status'            => array(
				'class' => 'Captwiki_Tag_Post_Status',
				'group' => 'post',
			),
			'post-type'              => array(
				'class' => 'Captwiki_Tag_Post_Type',
				'group' => 'post',
			),
			'post-cat-desc'          => array(
				'class' => 'Captwiki_Tag_Post_Category_Description',
				'group' => 'post',
			),
			'post-tag-desc'          => array(
				'class' => 'Captwiki_Tag_Post_Tag_Description',
				'group' => 'post',
			),
			'post-cat-post-count'    => array(
				'class' => 'Captwiki_Tag_Post_Category_Post_Count',
				'group' => 'post',
			),
			'post-tag-post-count'    => array(
				'class' => 'Captwiki_Tag_Post_Tag_Post_Count',
				'group' => 'post',
			),
			'post-featured-image'    => array(
				'class' => 'Captwiki_Tag_Post_Featured_Image_Data',
				'group' => 'post',
			),
			// Site.
			'site-title'             => array(
				'class' => 'Captwiki_Tag_Site_Title',
				'group' => 'site',
			),
			'site-tagline'           => array(
				'class' => 'Captwiki_Tag_Site_Tagline',
				'group' => 'site',
			),
			'site-current-date-time' => array(
				'class' => 'Captwiki_Tag_Site_Current_Date_Time',
				'group' => 'site',
			),
			// User.
			'user-info'              => array(
				'class' => 'Captwiki_Tag_User_Info',
				'group' => 'user',
			),
			'user-meta'              => array(
				'class' => 'Captwiki_Tag_User_Meta',
				'group' => 'user',
			),
			// Archive.
			'archive-title'          => array(
				'class' => 'Captwiki_Tag_Archive_Title',
				'group' => 'archive',
			),
			'archive-description'    => array(
				'class' => 'Captwiki_Tag_Archive_Description',
				'group' => 'archive',
			),
			'archive-meta'           => array(
				'class' => 'Captwiki_Tag_Archive_Meta',
				'group' => 'archive',
			),
			// DC.
			'dc-term-title'          => array(
				'class' => 'Captwiki_Tag_DC_Term_Title',
				'group' => 'dc',
			),
			'dc-term-description'    => array(
				'class' => 'Captwiki_Tag_DC_Term_Description',
				'group' => 'dc',
			),
			'dc-term-count'          => array(
				'class' => 'Captwiki_Tag_DC_Term_Count',
				'group' => 'dc',
			),
		);

		/**
		 * Image tags: slug => class.
		 *
		 * @since 1.2.0
		 * @var   array<string,string>
		 */
		private $image_tags = array(
			'post-featured-image' => array(
				'class' => 'Captwiki_Tag_Post_Featured_Image',
				'group' => 'post',
			),
			'post-author-avatar'  => array(
				'class' => 'Captwiki_Tag_Post_Author_Avatar',
				'group' => 'author',
			),
			'post-cat-image'      => array(
				'class' => 'Captwiki_Tag_Post_Category_Image',
				'group' => 'post',
			),
			'site-logo'           => array(
				'class' => 'Captwiki_Tag_Site_Logo',
				'group' => 'site',
			),
			'site-icon'           => array(
				'class' => 'Captwiki_Tag_Site_Icon',
				'group' => 'site',
			),
			'user-avatar'         => array(
				'class' => 'Captwiki_Tag_User_Avatar_Image',
				'group' => 'user',
			),
			'archive-image'       => array(
				'class' => 'Captwiki_Tag_Archive_Image',
				'group' => 'archive',
			),
			'dc-term-image'       => array(
				'class' => 'Captwiki_Tag_DC_Term_Image',
				'group' => 'dc',
			),
		);

		/**
		 * URL tags: slug => class.
		 *
		 * @since 1.2.0
		 * @var   array<string,string>
		 */
		private $url_tags = array(
			'post-url'              => array(
				'class' => 'Captwiki_Tag_Post_URL',
				'group' => 'post',
			),
			'post-term-url'         => array(
				'class' => 'Captwiki_Tag_Post_Term_URL',
				'group' => 'post',
			),
			'post-author-url'       => array(
				'class' => 'Captwiki_Tag_Post_Author_URL',
				'group' => 'author',
			),
			'site-url'              => array(
				'class' => 'Captwiki_Tag_Site_URL',
				'group' => 'site',
			),
			'user-url'              => array(
				'class' => 'Captwiki_Tag_User_URL',
				'group' => 'user',
			),
			'user-login-logout-url' => array(
				'class' => 'Captwiki_Tag_User_Login_Logout_URL',
				'group' => 'user',
			),
			'archive-url'           => array(
				'class' => 'Captwiki_Tag_Archive_URL',
				'group' => 'archive',
			),
			'dc-term-url'           => array(
				'class' => 'Captwiki_Tag_DC_Term_URL',
				'group' => 'dc',
			),
		);

		/**
		 * WooCommerce text tags.
		 *
		 * @since 1.2.0
		 * @var   array<string,string>
		 */
		private $woo_text_tags = array(
			'product-id'                => array(
				'class' => 'Captwiki_Tag_Product_ID',
				'group' => 'woocommerce',
			),
			'product-title'             => array(
				'class' => 'Captwiki_Tag_Product_Title',
				'group' => 'woocommerce',
			),
			'product-price'             => array(
				'class' => 'Captwiki_Tag_Product_Price',
				'group' => 'woocommerce',
			),
			'product-category'          => array(
				'class' => 'Captwiki_Tag_Product_Category',
				'group' => 'woocommerce',
			),
			'product-description'       => array(
				'class' => 'Captwiki_Tag_Product_Description',
				'group' => 'woocommerce',
			),
			'product-short-description' => array(
				'class' => 'Captwiki_Tag_Product_Short_Description',
				'group' => 'woocommerce',
			),
			'product-sku'               => array(
				'class' => 'Captwiki_Tag_Product_SKU',
				'group' => 'woocommerce',
			),
			'product-slug'              => array(
				'class' => 'Captwiki_Tag_Product_Slug',
				'group' => 'woocommerce',
			),
			'product-tags'              => array(
				'class' => 'Captwiki_Tag_Product_Tags',
				'group' => 'woocommerce',
			),
			'product-type'              => array(
				'class' => 'Captwiki_Tag_Product_Type',
				'group' => 'woocommerce',
			),
			'product-sale'              => array(
				'class' => 'Captwiki_Tag_Product_Sale',
				'group' => 'woocommerce',
			),
			'product-rating'            => array(
				'class' => 'Captwiki_Tag_Product_Rating',
				'group' => 'woocommerce',
			),
			'product-shipping'          => array(
				'class' => 'Captwiki_Tag_Product_Shipping',
				'group' => 'woocommerce',
			),
			'product-attribute'         => array(
				'class' => 'Captwiki_Tag_Product_Attribute',
				'group' => 'woocommerce',
			),
			'product-purchase-note'     => array(
				'class' => 'Captwiki_Tag_Product_Purchase_Note',
				'group' => 'woocommerce',
			),
			'product-stock-status'      => array(
				'class' => 'Captwiki_Tag_Product_Stock_Status',
				'group' => 'woocommerce',
			),
			'product-stock-qty'         => array(
				'class' => 'Captwiki_Tag_Product_Stock_Quantity',
				'group' => 'woocommerce',
			),
		);

		/**
		 * WooCommerce image tags.
		 *
		 * @since 1.2.0
		 * @var   array<string,string>
		 */
		private $woo_image_tags = array(
			'product-featured-image' => array(
				'class' => 'Captwiki_Tag_Product_Featured_Image',
				'group' => 'woocommerce',
			),
			'product-gallery-image'  => array(
				'class' => 'Captwiki_Tag_Product_Gallery',
				'group' => 'woocommerce',
			),
		);

		/**
		 * WooCommerce URL tags.
		 *
		 * @since 1.2.0
		 * @var   array<string,string>
		 */
		private $woo_url_tags = array(
			'product-url'             => array(
				'class' => 'Captwiki_Tag_Product_URL',
				'group' => 'woocommerce',
			),
			'product-cat-url'         => array(
				'class' => 'Captwiki_Tag_Product_Category_URL',
				'group' => 'woocommerce',
			),
			'product-tag-url'         => array(
				'class' => 'Captwiki_Tag_Product_Tag_URL',
				'group' => 'woocommerce',
			),
			'product-add-to-cart-url' => array(
				'class' => 'Captwiki_Tag_Product_Add_To_Cart_URL',
				'group' => 'woocommerce',
			),
			'product-checkout-url'    => array(
				'class' => 'Captwiki_Tag_Product_Checkout_URL',
				'group' => 'woocommerce',
			),
			'product-back-shop-url'   => array(
				'class' => 'Captwiki_Tag_Back_To_Shop_URL',
				'group' => 'woocommerce',
			),
		);

		/**
		 * ACF tags.
		 *
		 * @since 1.2.0
		 * @var   array<string,string>
		 */
		private $acf_tags = array(
			'acf-text'    => array(
				'class' => 'Captwiki_Tag_ACF_Text',
				'group' => 'acf',
			),
			'acf-url'     => array(
				'class' => 'Captwiki_Tag_ACF_URL',
				'group' => 'acf',
			),
			'acf-image'   => array(
				'class' => 'Captwiki_Tag_ACF_Image',
				'group' => 'acf',
			),
			'acf-gallery' => array(
				'class' => 'Captwiki_Tag_ACF_Gallery',
				'group' => 'acf',
			),
		);

		/**
		 * Get singleton instance.
		 *
		 * @since  1.2.0
		 * @return Captwiki_Dynamic_Tags
		 */
		public static function get_instance() {
			if ( null === self::$instance ) {
				self::$instance = new self();
			}
			return self::$instance;
		}

		/**
		 * Constructor — load enabled groups and register Elementor hooks.
		 *
		 * @since 1.2.0
		 */
		private function __construct() {
			$settings             = get_option( 'captwiki_settings', array() );
			$this->enabled_groups = ! empty( $settings['dynamic_tags_groups'] ) && is_array( $settings['dynamic_tags_groups'] )
				? $settings['dynamic_tags_groups']
				: array();

			add_action( 'elementor/dynamic_tags/register', array( $this, 'captwiki_register_groups' ), 1 );
			add_action( 'elementor/dynamic_tags/register', array( $this, 'captwiki_register_tags' ) );
		}

		/**
		 * Check if a group is enabled by the user.
		 *
		 * @since  1.2.0
		 * @param  string $group Group key (e.g. 'post', 'site', 'woocommerce').
		 * @return bool
		 */
		private function captwiki_is_group_enabled( $group ) {
			return in_array( $group, $this->enabled_groups, true );
		}

		/**
		 * Check whether an ACF-compatible plugin is active.
		 *
		 * Supports: Advanced Custom Fields (free/pro) and Secure Custom Fields (SCF).
		 * SCF ships the same ACF class and functions under the ACF namespace, so
		 * function-existence check is the most reliable detection — it works
		 * regardless of plugin slug or load order.
		 *
		 * @since  1.3.0
		 * @return bool
		 */
		private function captwiki_is_acf_active(): bool {
			return function_exists( 'acf_get_field_groups' );
		}

		/**
		 * Register all tag groups with Elementor.
		 *
		 * @since  1.2.0
		 * @param  \Elementor\Core\DynamicTags\Manager $manager Elementor dynamic tags manager.
		 * @return void
		 */
		public function captwiki_register_groups( $manager ) {
			if ( $this->captwiki_is_group_enabled( 'post' ) ) {
				$manager->register_group( 'captwiki-post', array( 'title' => esc_html__( 'Captain - Post', 'captain-widgets-kit' ) ) );
			}
			if ( $this->captwiki_is_group_enabled( 'author' ) ) {
				$manager->register_group( 'captwiki-author', array( 'title' => esc_html__( 'Captain - Author', 'captain-widgets-kit' ) ) );
			}
			if ( $this->captwiki_is_group_enabled( 'site' ) ) {
				$manager->register_group( 'captwiki-site', array( 'title' => esc_html__( 'Captain - Site', 'captain-widgets-kit' ) ) );
			}
			if ( $this->captwiki_is_group_enabled( 'user' ) ) {
				$manager->register_group( 'captwiki-user', array( 'title' => esc_html__( 'Captain - User', 'captain-widgets-kit' ) ) );
			}
			if ( $this->captwiki_is_group_enabled( 'archive' ) ) {
				$manager->register_group( 'captwiki-archive', array( 'title' => esc_html__( 'Captain - Archive', 'captain-widgets-kit' ) ) );
			}
			if ( $this->captwiki_is_group_enabled( 'dc' ) ) {
				$manager->register_group( 'captwiki-dc', array( 'title' => esc_html__( 'Captain - Dynamic Categories', 'captain-widgets-kit' ) ) );
			}
			if ( $this->captwiki_is_group_enabled( 'woocommerce' ) && class_exists( 'WooCommerce' ) ) {
				$manager->register_group( 'captwiki-woocommerce', array( 'title' => esc_html__( 'Captain - WooCommerce', 'captain-widgets-kit' ) ) );
			}
			if ( $this->captwiki_is_group_enabled( 'acf' ) && $this->captwiki_is_acf_active() ) {
				$manager->register_group( 'captwiki-acf', array( 'title' => esc_html__( 'Captain - ACF / SCF', 'captain-widgets-kit' ) ) );
			}
		}

		/**
		 * Load tag files and register all enabled tag instances.
		 *
		 * @since  1.2.0
		 * @param  \Elementor\Core\DynamicTags\Manager $manager Elementor dynamic tags manager.
		 * @return void
		 */
		public function captwiki_register_tags( $manager ) {
			$base = CAPTWIKI_PATH . 'includes/elementor/dynamic-tags/tags/';

			$this->captwiki_load_tags( $manager, $this->text_tags, $base . 'text/' );
			$this->captwiki_load_tags( $manager, $this->image_tags, $base . 'image/' );
			$this->captwiki_load_tags( $manager, $this->url_tags, $base . 'url/' );

			if ( $this->captwiki_is_acf_active() ) {
				$this->captwiki_load_tags( $manager, $this->acf_tags, $base . 'acf/' );
			}

			if ( class_exists( 'WooCommerce' ) ) {
				$this->captwiki_load_tags( $manager, $this->woo_text_tags, $base . 'woocommerce/text/' );
				$this->captwiki_load_tags( $manager, $this->woo_image_tags, $base . 'woocommerce/image/' );
				$this->captwiki_load_tags( $manager, $this->woo_url_tags, $base . 'woocommerce/url/' );
			}
		}

		/**
		 * Load and register a map of tag files if the group is enabled.
		 *
		 * @since  1.2.0
		 * @param  \Elementor\Core\DynamicTags\Manager $manager  Elementor manager.
		 * @param  array<string,array>                 $tag_map  slug => [ class, group ].
		 * @param  string                              $dir      Absolute directory path (with trailing slash).
		 * @return void
		 */
		private function captwiki_load_tags( $manager, array $tag_map, string $dir ) {
			foreach ( $tag_map as $slug => $tag_data ) {
				if ( ! $this->captwiki_is_group_enabled( $tag_data['group'] ) ) {
					continue;
				}
				$file = $dir . 'class-' . sanitize_file_name( strtolower( str_replace( '_', '-', $tag_data['class'] ) ) ) . '.php';
				if ( file_exists( $file ) ) {
					require_once $file;
					if ( class_exists( $tag_data['class'] ) ) {
						$manager->register( new $tag_data['class']() );
					}
				}
			}
		}
	}
}
