<?php
/**
 * Admin Service Provider
 *
 * Registers admin menu pages and enqueues admin scripts/styles.
 *
 * @package Sequensy
 * @since 2.0.0
 */

declare(strict_types=1);

namespace Sequensy\Providers;

use Sequensy\Container;
use Sequensy\Config\OperatorConfig;

// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
	die;
}

/**
 * Class AdminServiceProvider
 *
 * Provides admin UI services including menu registration and asset enqueueing.
 */
class AdminServiceProvider implements ServiceProvider {

	/**
	 * Cached base64-encoded SVG menu icon.
	 *
	 * @var string|null
	 */
	private static ?string $menu_icon_cache = null;

	/**
	 * Register admin services in the container.
	 *
	 * @param Container $container Service container instance.
	 * @return void
	 */
	public function register( Container $container ): void {
		// No container services needed for admin UI.
	}

	/**
	 * Boot the admin service provider.
	 *
	 * Hooks into WordPress admin actions for menu and script registration.
	 *
	 * @param Container $container Service container instance.
	 * @return void
	 */
	public function boot( Container $container ): void {
		add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
	}

	/**
	 * Add admin menu pages.
	 */
	public function add_admin_menu(): void {
		$icon = $this->get_menu_icon();

		// Top-level menu.
		add_menu_page(
			__( 'Sequensy Workflows', 'sequensy' ),
			apply_filters( 'sequensy_plugin_name', __( 'Sequensy', 'sequensy' ) ),
			'manage_options',
			'sequensy-workflows',
			array( $this, 'render_admin_page' ),
			$icon,
			30
		);

		// Submenus - first one with same slug replaces default submenu.
		add_submenu_page(
			'sequensy-workflows',
			__( 'Dashboard', 'sequensy' ),
			__( 'Dashboard', 'sequensy' ),
			'manage_options',
			'sequensy-workflows',
			array( $this, 'render_admin_page' )
		);

		add_submenu_page(
			'sequensy-workflows',
			__( 'Workflows', 'sequensy' ),
			__( 'Workflows', 'sequensy' ),
			'manage_options',
			'sequensy-workflows-workflows',
			array( $this, 'render_admin_page' )
		);

		add_submenu_page(
			'sequensy-workflows',
			__( 'Integrations', 'sequensy' ),
			__( 'Integrations', 'sequensy' ),
			'manage_options',
			'sequensy-workflows-integrations',
			array( $this, 'render_admin_page' )
		);

		add_submenu_page(
			'sequensy-workflows',
			__( 'Activity', 'sequensy' ),
			__( 'Activity', 'sequensy' ),
			'manage_options',
			'sequensy-workflows-activity',
			array( $this, 'render_admin_page' )
		);

		add_submenu_page(
			'sequensy-workflows',
			__( 'Settings', 'sequensy' ),
			__( 'Settings', 'sequensy' ),
			'manage_options',
			'sequensy-workflows-settings',
			array( $this, 'render_admin_page' )
		);
	}

	/**
	 * Get the base64-encoded SVG icon for the admin menu.
	 *
	 * @return string Data URI for the menu icon.
	 */
	private function get_menu_icon(): string {
		if ( null !== self::$menu_icon_cache ) {
			return self::$menu_icon_cache;
		}

		$svg_path = SEQUENSY_PLUGIN_DIR . 'assets/images/menu-icon.svg';

		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Local file read.
		$svg = file_get_contents( $svg_path );

		// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- SVG data URI for menu icon.
		self::$menu_icon_cache = 'data:image/svg+xml;base64,' . base64_encode( $svg );

		return self::$menu_icon_cache;
	}

	/**
	 * Render the admin page container for React app.
	 */
	public function render_admin_page(): void {
		?>
		<div id="sequensy-admin-root"></div>
		<?php
	}

	/**
	 * Enqueue admin scripts and styles.
	 *
	 * @param string $hook Current admin page hook.
	 */
	public function enqueue_admin_scripts( string $hook ): void {
		// Use page slug instead of hook suffix — hook suffix changes when
		// the menu title is filtered (e.g. Pro renames "Sequensy" to "Sequensy Pro"),
		// but page slugs stay constant.
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading page slug for screen detection, not processing form data.
		$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';

		if ( strpos( $page, 'sequensy-workflows' ) === false ) {
			return;
		}

		$screen_map = array(
			'sequensy-workflows'              => 'dashboard',
			'sequensy-workflows-workflows'    => 'workflows',
			'sequensy-workflows-integrations' => 'integrations',
			'sequensy-workflows-activity'     => 'logs',
			'sequensy-workflows-settings'     => 'settings',
		);

		$active_screen = $screen_map[ $page ] ?? 'dashboard';

		$plugin_path    = SEQUENSY_PLUGIN_DIR;
		$plugin_url     = SEQUENSY_PLUGIN_URL;
		$admin_js_path  = $plugin_path . 'admin/dist/admin.js';
		$admin_js_url   = $plugin_url . 'admin/dist/admin.js';
		$admin_css_path = $plugin_path . 'admin/dist/index.css';
		$admin_css_url  = $plugin_url . 'admin/dist/index.css';

		// Enqueue CSS if it exists.
		if ( file_exists( $admin_css_path ) ) {
			wp_enqueue_style(
				'sequensy-admin',
				$admin_css_url,
				array(),
				(string) filemtime( $admin_css_path )
			);
		}

		if ( file_exists( $admin_js_path ) ) {
			wp_enqueue_script(
				'sequensy-admin',
				$admin_js_url,
				array( 'wp-i18n' ),
				(string) filemtime( $admin_js_path ),
				true
			);

			// Load JavaScript translations.
			if ( function_exists( 'wp_set_script_translations' ) ) {
				wp_set_script_translations(
					'sequensy-admin',
					'sequensy',
					SEQUENSY_PLUGIN_DIR . 'languages'
				);
			}

			// Pass WordPress REST API configuration and active screen to React.
			// Allow extensions to add capabilities via filter hook.
			$capabilities = apply_filters(
				'sequensy_admin_capabilities',
				array(
					'multi_account'           => false,
					'version_history'         => apply_filters( 'sequensy_version_history_enabled', false ),
					'nested_filters'          => apply_filters( 'sequensy_filter_max_depth', 1 ) !== 1,
					'marketplace_can_install' => apply_filters( 'sequensy_marketplace_can_install', false ),
					'activity_log_limit'      => apply_filters( 'sequensy_activity_log_limit', 50 ),
					'filter_operators'        => array(
						'operators'                 => OperatorConfig::get_operators(),
						'operators_by_type'         => OperatorConfig::get_operators_by_type(),
						'operators_requiring_value' => OperatorConfig::get_operators_requiring_value(),
					),
				)
			);

			$localize_data = apply_filters(
				'sequensy_admin_localize_data',
				array(
					'root'         => esc_url_raw( rest_url( 'sequensy/v1' ) ),
					'nonce'        => wp_create_nonce( 'wp_rest' ),
					'activeScreen' => $active_screen,
					'capabilities' => $capabilities,
					'is_pro'       => defined( 'SEQUENSY_PRO' ),
					'plugin_name'  => apply_filters( 'sequensy_plugin_name', __( 'Sequensy', 'sequensy' ) ),
				)
			);

			wp_localize_script( 'sequensy-admin', 'sequensyAPI', $localize_data );
		}
	}
}
