<?php
/**
 * Network Admin Area wrapper.
 *
 * @package NimblyMail\SMTP
 *
 * @since 1.0.0
 */

namespace NimblyMail\SMTP\Admin;

defined( 'ABSPATH' ) || exit;

/**
 * Class NetworkArea
 *
 * Registers the Network Admin → NimblyMail menu (Dashboard, Sites,
 * Settings, and a hidden per-site override editor) and enqueues the
 * matching Vue bundle per page. Only active on multisite installs.
 *
 * @since 1.0.0
 */
class NetworkArea {

    /** Top-level network admin menu slug. */
    public const MENU_SLUG = 'nimblymail-smtp-network';

    /** Sites table page slug. */
    public const SITES_SLUG = 'nimblymail-smtp-network-sites';

    /** Network Settings page slug. */
    public const SETTINGS_SLUG = 'nimblymail-smtp-network-settings';

    /** Hidden per-site override editor slug. */
    public const SITE_EDIT_SLUG = 'nimblymail-smtp-network-site-settings';

    /**
     * Map of admin page hook_suffix → Vue bundle + context metadata.
     *
     * Populated in add_menu_pages() so it reflects the exact hook suffixes
     * WordPress returns from add_menu_page/add_submenu_page.
     *
     * @since 1.0.0
     *
     * @var array<string, array{handle: string, entry: string, context: string}>
     */
    private array $apps = array();

    /**
     * Initialize network admin hooks.
     *
     * @since 1.0.0
     *
     * @return void
     */
    public function init(): void {
        add_action( 'network_admin_menu', array( $this, 'add_menu_pages' ) );
        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
        add_filter( 'script_loader_tag', array( AssetLoader::class, 'add_module_to_script_tag' ), 10, 2 );
    }

    /**
     * Register the network admin menu and submenu pages.
     *
     * Registers all built-in network admin submenu pages then fires the
     * nimblymail_network_admin_menu action so Pro add-ons can register
     * their own network submenu pages under the NimblyMail parent slug.
     *
     * @since 1.0.0 Added nimblymail_network_admin_menu action for Pro add-ons.
     *
     * @return void
     */
    public function add_menu_pages(): void {
        // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
        $icon_svg = file_get_contents( NIMBLYMAIL_PATH . 'assets/images/logo/nimblymail-smtp-icon-menu.svg' );
        // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- Base64 SVG for menu icon data URI.
        $icon_url = 'data:image/svg+xml;base64,' . base64_encode( (string) $icon_svg );

        $dashboard_hook = add_menu_page(
            __( 'NimblyMail', 'nimblymail-smtp' ),
            __( 'NimblyMail', 'nimblymail-smtp' ),
            'manage_network_options',
            self::MENU_SLUG,
            array( $this, 'render_page' ),
            $icon_url,
            81
        );

        add_submenu_page(
            self::MENU_SLUG,
            __( 'Dashboard', 'nimblymail-smtp' ),
            __( 'Dashboard', 'nimblymail-smtp' ),
            'manage_network_options',
            self::MENU_SLUG,
            array( $this, 'render_page' )
        );

        $sites_hook = add_submenu_page(
            self::MENU_SLUG,
            __( 'Sites', 'nimblymail-smtp' ),
            __( 'Sites', 'nimblymail-smtp' ),
            'manage_network_options',
            self::SITES_SLUG,
            array( $this, 'render_page' )
        );

        $settings_hook = add_submenu_page(
            self::MENU_SLUG,
            __( 'Network Settings', 'nimblymail-smtp' ),
            __( 'Settings', 'nimblymail-smtp' ),
            'manage_network_options',
            self::SETTINGS_SLUG,
            array( $this, 'render_page' )
        );

        $site_edit_hook = add_submenu_page(
            '',
            __( 'Edit Site Settings', 'nimblymail-smtp' ),
            '',
            'manage_network_options',
            self::SITE_EDIT_SLUG,
            array( $this, 'render_page' )
        );

        /**
         * Fires after all built-in NimblyMail network submenu pages are registered.
         *
         * Allows Pro add-ons to register additional submenu pages under the
         * NimblyMail network admin parent menu slug using standard WordPress APIs.
         *
         * @since 1.0.0
         *
         * @param string $parent_slug The NimblyMail network top-level menu slug.
         */
        do_action( 'nimblymail_network_admin_menu', self::MENU_SLUG );

        $this->apps = array(
            $dashboard_hook => array(
                'handle'  => 'nimblymail-smtp-network-dashboard',
                'entry'   => 'apps/network-dashboard/index.ts',
                'context' => 'network-dashboard',
            ),
            $sites_hook     => array(
                'handle'  => 'nimblymail-smtp-network-sites',
                'entry'   => 'apps/network-sites/index.ts',
                'context' => 'network-sites',
            ),
            $settings_hook  => array(
                'handle'  => 'nimblymail-smtp-settings',
                'entry'   => 'apps/settings/index.ts',
                'context' => 'network',
            ),
            $site_edit_hook => array(
                'handle'  => 'nimblymail-smtp-settings',
                'entry'   => 'apps/settings/index.ts',
                'context' => 'network-site',
            ),
        );
    }

    /**
     * Render the Vue app mount point.
     *
     * All four network admin pages share the same mount — the enqueued bundle
     * decides what to render.
     *
     * @since 1.0.0
     *
     * @return void
     */
    public function render_page(): void {
        echo '<div class="wrap"><div id="nimblymail-smtp-app"></div></div>';
    }

    /**
     * Enqueue the Vue bundle for the currently active network admin page.
     *
     * @since 1.0.0
     *
     * @param string $hook_suffix The current admin page hook.
     *
     * @return void
     */
    public function enqueue_assets( string $hook_suffix ): void {
        if ( ! isset( $this->apps[ $hook_suffix ] ) ) {
            return;
        }

        $app    = $this->apps[ $hook_suffix ];
        $is_hmr = defined( 'HMR_DEV' ) && 'nimblymail-smtp' === HMR_DEV;

        $localize_data = array(
            'root'        => esc_url_raw( rest_url() ),
            'nonce'       => wp_create_nonce( 'wp_rest' ),
            'pluginUrl'   => NIMBLYMAIL_URL,
            'assetsUrl'   => NIMBLYMAIL_URL . 'dist/assets/',
            'adminUrl'    => network_admin_url( 'admin.php' ),
            'adminEmail'  => get_site_option( 'admin_email' ),
            'isDevMode'   => $is_hmr,
            'isMultisite' => true,
            'context'     => $app['context'],
        );

        // The hidden per-site editor needs the target blog id to route REST calls.
        if ( 'network-site' === $app['context'] ) {
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only page view.
            $blog_id = isset( $_GET['blog_id'] ) ? (int) $_GET['blog_id'] : 0;

            $localize_data['targetBlogId'] = $blog_id;
        }

        AssetLoader::enqueue( $app['handle'], $app['entry'], $localize_data, $is_hmr, 'http://localhost:5174' );
    }
}
