<?php

declare(strict_types=1);

namespace FleekDash\Admin;

/**
 * Suppresses the native WordPress admin bar on modern full-width admin UIs when not inside
 * a FleekDash iframe. Classic list screens keep the toolbar.
 */
final class AdminWordPressToolbarPolicy
{
    /** @var list<string> Lowercase substrings of $screen->id that indicate a full-bleed packaged admin UI. */
    private const DEFAULT_FULL_BLEED_SCREEN_ID_MARKERS = [
        'mailerpress',
    ];

    public function bootstrap(): void
    {
        \add_action('admin_enqueue_scripts', [$this, 'maybeSuppressToolbar'], 9999);
        // Screen id (e.g. toplevel_page_mailerpress-campaigns) exists before body output — reliable
        // when plugins add marketing/body classes only at late priority or via JS.
        \add_action('current_screen', [$this, 'maybeSuppressFromCurrentScreen'], 0);
        // Late pass: *-ui-full-screen on body is unreliable alone (MailerPress adds it globally).
        // Only treat it as full-bleed when core editor body classes are absent (see body heuristic).
        \add_filter('admin_body_class', [$this, 'maybeSuppressToolbarFromBodyClassString'], 99999);
    }

    public function maybeSuppressFromCurrentScreen(\WP_Screen $screen): void
    {
        $loggedIn = \is_user_logged_in();
        $forcedShow = (bool) \apply_filters('fleekdash_force_show_wp_admin_bar', false);
        $keepToolbar = $this->currentRequestExplicitlyKeepsToolbar();
        $implies = $this->currentScreenSuggestsHideNativeToolbar($screen);

        $suppress = $loggedIn && !$forcedShow && !$keepToolbar && $implies;
        if ($suppress) {
            \add_filter('show_admin_bar', '__return_false', 1000);
        }
    }

    private function currentScreenSuggestsHideNativeToolbar(\WP_Screen $screen): bool
    {
        $fromScreenFilter = (bool) \apply_filters('fleekdash_admin_bar_suppress_on_admin_screen', false, $screen);
        if ($fromScreenFilter) {
            return true;
        }

        return self::screenIdSuggestsFullBleedPackagedUi($screen);
    }

    /**
     * Packaged full-bleed admin UIs (e.g. MailerPress) — same markers as DEFAULT_FULL_BLEED_SCREEN_ID_MARKERS.
     * Used by iframe windowed policy to stay in sync with top-level toolbar suppression.
     */
    public static function screenIdSuggestsFullBleedPackagedUi(\WP_Screen $screen): bool
    {
        $id = strtolower((string) $screen->id);
        $markers = \apply_filters(
            'fleekdash_admin_bar_hide_screen_id_markers',
            self::DEFAULT_FULL_BLEED_SCREEN_ID_MARKERS,
        );
        foreach ($markers as $marker) {
            $m = strtolower(trim((string) $marker));
            if ($m !== '' && str_contains($id, $m)) {
                return true;
            }
        }

        return false;
    }

    /**
     * @param string $classes Space-separated body classes from earlier filters.
     */
    public function maybeSuppressToolbarFromBodyClassString(string $classes): string
    {
        $loggedIn = \is_user_logged_in();
        $forcedShow = (bool) \apply_filters('fleekdash_force_show_wp_admin_bar', false);
        $keepToolbar = $this->currentRequestExplicitlyKeepsToolbar();
        $impliesModern = $this->bodyClassStringImpliesFullScreenPluginUi($classes);

        $suppress = $loggedIn && !$forcedShow && !$keepToolbar && $impliesModern;
        if ($suppress) {
            \add_filter('show_admin_bar', '__return_false', 1000);
        }

        return $classes;
    }

