<?php

/**
 * Class AppPage
 * 
 * @package ArraySubs
 * @since 1.0.0
 *
 * Handles the admin menu pages and assets for the ArraySubs plugin.
 * Creates and manages the main plugin menu, dashboard, and widget builder pages.
 */

namespace ArraySubs\Features\MainAdmin\Services;

use ArraySubs\Supports\Config;
use ArraySubs\Features\MainAdmin\Services\MenuConfig;

if (! defined('ABSPATH')) {
    exit; // Exit if accessed directly
}

class Hooks
{
    public static $loadable = true;

    private string $capability = 'manage_woocommerce';
    private string $menu_slug = 'arraysubs-mainadmin';

    /**
     * Constructor.
     * 
     * Initializes the class by registering WordPress admin menu and asset hooks.
     */
    public function __construct()
    {
        add_action('admin_menu', [$this, 'registerMenu']);

        add_action('admin_enqueue_scripts', [$this, 'enqueueAssets'], 100);
    }

    /**
     * Enqueues the required CSS and JavaScript files.
     *
     * @param string $hook The current admin page hook.
     * @return void
     */
    public function enqueueAssets($hook): void
    {
        // Only load on app page
        if (
            !is_admin() ||
            !current_user_can($this->capability) ||
            $hook !== 'toplevel_page_' . $this->menu_slug
        ) {
            return;
        }

        wp_enqueue_media();
        wp_enqueue_editor();

        // Load dependencies and version from webpack asset file.
        $asset_file = Config::get('plugin.public_path') . 'build/admin/mainadmin.asset.php';
        $asset = file_exists($asset_file) ? require $asset_file : ['dependencies' => ['arraysubs-boot'], 'version' => ARRAYSUBS_VERSION];

        // Enqueue main CSS
        wp_enqueue_style(
            'arraysubs-mainadmin',
            Config::get('plugin.public_url') . 'build/admin/mainadmin.css',
            [],
            $asset['version']
        );

        // Enqueue main JS - webpack will lazy load chunks automatically
        wp_enqueue_script(
            'arraysubs-mainadmin',
            Config::get('plugin.public_url') . 'build/admin/mainadmin.js',
            array_merge($asset['dependencies'], ['arraysubs-boot', 'wp-element']),
            $asset['version'],
            true
        );

        // Load translations for React components
        wp_set_script_translations(
            'arraysubs-mainadmin',
            'arraysubs',
            Config::get('plugin.plugin_path') . 'languages'
        );

        // Pass menu config to JavaScript
        $json_flags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT;

        wp_add_inline_script(
            'arraysubs-mainadmin',
            'window.arraySubs.menu = ' . wp_json_encode([
                'items' => MenuConfig::getMenuItems(),
            ], $json_flags) . ';' .
                'window.arraySubs.shortcodes = ' . wp_json_encode($this->getShortcodeRegistry(), $json_flags) . ';',
            'before'
        );
    }

    /**
     * Get shortcode registry data for the admin UI.
     *
     * @return array<int, array<string, mixed>>
     */
    private function getShortcodeRegistry(): array
    {
        $shortcodes = apply_filters('arraysubs_shortcode_registry', []);

        if (!is_array($shortcodes)) {
            return [];
        }

        usort(
            $shortcodes,
            static function ($left, $right): int {
                $left_title = is_array($left) && isset($left['title']) ? (string) $left['title'] : '';
                $right_title = is_array($right) && isset($right['title']) ? (string) $right['title'] : '';

                return strcasecmp($left_title, $right_title);
            }
        );

        return $shortcodes;
    }

    /**
     * Registers the plugin's admin menu and submenu pages.
     *
     * Creates the main menu item and adds Dashboard and Widget Builder as submenus.
     *
     * @return void
     */
    public function registerMenu(): void
    {
        add_menu_page(
            esc_html__('Dashboard', 'arraysubs'),
            esc_html__('ArraySubs', 'arraysubs'),
            $this->capability,
            $this->menu_slug,
            [$this, 'render'],
            'dashicons-admin-generic',
            30
        );

        // Register submenus from MenuConfig
        $menuItems = MenuConfig::getMenuItems();
        foreach ($menuItems as $item) {
            $item_visibility = isset($item['visiblity']) ? (int) $item['visiblity'] : 1;

            if (0 === $item_visibility) {
                continue;
            }

            $path = $item['path'] ?? '/';

            if (isset($item['children']) && is_array($item['children'])) {
                foreach ($item['children'] as $child) {
                    $child_visibility = isset($child['visiblity']) ? (int) $child['visiblity'] : 1;

                    if (0 !== $child_visibility && isset($child['path']) && is_string($child['path'])) {
                        $path = $child['path'];
                        break;
                    }
                }
            }

            add_submenu_page(
                $this->menu_slug,
                esc_html($item['title']),
                esc_html($item['title']),
                $this->capability,
                $this->menu_slug . '#' . $path,
                [$this, 'render']
            );
        }

        // Remove the duplicate first submenu created by add_menu_page
        remove_submenu_page($this->menu_slug, $this->menu_slug);
    }

    /**
     * Renders the app page content with react router.
     *
     * @return void
     */
    public function render(): void
    {
        $view_file = dirname(__DIR__) . '/views/mainadmin.php';
        $fs = \ArraySubs\Supports\FileSystem::getInstance();
        if ($fs->exists($view_file)) {
            include $view_file;
        }
    }
}
