<?php

namespace WPSN\Admin;

use WPSN\Core\Branding;
use WPSN\Core\Capabilities;
use WPSN\Core\CompatibilityDetector;
use WPSN\Core\Container;
use WPSN\Core\RecoveryHelper;
use WPSN\Core\Queue\QueuePause;
use WPSN\Modules\TasksHub\PinnedTaskQueuesRepository;
use WPSN\Modules\TasksHub\TaskQueuesCatalog;
use WPSN\Modules\TasksHub\TaskViewsRepository;

defined('ABSPATH') || exit;

/**
 * Lightweight WP Admin Bar integration.
 *
 * Purpose:
 * - Quick visibility of recovery modes (Safe mode / Output disabled / Perf budget)
 * - One-click toggles (admin-only, nonce protected)
 *
 * This is strictly plugin UX (no marketing, no upsell).
 */
final class AdminBar
{
    private Container $container;

    public function __construct(Container $container)
    {
        $this->container = $container;
    }

    public function register(): void
    {
        add_action('admin_bar_menu', [$this, 'addMenu'], 90);
        // Add minimal CSS for status badges (admin + frontend).
        add_action('admin_head', [$this, 'printCss']);
        add_action('wp_head', [$this, 'printCss']);

        // Toggle handlers.
        add_action('admin_post_wpsn_toggle_mode', [$this, 'handleToggleMode']);
    }

    public function printCss(): void
    {
        if (!function_exists('is_admin_bar_showing') || !is_admin_bar_showing()) {
            return;
        }

        // Keep CSS minimal and scoped.
        echo '<style id="wpsn-adminbar-css">'
            . '#wpadminbar .wpsn-ab-badge{display:inline-block;margin-left:6px;padding:1px 6px;border-radius:10px;font-size:10px;line-height:14px;text-transform:uppercase;letter-spacing:.3px;}'
            . '#wpadminbar .wpsn-ab-badge.safe{background:#d63638;color:#fff;}'
            . '#wpadminbar .wpsn-ab-badge.out{background:#b32d2e;color:#fff;}'
            . '#wpadminbar .wpsn-ab-badge.perf{background:#2271b1;color:#fff;}'
            . '#wpadminbar .wpsn-ab-badge.auto{background:#00a32a;color:#fff;}'
            . '#wpadminbar .wpsn-ab-badge.queue{background:#dba617;color:#fff;}'
            . '</style>';
    }