    public function maybeSuppressToolbar(): void
    {
        $loggedIn = \is_user_logged_in();
        $forcedShow = (bool) \apply_filters('fleekdash_force_show_wp_admin_bar', false);
        $keepToolbar = $this->currentRequestExplicitlyKeepsToolbar();
        $modernUi = $this->requestUsesModernFullWidthAdminUi();

        $suppress = $loggedIn && !$forcedShow && !$keepToolbar && $modernUi;
        if ($suppress) {
            \add_filter('show_admin_bar', '__return_false', 999);
        }
    }

    private function bodyClassStringImpliesFullScreenPluginUi(string $classes): bool
    {
        $trimmed = trim($classes);
        $nonEmpty = $trimmed !== '';
        $fromFilter = $nonEmpty && (bool) \apply_filters(
            'fleekdash_admin_bar_suppress_by_body_class_heuristic',
            false,
            $trimmed,
        );
        $hasCoreEditorBody = $nonEmpty && $this->bodyClassStringSuggestsCoreWpEditor($trimmed);
        $fullScreenUi = $nonEmpty
            && !$hasCoreEditorBody
            && \preg_match('/(?:^|\s)[a-z0-9_-]+-ui-full-screen(?:\s|$)/i', $trimmed) === 1;
        $layoutSidebar = $nonEmpty
            && !$hasCoreEditorBody
            && \preg_match('/(?:^|\s)[a-z0-9_-]+__layout__sidebar(?:\s|$)/i', $trimmed) === 1;

        return $fromFilter || $fullScreenUi || $layoutSidebar;
    }

    /**
     * Core block/classic editor screens add these to body; they must keep the toolbar even if a
     * plugin adds *-ui-full-screen globally. (Inner-app layout classes live in React roots — not
     * visible to this PHP filter — so body-level checks stay conservative.)
     */
    private function bodyClassStringSuggestsCoreWpEditor(string $classes): bool
    {
        return \preg_match(
            '/(?:^|\s)(block-editor-page|post-new-php|post-php|site-editor-php)(?:\s|$)/',
            $classes,
        ) === 1;
    }

    private function currentRequestExplicitlyKeepsToolbar(): bool
    {
        $param = isset($_GET['adminbar']) ? \sanitize_text_field((string) $_GET['adminbar']) : '';

        return $param === 'true';
    }

    private function requestUsesModernFullWidthAdminUi(): bool
    {
        $result = false;
        $screen = \function_exists('get_current_screen') ? \get_current_screen() : null;
        if ($screen instanceof \WP_Screen) {
            // Core post/page block editor: keep the native toolbar (plugins may add global body classes).
            $result = $this->screenIsSiteEditor($screen);
        }

        if (!$result) {
            global $pagenow;
            $result = $pagenow === 'site-editor.php' || $this->adminPhpPageUsesReactAppStack();
        }

        return (bool) \apply_filters('fleekdash_suppress_wp_admin_bar_modern_admin', $result);
    }

    private function screenIsSiteEditor(\WP_Screen $screen): bool
    {
        $base = (string) $screen->base;
        $id = (string) $screen->id;

        return $base === 'site-editor' || str_contains($id, 'site-editor');
    }

    private function adminPhpPageUsesReactAppStack(): bool
    {
        global $pagenow;
        $page = '';
        if (isset($_GET['page']) && \is_string($_GET['page'])) {
            $page = (string) $_GET['page'];
        }

        $decoded = $page === '' ? '' : \rawurldecode($page);
        $pathLikePluginFile = str_contains($decoded, '/') && \preg_match('/\.php$/i', $decoded) === 1;
        $validPage = $page !== '' && !str_starts_with($page, 'fleekdash');

        $screen = \function_exists('get_current_screen') ? \get_current_screen() : null;
        $wooScreen = $screen instanceof \WP_Screen && str_starts_with((string) $screen->id, 'woocommerce');

        $scriptsReady = \wp_script_is('wp-element', 'enqueued')
            && \wp_script_is('wp-components', 'enqueued')
            && \wp_script_is('wp-data', 'enqueued');

        return $pagenow === 'admin.php' && $validPage && $pathLikePluginFile && !$wooScreen && $scriptsReady;
    }
}
