<?php

namespace FleekDash\Core;

defined('ABSPATH') || exit;

use FleekDash\Core\API;
use FleekDash\Services\ServiceWorkerService;
use FleekDash\Services\Theme\ThemeStylesService;

/**
 * Orchestrates FleekDash plugin initialization phases.
 * Extracted from fleekdashInit() to satisfy S138 (function length) and S3776 (cognitive complexity).
 */
class FleekDashBootstrap
{
    private const WP_ADMIN_PATH_PREFIX = '/wp-admin/';
    public static function registerRestApis(): void
    {
        add_action('rest_api_init', function () {
            $formatter_file = FLEEKDASH_PLUGIN_DIR . 'includes/API/AdminDataFormatter.php';
            if (file_exists($formatter_file)) {
                require_once $formatter_file;
            }

            $menu_data_api_file = FLEEKDASH_PLUGIN_DIR . 'includes/API/MenuDataAPI.php';
            if (file_exists($menu_data_api_file)) {
                require_once $menu_data_api_file;
                $menu_data_api = new \FleekDash\API\MenuDataAPI();
                $menu_data_api->registerRoutes();
            }

            $toolbar_data_api_file = FLEEKDASH_PLUGIN_DIR . 'includes/API/ToolbarDataAPI.php';
            if (file_exists($toolbar_data_api_file)) {
                require_once $toolbar_data_api_file;
                $toolbar_data_api = new \FleekDash\API\ToolbarDataAPI();
                $toolbar_data_api->registerRoutes();
            }
        }, 5);
    }

    public static function bootstrapClassicMode(): void
    {
        if (!is_admin()) {
            return;
        }

        self::setupClassicModeIframeAndInterceptor();
        self::addClassicModeAdminNotice();
        self::addClassicModeFooterScripts();
        self::addClassicModeRedirectFilter();
        self::addClassicModeFormInterceptor();

        $api = new API();
        $api->init();

        add_action('rest_api_init', function () {
            $routes_file = FLEEKDASH_PLUGIN_DIR . 'includes/Routes/Api.php';
            if (file_exists($routes_file)) {
                if (!defined('FLEEKDASH_API_NAMESPACE')) {
                    define('FLEEKDASH_API_NAMESPACE', 'fleekdash/v1');
                }
                require_once $routes_file;
            }
        }, 5);
    }

    public static function configureErrorReporting(): void
    {
        $is_wp_debug = defined('WP_DEBUG') && WP_DEBUG;
        $wp_debug_display = defined('WP_DEBUG_DISPLAY') && WP_DEBUG_DISPLAY;
        $is_fleekdash_context = self::isFleekDashRequestContext();
        $should_display_errors = $is_wp_debug && $wp_debug_display;

        // Never leak notices/warnings into FleekDash screens (SPA shell).
        if ($is_fleekdash_context) {
            \ini_set('display_errors', '0');
            \ini_set('display_startup_errors', '0');
        } else {
            // Respect wp-config WP_DEBUG_DISPLAY (e.g. classic iframe: update-core.php).
            \ini_set('display_errors', $should_display_errors ? '1' : '0');
            \ini_set('display_startup_errors', $should_display_errors ? '1' : '0');
        }

        ErrorHandler::applyGlobalReportingMask();
    }

    private static function isFleekDashRequestContext(): bool
    {
        $page = isset($_GET['page']) ? \sanitize_text_field((string) \wp_unslash($_GET['page'])) : '';
        if ($page !== '' && \strpos($page, 'fleekdash') === 0) {
            return true;
        }

        $request_uri = isset($_SERVER['REQUEST_URI']) ? (string) $_SERVER['REQUEST_URI'] : '';
        if ($request_uri !== '' && \strpos($request_uri, '/wp-json/fleekdash/') !== false) {
            return true;
        }

        $rest_request = isset($_GET['rest_route']) ? (string) $_GET['rest_route'] : '';
        return $rest_request !== '' && \strpos($rest_request, '/fleekdash/') === 0;
    }

