<?php
// Ensure project root constant
if (!defined('BEEZUI_ROOT')) {
    define('BEEZUI_ROOT', __DIR__);
}

@ini_set('display_errors', '1');
@ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
// Bootstrap router & routes (idempotent via require_once)
require_once BEEZUI_ROOT . '/components/Autoload.php';
require_once BEEZUI_ROOT . '/components/routes.php';
require_once BEEZUI_ROOT . '/components/index.php';

// Load URL sync configuration from Router (based on routes definitions)
$urlSyncConfig = \Components\Router::getUrlSyncConfig();

// Determine base src for the iframe.
// Priority: query param `base` > data attribute default (BEEZUI_ENTRYPOINT)
$baseSrc = mh_get('base', BEEZUI_ENTRYPOINT, 'string');
// Capture inline HTML for reuse
ob_start();
?>
    <style>
        /* Minimal styles to ensure the iframe fills its wrapper. The host page should provide layout (e.g., flex container). */
        body {
            /*overflow: hidden;*/
        }

        .boxCenterWrapper {
            margin: 0 !important;
        }

        .message_stack_container.hidden {
            display: none !important;
        }

        .frame-wrap {
            position: relative;
            width: 100%;
            /* modified*/
            <?php if (mh_saas()): ?>
            height: 100vh;
            <?php elseif (mh_cfg('MH_PLATFORM') == 'gambio'): ?>
            /* gambio */
            height: calc(100vh - 100px);
            <?php else: ?>
            height: calc(100vh - 150px);
            <?php endif; ?>
            flex: 1 1 auto;
            min-height: 0;
            overflow: hidden;
            background: #ffffff;
        }

        iframe.fullsize {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            border: 0;
        }

        /* Loader overlay */
        .loader {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            background: #ffffff;
            z-index: 10;
            opacity: 1;
            visibility: visible;
            transition: opacity 180ms ease, visibility 0s linear 0s;
            will-change: opacity, visibility;
        }

        .loader.hidden {
            opacity: 0;
            visibility: hidden;
            pointer-events: none;
            transition: opacity 180ms ease, visibility 0s linear 180ms;
        }

        .loader .spinner {
            width: 18px;
            height: 18px;
            border: 2px solid hsl(218, 18%, 27%);
            border-top-color: #ffffff;
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }

        .loader .loader-text {
            font-family: Arial, Helvetica, sans-serif;
            color: #374151;
            font-size: 14px;
        }

        @keyframes spin {
            to {
                transform: rotate(360deg);
            }
        }

        @media (prefers-reduced-motion: reduce) {
            .loader .spinner {
                animation: none;
            }
        }
    </style>

    <div class="frame-wrap">
        <div id="frame-loader" class="loader" role="status" aria-live="polite" aria-label="Loading">
            <div class="spinner" aria-hidden="true"></div>
        </div>
        <iframe id="app-iframe" class="fullsize" src="about:blank"
                data-base-src="<?php echo htmlspecialchars($baseSrc, ENT_QUOTES, 'UTF-8'); ?>"
                title="App Frame"></iframe>
    </div>
    <script>
        (function () {
            const iframe = document.getElementById('app-iframe');
            const loader = document.getElementById('frame-loader');
            const DEFAULT_ENTRYPOINT = <?php echo json_encode(BEEZUI_ENTRYPOINT); ?>;
            const baseSrc = iframe.getAttribute('data-base-src') || DEFAULT_ENTRYPOINT;
            const urlSyncConfig = <?php echo json_encode($urlSyncConfig, JSON_UNESCAPED_SLASHES); ?>;
            const TAB_PARAM = <?php echo json_encode(\Components\Router::tabParam()); ?>;

            function getAllowedKeys(route) {
                const common = Array.isArray(urlSyncConfig.common) ? urlSyncConfig.common : [];
                const per = (urlSyncConfig.routeParams && urlSyncConfig.routeParams[route]) ? urlSyncConfig.routeParams[route] : [];
                return new Set([...common, ...per]);
            }

            function scrubRouteSpecific(parentUrl, keepRoute) {
                if (!urlSyncConfig.routeParams) return;
                const allowed = getAllowedKeys(keepRoute);
                Object.entries(urlSyncConfig.routeParams).forEach(([route, keys]) => {
                    if (route === keepRoute) return;
                    (keys || []).forEach((k) => {
                        if (!allowed.has(k)) {
                            parentUrl.searchParams.delete(k);
                        }
                    });
                });
            }

            function filterApplyParamsToParent(childParams, route, parentUrl) {
                const allowed = getAllowedKeys(route);
                scrubRouteSpecific(parentUrl, route);
                childParams.forEach((value, key) => {
                    if (allowed.has(key)) parentUrl.searchParams.set(key, value);
                });
                return parentUrl;
            }

            function initIframe() {
                const parentUrl = new URL(window.location.href);
                const initialRoute = (parentUrl.searchParams.get(TAB_PARAM) || 'dashboard').toLowerCase();
                const srcUrl = new URL(baseSrc, window.location.origin + window.location.pathname);
                const allowed = getAllowedKeys(initialRoute);
                parentUrl.searchParams.forEach((value, key) => {
                    if (allowed.has(key)) srcUrl.searchParams.set(key, value);
                });
                if (!srcUrl.searchParams.get(TAB_PARAM)) srcUrl.searchParams.set(TAB_PARAM, initialRoute);
                iframe.src = srcUrl.toString();
            }

            function handleIframeLoad() {
                let childUrl;
                try {
                    const childLoc = iframe.contentWindow.location;
                    // Ignore the iframe bootstrap load for the initial about:blank document.
                    if (!childLoc || childLoc.href === 'about:blank') return;
                    childUrl = new URL(childLoc.href);
                } catch (e) {
                    // Cross-origin: cannot read iframe location; still hide loader on load.
                }

                // Hide loader once iframe reports loaded (fires for same- or cross-origin)
                if (loader) loader.classList.add('hidden');

                if (!childUrl) return;

                try {
                    const route = (childUrl.searchParams.get(TAB_PARAM) || 'dashboard').toLowerCase();
                    const parentUrl = new URL(window.location.href);
                    const before = parentUrl.toString();
                    const afterUrl = filterApplyParamsToParent(childUrl.searchParams, route, parentUrl);
                    const after = afterUrl.toString();
                    if (after !== before) {
                        window.history.replaceState(null, '', after);
                    }
                } catch (e) {
                    // Cross-origin: cannot read iframe location; skip syncing
                }
            }

            document.addEventListener('DOMContentLoaded', function () {
                initIframe();
            });

            iframe.addEventListener('load', handleIframeLoad);

            window.addEventListener('message', function (event) {
                try {
                    if (!iframe.contentWindow || event.source !== iframe.contentWindow) return;
                    const data = event.data || {};
                    // Handle URL sync message from iframe
                    if (data.type === 'iframe-location-update') {
                        const parentUrl = new URL(window.location.href);
                        const childParams = new URLSearchParams(data.search || '');
                        const route = (data.route || childParams.get(TAB_PARAM) || 'dashboard').toLowerCase();
                        const before = parentUrl.toString();
                        const afterUrl = filterApplyParamsToParent(childParams, route, parentUrl);
                        const next = afterUrl.toString();
                        if (next !== before) {
                            window.history.replaceState(null, '', next);
                        }
                        return;
                    }

                    // Optional top-level navigation request from inside the iframe
                    if (data.type === 'mb:navigateTop') {
                        const url = (data && data.url) ? String(data.url) : '';
                        const replace = !!(data && data.replace);
                        if (url) {
                            try {
                                if (replace && typeof window.top.location.replace === 'function') {
                                    window.top.location.replace(url);
                                } else {
                                    window.top.location.href = url;
                                }
                            } catch (e2) {
                                // Fallback to current window navigation
                                if (replace && typeof window.location.replace === 'function') {
                                    window.location.replace(url);
                                } else {
                                    window.location.href = url;
                                }
                            }
                        }
                        return;
                    }
                } catch (e) { /* no-op */
                }
            });
        })();
    </script>
<?php
$BEEZUI_WRAPPER_HTML = ob_get_clean();
echo $BEEZUI_WRAPPER_HTML;