<?php
declare(strict_types=1);

namespace Ekesto\CacheWarmup\Settings;

use Ekesto\CacheWarmup\WarmupRuntime;
use Ekesto\CacheWarmup\Settings;
use Ekesto\CacheWarmup\Support\Access;

/**
 * WordPress admin bar operational controls for Cache Warmup.
 */
final class AdminBarMenu
{
    private const ROOT_NODE_ID = 'ekesto-cache-warmup';
    private const STATE_NODE_ID = 'ekesto-cache-warmup-state';
    private const TOGGLE_NODE_ID = 'ekesto-cache-warmup-toggle';
    private const RUN_FULL_NODE_ID = 'ekesto-cache-warmup-run-full';
    private const OPEN_SETTINGS_NODE_ID = 'ekesto-cache-warmup-open-settings';

    /**
     * Register the admin bar menu and submenu actions.
     *
     * @param \WP_Admin_Bar $adminBar WordPress admin bar instance.
     * @return void
     */
    public static function registerMenu(\WP_Admin_Bar $adminBar): void
    {
        if (!self::shouldRender()) {
            return;
        }

        $isEnabled = Repository::isEnabled('general.enabled');
        $settingsUrl = self::settingsUrl();
        $loggingUrl = self::loggingUrl();

        $adminBar->add_node([
            'id' => self::ROOT_NODE_ID,
            'title' => self::rootLabelHtml($isEnabled),
            'href' => $settingsUrl,
        ]);

        $adminBar->add_node([
            'id' => self::STATE_NODE_ID,
            'parent' => self::ROOT_NODE_ID,
            'title' => $isEnabled
                ? esc_html__('Warmup: Active', 'cache-autopilot')
                : esc_html__('Warmup: Paused', 'cache-autopilot'),
            'meta' => ['class' => 'ecw-adminbar-state-row'],
        ]);

        $adminBar->add_node([
            'id' => self::TOGGLE_NODE_ID,
            'parent' => self::ROOT_NODE_ID,
            'title' => $isEnabled
                ? esc_html__('Pause automatic warmup', 'cache-autopilot')
                : esc_html__('Enable automatic warmup', 'cache-autopilot'),
            'href' => self::toggleUrl(!$isEnabled),
        ]);

        $adminBar->add_node([
            'id' => self::RUN_FULL_NODE_ID,
            'parent' => self::ROOT_NODE_ID,
            'title' => esc_html__('Trigger full cache refresh', 'cache-autopilot'),
            'href' => self::runFullUrl(),
            'meta' => [
                'class' => $isEnabled ? '' : 'ecw-adminbar-hidden',
            ],
        ]);

        $adminBar->add_node([
            'id' => self::OPEN_SETTINGS_NODE_ID,
            'parent' => self::ROOT_NODE_ID,
            'title' => esc_html__('Show log', 'cache-autopilot'),
            'href' => $loggingUrl,
        ]);
    }

    /**
     * Register the admin bar menu from the late render hook.
     *
     * @return void
     */
    public static function registerMenuBeforeRender(): void
    {
        global $wp_admin_bar;

        if (!$wp_admin_bar instanceof \WP_Admin_Bar) {
            return;
        }

        self::registerMenu($wp_admin_bar);
    }

    /**
     * Enqueue toolbar styles on frontend requests where the menu can render.
     *
     * @return void
     */
    public static function enqueueFrontendStyles(): void
    {
        if (!self::shouldRender()) {
            return;
        }

        AdminPage::enqueueGlobalAdminStyles();
    }

    /**
     * Determine whether the current request should render admin bar controls.
     *
     * @return bool True when toolbar controls should be rendered.
     */
    private static function shouldRender(): bool
    {
        return is_admin_bar_showing() && Access::userCanManage();
    }

    /**
     * Build the settings page URL.
     *
     * @return string Settings page URL.
     */
    private static function settingsUrl(): string
    {
        return AdminPage::settingsPageUrl();
    }

    /**
     * Build the logging tab URL.
     *
     * @return string Logging tab URL.
     */
    private static function loggingUrl(): string
    {
        return AdminPage::settingsPageUrl(['tab' => 'logging']) . '#logging';
    }

    /**
     * Build a nonce-protected URL for the warmup toggle admin-post action.
     *
     * @param bool $enabled Target enabled state to persist.
     * @return string Nonce-protected action URL.
     */
    private static function toggleUrl(bool $enabled): string
    {
        $url = add_query_arg(
            [
                'action' => 'ekesto_cache_warmup_toggle_enabled',
                'enabled' => $enabled ? '1' : '0',
            ],
            admin_url('admin-post.php')
        );

        return wp_nonce_url($url, 'ekesto_cache_warmup_toggle_enabled');
    }

    /**
     * Build a nonce-protected URL for full warmup enqueueing from the admin bar.
     *
     * @return string Nonce-protected action URL.
     */
    private static function runFullUrl(): string
    {
        $url = add_query_arg(
            ['action' => 'ekesto_cache_warmup_run_full'],
            admin_url('admin-post.php')
        );

        return wp_nonce_url($url, 'ekesto_cache_warmup_run_full');
    }

    /**
     * Build icon-only label HTML with screen-reader text and optional paused indicator.
     *
     * @param bool $isEnabled Whether warmup is currently enabled.
     * @return string HTML used as admin bar root title.
     */
    private static function rootLabelHtml(bool $isEnabled): string
    {
        $screenReader = esc_html__('Cache Warmup settings', 'cache-autopilot');
        $pausedBadge = $isEnabled
            ? ''
            : '<span class="ecw-adminbar-pause-indicator" aria-hidden="true"></span>';

        return sprintf(
            '<span class="screen-reader-text">%1$s</span><span class="ecw-adminbar-icon-wrap" aria-hidden="true">%2$s</span>',
            $screenReader,
            $pausedBadge
        );
    }
}
