<?php

declare(strict_types=1);

namespace FleekDash\Admin;

// Load debug helpers
if (!function_exists('fleekdash_log_debug')) {
    require_once FLEEKDASH_PLUGIN_DIR . 'includes/Core/debug-helpers.php';
}

use FleekDash\Admin\Menu\RouteConverter;
use FleekDash\Admin\Menu\MenuHelpers;
use FleekDash\Admin\Menu\MenuCaptureService;
use FleekDash\Admin\Menu\MenuItemFormatter;
use FleekDash\Admin\Menu\ToolbarCaptureService;

/**
 * Admin Menu - Refactored
 *
 * Manages the registration and capture of WordPress Admin menus
 * Uses service classes for route conversion and utilities
 *
 * @package FleekDash\Admin
 */
class AdminMenu
{
    /**
     * Route converter service
     */
    private RouteConverter $routeConverter;

    /**
     * Menu capture service
     */
    private MenuCaptureService $menuCapture;

    /**
     * Toolbar capture service
     */
    private ToolbarCaptureService $toolbarCapture;

    /**
     * Menu formatter service
     */
    private MenuItemFormatter $menuFormatter;

    /**
     * Constructor
     */
    private function __construct()
    {
        $this->routeConverter = new RouteConverter();
        $this->menuCapture = new MenuCaptureService();
        $this->toolbarCapture = new ToolbarCaptureService();
        $this->menuFormatter = new MenuItemFormatter($this->routeConverter);
    }

    /**
     * Singleton instance
     */
    private static ?self $instance = null;

    /**
     * Get singleton instance
     */
    public static function getInstance(): self
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * URLs that should open in a new tab
     */
    private $newTabUrls = [
        'customize.php',
        'site-editor.php',
    ];

    /**
     * Register menu-related WordPress hooks
     */
    public function bootstrap()
    {
        // GUARD: Prevent multiple bootstrap calls from registering hooks multiple times
        static $bootstrapped = false;
        if ($bootstrapped) {
            return;
        }
        $bootstrapped = true;

        // Register our menu pages first with normal priority
        \add_action('admin_menu', array($this, 'registerMenuPages'), 10);

        // Capture the complete menu after all plugins have registered their items
        \add_action('admin_menu', array($this, 'captureAdminMenuComplete'), 998);

        // Ensure we have the menu before admin bar renders
        \add_action('wp_before_admin_bar_render', array($this, 'ensureMenuCaptured'));

        // URLs that should open in a new tab
        \add_filter('fleekdash_menu_new_tab_urls', array($this, 'filterNewTabUrls'));

        // DEFINITIVE SNAPSHOT: Persist the final menu snapshot at end of real wp-admin requests.
        // This ensures the REST API always returns what WordPress actually rendered for the user.
        \add_action('shutdown', array($this, 'captureAdminMenuShutdown'), 1);

        // AJAX endpoint removed - will be replaced with REST API
    }

    /**
     * Register menu pages for FleekDash
     */
    public function registerMenuPages()
    {
        // Static guard to prevent multiple registrations
        static $menu_registered = false;

        if ($menu_registered) {
            return;
        }

        fleekdash_log_debug('[FleekDash] Registering menu pages in debug mode');

        add_menu_page(
            'FleekDash',
            'FleekDash',
            'manage_options',
            'fleekdash',
            array($this, 'renderApp'),
            'dashicons-chart-area',
            2,
        );

        add_submenu_page(
            'fleekdash',
            'Dashboard',
            'Dashboard',
            'manage_options',
            'fleekdash',
            array($this, 'renderApp'),
        );

        add_submenu_page(
            'fleekdash',
            'Settings',
            'Settings',
            'manage_options',
            'fleekdash-settings',
            array($this, 'renderApp'),
        );

        $menu_registered = true;
    }

    /**
     * Render the React application
     */
    public function renderApp()
    {
        // For all FleekDash pages, let the React app mount automatically
        // The debug tools now use React routing instead of PHP rendering
        echo '<!-- FleekDash V2 app will be mounted automatically -->';
    }

    /**
     * Capture the complete WordPress menu after all plugins have registered their items
     */
    public function captureAdminMenuComplete()
    {
        global $menu, $submenu;
        $this->menuCapture->captureAdminMenu($menu, $submenu);
    }

    /**
     * Ensure we have captured the menu before admin bar renders
     */
    public function ensureMenuCaptured()
    {
        $this->menuCapture->ensureMenuCaptured();
    }

