<?php
/**
 * Maps every registered Elementor widget to the plugin (or theme) that provides it.
 */

defined( 'ABSPATH' ) || exit;

class TFWA_Widget_Map {

	/**
	 * Registered widgets grouped with provider info.
	 *
	 * @return array<string, array{name:string, title:string, provider:string, provider_slug:string}>
	 *         keyed by widget name (the widgetType stored in _elementor_data).
	 */
	public static function get_map(): array {
		static $map = null;

		if ( null !== $map ) {
			return $map;
		}

		$map     = array();
		$manager = \Elementor\Plugin::instance()->widgets_manager;

		foreach ( $manager->get_widget_types() as $name => $widget ) {
			if ( 'common' === $name ) {
				continue;
			}

			try {
				$file = ( new ReflectionClass( $widget ) )->getFileName();
			} catch ( \ReflectionException $e ) {
				$file = '';
			}

			list( $provider, $slug ) = self::resolve_provider( (string) $file );

			$map[ $name ] = array(
				'name'          => $name,
				'title'         => $widget->get_title() ? $widget->get_title() : $name,
				'provider'      => $provider,
				'provider_slug' => $slug,
			);
		}

		return $map;
	}

	/**
	 * Resolve a class file path to a human-readable provider.
	 *
	 * @return array{0:string,1:string} [provider label, provider slug]
	 */
	private static function resolve_provider( string $file ): array {
		if ( '' === $file ) {
			return array( __( 'Unknown', 'tendforge-widget-auditor-for-elementor' ), 'unknown' );
		}

		$file       = wp_normalize_path( $file );
		$plugin_dir = wp_normalize_path( WP_PLUGIN_DIR ) . '/';
		$mu_dir     = wp_normalize_path( WPMU_PLUGIN_DIR ) . '/';
		$theme_dir  = wp_normalize_path( get_theme_root() ) . '/';

		if ( 0 === strpos( $file, $plugin_dir ) ) {
			$slug = strtok( substr( $file, strlen( $plugin_dir ) ), '/' );

			if ( in_array( $slug, array( 'elementor', 'elementor-pro' ), true ) ) {
				return array( 'elementor' === $slug ? 'Elementor' : 'Elementor Pro', $slug );
			}

			return array( self::plugin_name_from_slug( $slug ), $slug );
		}

		if ( 0 === strpos( $file, $mu_dir ) ) {
			return array( __( 'Must-use plugin', 'tendforge-widget-auditor-for-elementor' ), 'mu-plugin' );
		}

		if ( 0 === strpos( $file, $theme_dir ) ) {
			$theme = wp_get_theme( strtok( substr( $file, strlen( $theme_dir ) ), '/' ) );
			return array(
				sprintf(
					/* translators: %s: theme name */
					__( 'Theme: %s', 'tendforge-widget-auditor-for-elementor' ),
					$theme->exists() ? $theme->get( 'Name' ) : __( 'Unknown theme', 'tendforge-widget-auditor-for-elementor' )
				),
				'theme',
			);
		}

		return array( __( 'Other', 'tendforge-widget-auditor-for-elementor' ), 'other' );
	}

	private static function plugin_name_from_slug( string $slug ): string {
		static $plugins = null;

		if ( null === $plugins ) {
			if ( ! function_exists( 'get_plugins' ) ) {
				require_once ABSPATH . 'wp-admin/includes/plugin.php';
			}
			$plugins = get_plugins();
		}

		foreach ( $plugins as $basename => $data ) {
			if ( 0 === strpos( $basename, $slug . '/' ) && ! empty( $data['Name'] ) ) {
				return $data['Name'];
			}
		}

		return $slug;
	}
}