    public function addMenu($wpAdminBar): void
    {
        if (!($wpAdminBar instanceof \WP_Admin_Bar)) {
            return;
        }
        if (!is_user_logged_in()) {
            return;
        }
        // Only show to users who can actually change things.
        if (!Capabilities::canManageTools()) {
            return;
        }

        $settings = $this->container->get('settings');

        $brand = Branding::brand($settings);
        if ($brand === '') {
            $brand = __('SEO', 'wp-seo-next');
        }

        $safeModeForced = defined('WPSN_SAFE_MODE') && (bool) WPSN_SAFE_MODE;
        $safeModeStored = (bool) $settings->get('compatibility.safe_mode', false);
        $safeMode = $safeModeForced || $safeModeStored;

        $disableOutputForced = defined('WPSN_DISABLE_OUTPUT') && (bool) WPSN_DISABLE_OUTPUT;
        $disableOutputStored = (bool) $settings->get('compatibility.disable_output', false);
        $autoDisableOnConflict = (bool) $settings->get('compatibility.auto_disable_output_on_conflict', false);
        $hasConflict = CompatibilityDetector::hasSeoConflict();
        $disableOutputAuto = $autoDisableOnConflict && $hasConflict;
        $disableOutput = $disableOutputForced || $disableOutputStored || $disableOutputAuto;

        $minFootprint = (bool) $settings->get('performance.admin.minimize_admin_footprint', false);

        $queuePaused = QueuePause::isPaused();

        $badges = '';
        if ($safeMode) {
            $badges .= '<span class="wpsn-ab-badge safe">SAFE</span>';
        }
        if ($disableOutput) {
            $badges .= '<span class="wpsn-ab-badge out">OUT</span>';
            if ($disableOutputAuto && !$disableOutputStored && !$disableOutputForced) {
                $badges .= '<span class="wpsn-ab-badge auto">AUTO</span>';
            }
        }
        if ($minFootprint) {
            $badges .= '<span class="wpsn-ab-badge perf">PERF</span>';
        }
        if ($queuePaused) {
            $badges .= '<span class="wpsn-ab-badge queue">QPAUSE</span>';
        }

        $hubUrl = admin_url('admin.php?page=wpsn');
        $settingsUrl = admin_url('admin.php?page=wp-seo-next');
        $diagnosticsUrl = admin_url('tools.php?page=wpsn-diagnostics');
        $notificationsUrl = admin_url('tools.php?page=wpsn-notifications');

        $wpAdminBar->add_node([
            'id'    => 'wpsn',
            'title' => esc_html($brand) . $badges,
            'href'  => $hubUrl,
            'meta'  => ['title' => __('WP SEO Next', 'wp-seo-next')],
        ]);

        // Primary links.
        $wpAdminBar->add_node([
            'id'     => 'wpsn-dashboard',
            'parent' => 'wpsn',
            'title'  => __('Dashboard', 'wp-seo-next'),
            'href'   => $hubUrl,
        ]);
        $wpAdminBar->add_node([
            'id'     => 'wpsn-settings',
            'parent' => 'wpsn',
            'title'  => __('Settings', 'wp-seo-next'),
            'href'   => $settingsUrl,
        ]);
        $wpAdminBar->add_node([
            'id'     => 'wpsn-notifications',
            'parent' => 'wpsn',
            'title'  => __('Notifications', 'wp-seo-next'),
            'href'   => $notificationsUrl,
        ]);
        $wpAdminBar->add_node([
            'id'     => 'wpsn-diagnostics',
            'parent' => 'wpsn',
            'title'  => __('Compatibility & Diagnostics', 'wp-seo-next'),
            'href'   => $diagnosticsUrl,
        ]);

        $taskUserId = function_exists('get_current_user_id') ? (int) get_current_user_id() : 0;
        $taskCatalog = new TaskQueuesCatalog(new TaskViewsRepository(), $taskUserId);
        $pinnedTaskQueues = (new PinnedTaskQueuesRepository($taskCatalog, $taskUserId))->all();
        if (!empty($pinnedTaskQueues)) {
            $wpAdminBar->add_node([
                'id'     => 'wpsn-task-queues',
                'parent' => 'wpsn',
                'title'  => __('Task queues', 'wp-seo-next'),
                'href'   => admin_url('tools.php?page=wpsn-tasks&tab=all'),
            ]);

            foreach (array_slice($pinnedTaskQueues, 0, 5) as $queue) {
                if (!is_array($queue)) {
                    continue;
                }
                $label = isset($queue['label']) ? (string) $queue['label'] : '';
                $url = isset($queue['url']) ? (string) $queue['url'] : '';
                $ref = isset($queue['ref']) ? (string) $queue['ref'] : '';
                if ($label === '' || $url === '' || $ref === '') {
                    continue;
                }
                $nodeId = 'wpsn-task-queue-' . md5($ref);
                $wpAdminBar->add_node([
                    'id'     => $nodeId,
                    'parent' => 'wpsn-task-queues',
                    'title'  => $label,
                    'href'   => $url,
                ]);
            }

            $wpAdminBar->add_node([
                'id'     => 'wpsn-task-queues-manage',
                'parent' => 'wpsn-task-queues',
                'title'  => __('Manage queues', 'wp-seo-next'),
                'href'   => admin_url('tools.php?page=wpsn-tasks&tab=all'),
            ]);
        }

        // Separator.
        $wpAdminBar->add_node([
            'id'     => 'wpsn-sep-1',
            'parent' => 'wpsn',
            'title'  => '<span style="opacity:.7;">' . esc_html__('Recovery modes', 'wp-seo-next') . '</span>',
            'href'   => false,
            'meta'   => ['html' => true],
        ]);

        $current = (function_exists('wp_get_referer') ? (string) wp_get_referer() : '');
        if ($current === '') {
            $current = (function_exists('home_url') ? (string) home_url('/') : '/');
        }

        // Toggle links (disable if forced by constants).
        $wpAdminBar->add_node([
            'id'     => 'wpsn-toggle-safe',
            'parent' => 'wpsn',
            'title'  => $safeMode ? __('Safe mode: ON', 'wp-seo-next') : __('Safe mode: OFF', 'wp-seo-next'),
            'href'   => $safeModeForced ? $diagnosticsUrl : $this->toggleUrl('safe_mode', $current),
            'meta'   => ['title' => $safeModeForced ? __('Forced by WPSN_SAFE_MODE', 'wp-seo-next') : ''],
        ]);

        $wpAdminBar->add_node([
            'id'     => 'wpsn-toggle-output',
            'parent' => 'wpsn',
            'title'  => $disableOutput ? __('Output: OFF', 'wp-seo-next') : __('Output: ON', 'wp-seo-next'),
            'href'   => $disableOutputForced ? $diagnosticsUrl : $this->toggleUrl('disable_output', $current),
            'meta'   => ['title' => $disableOutputForced ? __('Forced by WPSN_DISABLE_OUTPUT', 'wp-seo-next') : ''],
        ]);

        $wpAdminBar->add_node([
            'id'     => 'wpsn-toggle-perf',
            'parent' => 'wpsn',
            'title'  => $minFootprint ? __('Admin footprint: MIN', 'wp-seo-next') : __('Admin footprint: NORMAL', 'wp-seo-next'),
            'href'   => $this->toggleUrl('min_footprint', $current),
        ]);

        $queuePauseForced = (defined('WPSN_QUEUE_PAUSE') && (bool) WPSN_QUEUE_PAUSE) || (defined('WPSN_QUEUE_PAUSE_UNTIL') && (int) WPSN_QUEUE_PAUSE_UNTIL > time());
        $wpAdminBar->add_node([
            'id'     => 'wpsn-toggle-queue',
            'parent' => 'wpsn',
            'title'  => $queuePaused ? __('Queue: PAUSED', 'wp-seo-next') : __('Queue: RUNNING', 'wp-seo-next'),
            'href'   => $queuePauseForced ? $diagnosticsUrl : $this->toggleUrl('queue_pause', $current),
            'meta'   => ['title' => $queuePauseForced ? __('Forced by WPSN_QUEUE_PAUSE / WPSN_QUEUE_PAUSE_UNTIL', 'wp-seo-next') : ''],
        ]);

        // Recovery helper quick access (admin-only). This link is harmless if MU-helper isn't installed.
        if (Capabilities::canManageSettings()) {
            $wpAdminBar->add_node([
                'id'     => 'wpsn-sep-2',
                'parent' => 'wpsn',
                'title'  => '<span style="opacity:.7;">' . esc_html__('Emergency actions', 'wp-seo-next') . '</span>',
                'href'   => false,
                'meta'   => ['html' => true],
            ]);

            $wpAdminBar->add_node([
                'id'     => 'wpsn-recovery-disable',
                'parent' => 'wpsn',
                'title'  => __('Disable plugin (recovery)', 'wp-seo-next'),
                'href'   => RecoveryHelper::recoveryUrlAdminOnly('disable', $current),
            ]);

            $wpAdminBar->add_node([
                'id'     => 'wpsn-recovery-restore',
                'parent' => 'wpsn',
                'title'  => __('Restore last config snapshot (recovery)', 'wp-seo-next'),
                'href'   => RecoveryHelper::recoveryUrlAdminOnly('restore_config', $current),
            ]);
        }
    }

