<?php
/**
 * SailWP Co-pilot — full-bleed template for designed pages.
 *
 * Loaded via the template_include filter when a page has _swcp_designed=1.
 * The Opus 4.7 design HTML is output in a clean, theme-neutral shell so it
 * always presents at full viewport width on any host theme (Cadence, Astra,
 * GeneratePress, Divi, FSE, ...).
 *
 * Uses standard wp_head() / wp_footer() so admin bar, the rail, SEO plugins,
 * analytics, and other site-wide hooks still fire — only the visual chrome
 * is replaced.
 */
if (!defined('ABSPATH')) exit;

$swcp_post = get_queried_object();
if (!$swcp_post instanceof WP_Post) return;

// Strip wp:html block markers — design content is raw HTML, no need to
// re-render block markup.
$swcp_content = preg_replace('/<!--\s*\/?wp:html\s*-->/', '', (string) $swcp_post->post_content);

// Inline-edit overlay for logged-in editors only. Visitors get the plain
// design; editors get hover outlines + drag handles + a tiny status chip
// at the bottom-left. The frontend rail (Co-pilot chat) stays mounted
// in parallel via wp_footer().
// v0.24.2: overlay only loads when the URL carries ?swcp_edit=1. Without
// the param the page renders read-only ("view as visitor") even for
// logged-in editors. The row-action "Edit" + admin-bar "Edit Page" both
// route through SailWP_Copilot_Edit_Redirect, which adds the param.
// Joost 2026-05-17: respects WordPress paradigm — Edit vs View are
// genuinely different intents.
// Edit-mode is gated by either ?swcp_edit=1 (explicit click from admin
// row-action) OR the iframe session cookie (set on token-consume, lets
// every navigation inside the dashboard iframe stay in edit-mode without
// each link needing the query param). See class-iframe-bridge.php.
$swcp_edit_requested = class_exists('SailWP_Copilot_Iframe_Bridge')
    ? SailWP_Copilot_Iframe_Bridge::is_edit_mode_requested()
    : (isset($_GET['swcp_edit']) && (string) $_GET['swcp_edit'] === '1');
$swcp_can_edit = $swcp_edit_requested && is_user_logged_in() && current_user_can('edit_post', $swcp_post->ID);
if ($swcp_can_edit) {
    add_action('wp_enqueue_scripts', function () use ($swcp_post) {
        // Cache buster — append filemtime so every edit on disk
        // becomes a fresh URL the browser hasn't seen before. Bumping
        // SAILWP_COPILOT_VERSION alone wasn't enough on at least one
        // 2026-05-15 deploy: Joost's browser kept serving the v0.20.35
        // editor JS even after v0.20.42 shipped, so drag-and-Replace
        // fixes never reached him. filemtime is a per-edit
        // fingerprint, which Cloudflare and the browser both treat as
        // a distinct asset.
        $css_path = SAILWP_COPILOT_DIR . 'assets/css/inline-edit.css';
        $js_path  = SAILWP_COPILOT_DIR . 'assets/js/inline-edit.js';
        $css_ver  = SAILWP_COPILOT_VERSION . '.' . (file_exists($css_path) ? filemtime($css_path) : 0);
        $js_ver   = SAILWP_COPILOT_VERSION . '.' . (file_exists($js_path)  ? filemtime($js_path)  : 0);

        wp_enqueue_style(
            'sailwp-copilot-inline-edit',
            SAILWP_COPILOT_URL . 'assets/css/inline-edit.css',
            [],
            $css_ver
        );
        // wp.media is only loaded for logged-in editors on designed pages
        // — used by the "Replace image" overlay on <img> elements. Extra
        // ~200KB but it's worth it for the familiar WP picker UX (browse
        // library + upload in one place).
        wp_enqueue_media();
        wp_enqueue_script(
            'sailwp-copilot-sortable',
            SAILWP_COPILOT_URL . 'assets/js/Sortable.min.js',
            [],
            '1.15.2',
            true
        );
        wp_enqueue_script(
            'sailwp-copilot-inline-edit',
            SAILWP_COPILOT_URL . 'assets/js/inline-edit.js',
            ['sailwp-copilot-sortable'],
            $js_ver,
            true
        );
        wp_localize_script('sailwp-copilot-inline-edit', 'SailWPInlineEdit', [
            'postId'    => (int) $swcp_post->ID,
            'restUrl'   => esc_url_raw(rest_url('sailwp-copilot/v1/')),
            'restNonce' => wp_create_nonce('wp_rest'),
        ]);
    }, 9000);
}

nocache_headers();
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo('charset'); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?php echo esc_html(wp_get_document_title()); ?></title>
<?php
// Disable WP's own automatic title-tag rendering for this template
// — we already emit a <title> above and the SEO class outputs the
// canonical/og/etc. via wp_head(). Without this, themes that
// declare add_theme_support('title-tag') cause a duplicate <title>
// pair (Joost 2026-05-15 SEO check). Also disable canonical link
// rel emission to avoid the same with our SEO class.
remove_action('wp_head', '_wp_render_title_tag', 1);
// Our SEO class emits its own canonical via wp_head priority 1;
// drop core's rel_canonical so we don't ship two of them.
remove_action('wp_head', 'rel_canonical');
?>
<style>
/* Reset every wrapper a host theme might be applying on its own body
   classes. Astra in particular paints body.ast-separate-container with a
   gray background and constrains the inner area; Kadence does similar
   things via .site, .content-wrap; GeneratePress via .grid-container.
   The Co-pilot's design owns the whole viewport — we override the lot
   with !important so no theme stylesheet wins. */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
    background: #ffffff !important;
    color: #1a1a1a;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, "Helvetica Neue", sans-serif;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    margin: 0 !important;
    padding: 0 !important;
    max-width: none !important;
    width: auto !important;
}
body { min-height: 100vh; }
body.admin-bar { padding-top: 32px !important; }
@media screen and (max-width: 782px) {
    body.admin-bar { padding-top: 46px !important; }
}
/* Strip any host-theme containers that wrap the body in centered/max-width
   layouts (Astra .ast-* wrappers, Kadence .site / .content-wrap, GP
   .grid-container, Twenty* .site / .site-main). The design content is a
   direct child of body in this template, so the selectors below kill any
   stray container rules without touching the design itself. */