    /**
     * Capture final menu snapshot at the end of admin request lifecycle.
     *
     * Persists menu snapshot to user_meta for REST endpoints.
     * This ensures REST endpoints return exactly what WordPress rendered in wp-admin.
     *
     * This runs in web admin context only.
     */
    public function captureAdminMenuShutdown(): void
    {
        if (!\is_admin() || !\is_user_logged_in()) {
            return;
        }

        global $menu, $submenu, $wp_admin_bar;

        // DEFINITIVE: Persist the final menu snapshot at end of real wp-admin requests.
        // REST endpoints must return exactly what WordPress rendered (same as window.FleekDash.adminMenu).
        $this->menuCapture->clearInMemoryCache();
        $this->menuCapture->captureAdminMenu($menu, $submenu);
        $this->menuCapture->persistSnapshotForCurrentUser();

        // DEFINITIVE: Persist the final toolbar snapshot at end of real wp-admin requests.
        // REST endpoints must return exactly what WordPress rendered (same as window.FleekDash.adminToolbar).
        if ($wp_admin_bar instanceof \WP_Admin_Bar) {
            $this->toolbarCapture->clearInMemoryCache();
            $this->toolbarCapture->captureAdminToolbar($wp_admin_bar);
            $this->toolbarCapture->persistSnapshotForCurrentUser();
        }
    }

    /**
     * Get WordPress admin menu items.
     *
     * Ensures menu is captured before returning. In admin context, uses globals directly.
     * In REST context, MenuCaptureService will prioritize user_meta snapshot.
     *
     * @return array
     */
    public function getAdminMenuItems()
    {
        // Always clear in-memory cache first to force fresh capture
        // This ensures we always get the current state, not stale cached data
        $this->menuCapture->clearInMemoryCache();

        // Ensure menu is captured before reading
        $this->menuCapture->ensureMenuCaptured();

        $menu = $this->menuCapture->getStoredMenu();
        $submenu = $this->menuCapture->getStoredSubmenu();

        return $this->menuFormatter->formatMenuItems($menu, $submenu);
    }

    /**
     * Add URLs from $newTabUrls to the list of URLs that open in a new tab
     *
     * @param array $urls Current URLs
     * @return array Updated URLs
     */
    public function filterNewTabUrls(array $urls): array
    {
        if (empty($this->newTabUrls) || !is_array($this->newTabUrls)) {
            return $urls;
        }

        return array_unique(array_merge($urls, $this->newTabUrls));
    }

    /**
     * Get stored menu items
     *
     * @return array
     */
    public function getStoredMenu()
    {
        return $this->menuCapture->getStoredMenu();
    }

    /**
     * Get stored submenu items
     *
     * @return array
     */
    public function getStoredSubmenu()
    {
        return $this->menuCapture->getStoredSubmenu();
    }

    /**
     * Get WordPress admin toolbar data
     *
     * @return array
     */
    public function getAdminToolbarData()
    {
        global $wp_admin_bar;

        $toolbar_data = array(
            'updateCount' => 0,
            'commentCount' => 0,
            'newContentItems' => array(),
        );

        // Get update count from core
        // Note: \get_core_updates() returns array with current version too (response='latest')
        // We only count items with response='upgrade' (actual pending updates)
        $core_updates = \get_core_updates();
        if (is_array($core_updates)) {
            foreach ($core_updates as $update) {
                // Only count if response is 'upgrade' (pending update)
                // 'latest' means already up-to-date, 'development' is dev version
                if (isset($update->response) && $update->response === 'upgrade') {
                    $toolbar_data['updateCount']++;
                }
            }
        }

        // Check for plugin updates
        $plugin_updates = \get_site_transient('update_plugins');
        if (is_object($plugin_updates) && !empty($plugin_updates->response)) {
            $toolbar_data['updateCount'] += count($plugin_updates->response);
        }

        // Check for theme updates
        $theme_updates = \get_site_transient('update_themes');
        if (is_object($theme_updates) && !empty($theme_updates->response)) {
            $toolbar_data['updateCount'] += count($theme_updates->response);
        }

        // Get comment moderation count
        $awaiting_mod = \wp_count_comments();
        if (is_object($awaiting_mod)) {
            $toolbar_data['commentCount'] = (int) $awaiting_mod->moderated;
        }

        // Get new content menu items
        $toolbar_data['newContentItems'] = MenuHelpers::getNewContentItems();

        return $toolbar_data;
    }

    // AJAX endpoint removed - will be replaced with REST API in next implementation
}