    private function toggleUrl(string $mode, string $redirect): string
    {
        $url = add_query_arg([
            'action' => 'wpsn_toggle_mode',
            'mode' => $mode,
            'redirect' => $redirect,
        ], admin_url('admin-post.php'));

        return (string) wp_nonce_url($url, 'wpsn_toggle_mode', 'wpsn_nonce');
    }

    public function handleToggleMode(): void
    {
        if (!Capabilities::canManageSettings()) {
            wp_die(esc_html__('You do not have permission to perform this action.', 'wp-seo-next'));
        }
        check_admin_referer('wpsn_toggle_mode', 'wpsn_nonce');

        $mode = isset($_GET['mode']) ? sanitize_key((string) wp_unslash($_GET['mode'])) : '';
        $redirect = isset($_GET['redirect']) ? (string) wp_unslash($_GET['redirect']) : '';

        $repo = new \WPSN\Admin\SettingsRepository();
        $all = $repo->getAll();

        if (!isset($all['compatibility']) || !is_array($all['compatibility'])) {
            $all['compatibility'] = [];
        }
        if (!isset($all['performance']) || !is_array($all['performance'])) {
            $all['performance'] = [];
        }
        if (!isset($all['performance']['admin']) || !is_array($all['performance']['admin'])) {
            $all['performance']['admin'] = [];
        }

        if ($mode === 'safe_mode') {
            // Don't fight constants.
            if (!(defined('WPSN_SAFE_MODE') && (bool) WPSN_SAFE_MODE)) {
                $all['compatibility']['safe_mode'] = empty($all['compatibility']['safe_mode']);
            }
        } elseif ($mode === 'disable_output') {
            if (!(defined('WPSN_DISABLE_OUTPUT') && (bool) WPSN_DISABLE_OUTPUT)) {
                $all['compatibility']['disable_output'] = empty($all['compatibility']['disable_output']);
            }
        } elseif ($mode === 'min_footprint') {
            $all['performance']['admin']['minimize_admin_footprint'] = empty($all['performance']['admin']['minimize_admin_footprint']);
        } elseif ($mode === 'queue_pause') {
            // Queue pause is an operational flag (stored outside settings) so it doesn't pollute snapshots/config sync.
            if (!((defined('WPSN_QUEUE_PAUSE') && (bool) WPSN_QUEUE_PAUSE) || (defined('WPSN_QUEUE_PAUSE_UNTIL') && (int) WPSN_QUEUE_PAUSE_UNTIL > time()))) {
                if (QueuePause::isPaused()) {
                    QueuePause::resume();
                } else {
                    QueuePause::pause(3600, 'admin_bar');
                }
            }
        }

        // Only persist settings if we touched them.
        if ($mode !== 'queue_pause') {
            $repo->update($all);
        }

        // Redirect back.
        $redirect = $redirect !== '' ? $redirect : admin_url('admin.php?page=wpsn');
        $redirect = wp_validate_redirect($redirect, admin_url('admin.php?page=wpsn'));
        wp_safe_redirect($redirect);
        exit;
    }
}