    public static function initializeCoreServices(): void
    {
        \FleekDash\Controllers\LicenseController::getInstance();

        try {
            if (class_exists('FleekDash\\Core\\IntegrationManager')) {
                $integration_manager = IntegrationManager::getInstance();
                if ($integration_manager->isActive('analytics')) {
                    \FleekDash\Services\AnalyticsTrackingService::getInstance();
                }
            }
        } catch (\Throwable $e) {
            if (defined('WP_DEBUG') && WP_DEBUG && \function_exists('fleekdash_log_error')) {
                \fleekdash_log_error('FleekDash: Failed to initialize AnalyticsTrackingService conditionally: ' . $e->getMessage());
            }
        }

        try {
            new ServiceWorkerService();
        } catch (\Throwable $e) {
            if (defined('WP_DEBUG') && WP_DEBUG && \function_exists('fleekdash_log_error')) {
                \fleekdash_log_error('FleekDash: Failed to initialize ServiceWorkerService: ' . $e->getMessage());
            }
        }

        new \FleekDash\Admin\Iframe(); // NOSONAR S1848 - constructor registers hooks
        \FleekDash::get_instance();

        global $fleekdash_core;
        $fleekdash_core = new \FleekDash();
    }

    public static function initializeManagersAndFeatures(): void
    {
        require_once FLEEKDASH_PLUGIN_DIR . 'includes/Core/ModuleManager.php';
        require_once FLEEKDASH_PLUGIN_DIR . 'includes/Interfaces/ModuleInterface.php';
        require_once FLEEKDASH_PLUGIN_DIR . 'includes/Core/BaseModule.php';

        ModuleManager::getInstance();

        require_once FLEEKDASH_PLUGIN_DIR . 'includes/Core/IntegrationManager.php';
        IntegrationManager::getInstance()->init();

        \FleekDash\Core\AvatarManager::getInstance()->init();
        \FleekDash\Core\I18nManager::getInstance();
        ThemeStylesService::init();
        \FleekDash\Core\FeaturesManager::getInstance();
    }

    public static function initializeGrowthMeter(): void
    {
        ob_start();
        try {
            $growth_service = new \FleekDash\Services\SiteGrowthMeterService();
            $growth_service->registerTrackingHooks();

            if (\FleekDash\Models\SiteGrowthEvent::tableExists()) {
                fleekdash_log_debug('Site Growth Meter: Tracking hooks registered');
            } else {
                fleekdash_log_debug('Site Growth Meter: Tables not ready yet (activation in progress)');
            }
        } catch (\Throwable $e) {
            if (function_exists('fleekdash_log_error')) {
                fleekdash_log_error('Site Growth Meter initialization error: ' . $e->getMessage());
            }
        }
        ob_end_clean();
    }

    public static function initializeUpdateChecker(): void
    {
        try {
            $update_checker_file = FLEEKDASH_PLUGIN_DIR . 'includes/Core/UpdateChecker.php';
            if (file_exists($update_checker_file)) {
                require_once $update_checker_file;
            }

            if (class_exists('FleekDash\\Core\\UpdateChecker')) {
                $plugin_file = plugin_basename(FLEEKDASH_PLUGIN_FILE);
                $current_version = defined('FLEEKDASH_VERSION') ? FLEEKDASH_VERSION : '2.1.4';
                $update_checker = new \FleekDash\Core\UpdateChecker($plugin_file, $current_version);
                $update_checker->init();
                fleekdash_log('UpdateChecker initialized successfully', 'info');
            }
        } catch (\Exception $e) {
            fleekdash_log('UpdateChecker initialization failed: ' . $e->getMessage(), 'error');
        }
    }

    private static function setupClassicModeIframeAndInterceptor(): void
    {
        try {
            new \FleekDash\Admin\Iframe(); // NOSONAR S1848 - constructor registers hooks
            $interceptor = new \FleekDash\Admin\Interceptor();
            $interceptor->bootstrap();
        } catch (\Throwable $e) {
            if (defined('WP_DEBUG') && WP_DEBUG) {
                error_log('FleekDash: Failed to initialize Iframe/Interceptor in classic mode: ' . $e->getMessage());
            }
        }
    }