body > .ast-container,
body > .site,
body > .site-content,
body > .ast-separate-container,
body > .content-wrap,
body > .grid-container,
body > .site-main {
    max-width: none !important;
    width: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
}
/* The design's outer wp-block-group wrapper. Make sure it spans full
   width even when host theme injects .alignfull rules that subtract
   admin-bar offsets or apply theme padding. */
body > .wp-block-group,
body > .swcp-redesigned-section {
    max-width: none !important;
    width: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
}

/* Theme-neutral site header that floats over the design hero. Logo +
   primary nav rendered from WP APIs (get_custom_logo, wp_nav_menu) so it
   works on any host theme without dragging in theme CSS. */
.swcp-fullpage-header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 999;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    padding: 14px clamp(16px, 4vw, 32px);
    background: rgba(0, 0, 0, 0.32);
    -webkit-backdrop-filter: blur(10px) saturate(140%);
    backdrop-filter: blur(10px) saturate(140%);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    color: #fff;
    font-family: inherit;
    font-size: 14px;
    line-height: 1;
}
body.admin-bar .swcp-fullpage-header { top: 32px; }
@media screen and (max-width: 782px) {
    body.admin-bar .swcp-fullpage-header { top: 46px; }
}
.swcp-fullpage-header a { color: inherit; text-decoration: none; }
.swcp-fullpage-header a:hover { color: #ffd9c9; }
.swcp-header-brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-weight: 600;
    font-size: 15px;
    letter-spacing: 0.01em;
}
.swcp-header-brand .custom-logo,
.swcp-header-brand img {
    max-height: 32px;
    width: auto;
    display: block;
}
.swcp-header-nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    gap: clamp(14px, 2.5vw, 28px);
}
.swcp-header-nav li { margin: 0; }
.swcp-header-nav a {
    display: inline-block;
    padding: 8px 0;
    font-weight: 500;
}
.swcp-header-nav .current-menu-item > a,
.swcp-header-nav .current_page_item > a {
    color: #ffd9c9;
}
@media (max-width: 640px) {
    .swcp-header-nav ul { gap: 14px; flex-wrap: wrap; }
    .swcp-fullpage-header { font-size: 13px; }
}
</style>
<?php wp_head(); ?>
</head>
<?php
// Do NOT call body_class() — host themes (Astra, Kadence, GeneratePress,
// Cadence, Twenty*) hang container-layout classes off the body that their
// stylesheets then constrain via .ast-separate-container, .grid-container,
// .site, .content-wrap, etc. Even with theme stylesheets dequeued we keep
// the body clean so any future plugin-injected CSS can't latch on.
$swcp_body_classes = ['swcp-fullpage'];
if (is_admin_bar_showing()) $swcp_body_classes[] = 'admin-bar';
if (is_user_logged_in())    $swcp_body_classes[] = 'logged-in';
?>
<body class="<?php echo esc_attr(implode(' ', $swcp_body_classes)); ?>">
<?php
if (function_exists('wp_body_open')) {
    wp_body_open();
}

// Theme-neutral site header so visitors can still navigate. Uses
// get_custom_logo() + the site's primary nav menu. Falls back to the
// site title if no logo is set, and tries the first available menu if
// no theme location is named "primary" (common on Twenty* / FSE themes).
$swcp_has_logo = function_exists('has_custom_logo') && has_custom_logo();
$swcp_menu_locations = get_nav_menu_locations();
$swcp_menu_args = [
    'container'  => false,
    'menu_class' => 'swcp-header-menu',
    'depth'      => 1,
    'fallback_cb'=> false,
    'echo'       => false,
];
if (!empty($swcp_menu_locations['primary'])) {
    $swcp_menu_args['theme_location'] = 'primary';
} else {
    $swcp_menus = wp_get_nav_menus();
    if (!empty($swcp_menus)) {
        $swcp_menu_args['menu'] = $swcp_menus[0]->term_id;
    }
}
$swcp_menu_html = wp_nav_menu($swcp_menu_args);
?>
<header class="swcp-fullpage-header">
    <a class="swcp-header-brand" href="<?php echo esc_url(home_url('/')); ?>">
        <?php if ($swcp_has_logo) {
            echo get_custom_logo();
        } else {
            echo esc_html(get_bloginfo('name'));
        } ?>
    </a>
    <?php if ($swcp_menu_html): ?>
        <nav class="swcp-header-nav" aria-label="Site"><?php echo $swcp_menu_html; ?></nav>
    <?php endif; ?>
</header>
<?php
echo $swcp_content;
wp_footer();
?>
</body>
</html>