    private static function addClassicModeAdminNotice(): void
    {
        add_action('admin_notices', function () {
            $used_param = '';
            $disable_params = [
                'wp' => 'true',
                'fleekdash' => 'off',
                'fleek-disable' => '1',
                'classic-wp' => '1'
            ];

            foreach ($disable_params as $param => $value) {
                if (isset($_GET[$param]) && $_GET[$param] === $value) {
                    $used_param = $param;
                    break;
                }
            }

            $base_url = admin_url('admin.php');
            $enable_url = add_query_arg('page', 'fleekdash', $base_url);
            $enable_url = add_query_arg('fleekdash', 'on', $enable_url);

            echo '<div class="notice notice-warning is-dismissible" style="border-left-color: #f59e0b;">';
            echo '<p><strong>FleekDash:</strong> Classic WordPress mode active in this tab ';
            echo $used_param ? 'via <code>?' . esc_html($used_param) . '</code> parameter. ' : 'via localStorage. ';
            echo 'You are viewing the native WordPress admin interface.<br>';
            echo '<div style="margin-top: 8px;">';
            echo '<a href="' . esc_url($enable_url) . '" class="button button-primary" style="margin-right: 10px;">Disable Classic Mode</a>';
            echo '<a href="' . esc_url(admin_url('admin.php?page=fleekdash')) . '" class="button button-secondary fleekdash-new-tab-link" target="_blank">Open FleekDash in New Tab</a>';
            echo '</div>';
            echo '<small style="color: #666; margin-top: 5px; display: block;">Tip: You can have both interfaces open simultaneously in different browser tabs</small>';
            echo '</p></div>';

            echo '<style>
            .notice.notice-warning[style*="border-left-color: #f59e0b"] {
                background: linear-gradient(90deg, rgba(245, 158, 11, 0.1) 0%, rgba(245, 158, 11, 0.05) 100%);
                border-left: 4px solid #f59e0b;
                animation: slideInFromTop 0.3s ease-out;
            }
            @keyframes slideInFromTop {
                from { opacity: 0; transform: translateY(-20px); }
                to { opacity: 1; transform: translateY(0); }
            }
            .notice .button { transition: all 0.2s ease; }
            .notice .button:hover { transform: translateY(-1px); box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
            </style>';
        });
    }

    private static function addClassicModeFooterScripts(): void
    {
        add_action('admin_footer', function () {
            $version = defined('FLEEKDASH_VERSION') ? FLEEKDASH_VERSION : '1.0.0';
            echo '<script src="' . esc_url(plugin_dir_url(FLEEKDASH_PLUGIN_FILE) . 'assets/js/tab-session-manager.js') . '?ver=' . esc_attr($version) . '"></script>';

            echo '<script>
            (function() {
                try {
                    if (window.top !== window) return;
                    if (new URLSearchParams(window.location.search).get("fleekdash-frame") === "1") return;
                    if (document.cookie.indexOf("fleekdash_classic_admin=1") === -1) return;

                    var clearUrl = "' . esc_js(admin_url('index.php?fleekdash=on&fleekdash_auto=1')) . '";
                    var isNavigating = false;
                    var clearTimeout = null;

                    function clearClassic() {
                        if (isNavigating) return;
                        try {
                            if (navigator.sendBeacon) {
                                navigator.sendBeacon(clearUrl, new Blob([], { type: "text/plain" }));
                                return;
                            }
                            fetch(clearUrl, { method: "POST", credentials: "include", keepalive: true });
                        } catch (e) { /* silent */ }
                    }

                    var done = false;
                    function once() {
                        if (!done) { done = true; clearTimeout = setTimeout(clearClassic, 100); }
                    }

                    window.addEventListener("beforeunload", function() {
                        isNavigating = true;
                        if (clearTimeout) clearTimeout(clearTimeout);
                    });
                    window.addEventListener("load", function() { setTimeout(function() { isNavigating = false; }, 200); });
                    window.addEventListener("pagehide", once, { capture: true });
                    document.addEventListener("visibilitychange", function() {
                        if (document.visibilityState === "hidden" && !isNavigating) once();
                    }, { capture: true });
                } catch (e) { /* silent */ }
            })();
            </script>';

            if (defined('WP_DEBUG') && WP_DEBUG) {
                echo '<script>
                console.log("FleekDash Keyboard Shortcuts:");
                console.log("  Ctrl/Cmd + K = Open Command Palette (search & navigation)");
                console.log("  Ctrl/Cmd + Space = Toggle fullscreen mode");
                console.log("  Ctrl/Cmd + Shift + F = Toggle FleekDash mode");
                console.log("  Ctrl/Cmd + Shift + N = Open FleekDash in new tab");
                </script>';
            }
        });
    }

    private static function addClassicModeRedirectFilter(): void
    {
        add_filter('wp_redirect', function ($location, $status = 302) { // NOSONAR S1172 - $status required by wp_redirect filter
            if (!is_admin() || !$location) {
                return $location;
            }

            if (!self::shouldMaintainClassicMode()) {
                return $location;
            }

            return self::appendClassicModeToRedirect($location);
        }, 10, 2);
    }

    private static function shouldMaintainClassicMode(): bool
    {
        if (isset($_GET['tab_id']) || isset($_POST['tab_id']) ||
            isset($_GET['fleekdash_classic_mode']) || isset($_POST['fleekdash_classic_mode'])) {
            return true;
        }

        $disable_params = ['wp' => 'true', 'fleekdash' => 'off', 'fleek-disable' => '1', 'classic-wp' => '1'];
        foreach ($disable_params as $param => $value) {
            if (isset($_GET[$param]) && $_GET[$param] === $value) {
                return true;
            }
        }

        return false;
    }

    private static function isWpAdminRedirectLocation(string $location): bool
    {
        if (strpos($location, self::WP_ADMIN_PATH_PREFIX) !== false) {
            return true;
        }

        $adminPrefix = \admin_url();
        return $adminPrefix !== '' && strpos($location, $adminPrefix) === 0;
    }

    /**
     * wp_redirect often emits relative /wp-admin/... locations (site editor, block editor).
     * Rebuilding with parse_url() without a host produces broken ":///wp-admin/..." URLs.
     */
    private static function resolveClassicModeRedirectLocation(string $location): string
    {
        $parsed = parse_url($location);
        if (!empty($parsed['host'])) {
            return $location;
        }

        $path = $parsed['path'] ?? $location;
        if (strpos($path, self::WP_ADMIN_PATH_PREFIX) === 0) {
            $underAdmin = ltrim(substr($path, strlen(self::WP_ADMIN_PATH_PREFIX)), '/');
            $absolute = \admin_url($underAdmin);
        } elseif (strpos($path, '/') === 0) {
            $absolute = \home_url($path);
        } else {
            $absolute = \admin_url($path);
        }

        if (!empty($parsed['query'])) {
            parse_str($parsed['query'], $queryParams);
            foreach ($queryParams as $key => $value) {
                $absolute = \add_query_arg($key, $value, $absolute);
            }
        }

        if (!empty($parsed['fragment'])) {
            $absolute .= '#' . $parsed['fragment'];
        }

        return $absolute;
    }

    private static function appendClassicModeToRedirect(string $location): string
    {
        if (!self::isWpAdminRedirectLocation($location)) {
            return $location;
        }

        $absolute = self::resolveClassicModeRedirectLocation($location);
        $args = ['fleekdash_classic_mode' => '1'];
        $tab_id = self::getClassicModeParam('tab_id');
        if ($tab_id !== '') {
            $args['tab_id'] = $tab_id;
        }

        return \add_query_arg($args, $absolute);
    }

    private static function addClassicModeFormInterceptor(): void
    {
        add_action('admin_init', function () {
            if (
                ($_SERVER['REQUEST_METHOD'] ?? '') === 'POST' &&
                (isset($_POST['tab_id']) || isset($_POST['fleekdash_classic_mode']))
            ) {
                if (isset($_POST['tab_id'])) {
                    $_GET['tab_id'] = self::getClassicModeParam('tab_id', 'post');
                }
                if (isset($_POST['fleekdash_classic_mode'])) {
                    $_GET['fleekdash_classic_mode'] = self::getClassicModeParam('fleekdash_classic_mode', 'post');
                }
            }
        });
    }

    private static function getClassicModeParam(string $key, string $source = 'request'): string
    {
        $value = '';
        if (($source === 'request' || $source === 'get') && isset($_GET[$key])) {
            $value = \sanitize_text_field((string) \wp_unslash($_GET[$key]));
        } elseif (($source === 'request' || $source === 'post') && isset($_POST[$key])) {
            $value = \sanitize_text_field((string) \wp_unslash($_POST[$key]));
        }

        return $value;
    }
}
