<?php
/**
 * Tool: apply_page_design
 *
 * Step 2 of the custom design workflow. After the user has reviewed the
 * preview from design_page_preview and approved it, this swaps the new
 * design into the ORIGINAL page (same ID, same slug, same SEO, same
 * internal links). The preview draft is then trashed so it stays
 * recoverable for a while if anything goes wrong.
 */
if (!defined('ABSPATH')) exit;

function swcp_tool_apply_page_design($input, $ctx) {
    $preview_id = isset($input['preview_id']) ? (int) $input['preview_id'] : 0;
    if (!$preview_id) {
        return ['ok' => false, 'message' => 'I lost track of which preview to apply. Tell me to design a fresh preview and try again.'];
    }
    $preview = get_post($preview_id);
    if (!$preview || $preview->post_type !== 'page') {
        return ['ok' => false, 'message' => 'That preview is no longer here. Tell me to design a fresh one and try again.'];
    }
    if (!get_post_meta($preview_id, '_swcp_is_preview', true)) {
        return ['ok' => false, 'message' => 'That page is not a co-pilot preview. I can only apply previews I created.'];
    }
    $original_id = (int) get_post_meta($preview_id, '_swcp_preview_of', true);
    if (!$original_id) {
        return ['ok' => false, 'message' => 'I lost the link between this preview and the original page.'];
    }
    $original = get_post($original_id);
    if (!$original) {
        return ['ok' => false, 'message' => 'The original page is gone. Nothing to apply the design to.'];
    }

    $compat = swcp_check_builder_compat($original->ID);
    if ($compat !== null) return $compat;

    // Capture BEFORE-html so the cloud activity feed can offer a
    // one-click restore. We grab it now, before wp_update_post mutates
    // the row.
    $before_html = (string) $original->post_content;

    // Self-contained envelope for HTML designs only. Blocks-kind previews
    // (redesign_page) keep rendering through the host theme, so wrapping
    // them would double-wrap them with a viewport-escape they don't need.
    $preview_kind = (string) get_post_meta($preview_id, '_swcp_preview_kind', true);
    $content_to_save = ($preview_kind === 'blocks')
        ? $preview->post_content
        : swcp_wrap_self_contained($preview->post_content);

    // Swap content. wp_update_post creates a revision automatically, so
    // the user can still revert via Editor → Revisions.
    $update = wp_update_post([
        'ID'           => $original_id,
        'post_content' => $content_to_save,
    ], true);
    if (is_wp_error($update)) {
        return ['ok' => false, 'message' => 'Could not apply the design to the live page. The preview is still there.'];
    }

    // Verify the write actually persisted. wp_update_post can return a
    // non-error post ID even when a wp_insert_post_data filter (security
    // plugin, content-rewrite plugin, kses sanitiser without unfiltered_html
    // capability) silently rewrote or dropped the content. Without this
    // check, the apply chip would say "Live ✓" while the live page kept
    // its old content — exactly the bug reported on Apr 30 2026.
    clean_post_cache($original_id);
    $verify = get_post($original_id);
    if (!$verify || trim((string) $verify->post_content) !== trim((string) $content_to_save)) {
        return [
            'ok'      => false,
            'message' => 'The save returned without an error, but the page content did not change. A security plugin or content filter may have blocked it. The preview is still available — open it in the editor to copy the design over manually.',
            'preview_id'  => (int) $preview_id,
            'preview_url' => add_query_arg('swcp_render_preview', $preview_id, home_url('/')),
        ];
    }

    // Fire-and-forget: ship the BEFORE-snapshot to the proxy so it can
    // Haiku-summarise the change and offer a restore button in the
    // cloud activity feed. We don't block the apply on this — if the
    // proxy is slow/unreachable, the apply still succeeded locally.
    if (function_exists('swcp_log_page_version')) {
        swcp_log_page_version($original_id, $before_html, (string) $content_to_save);
    }

    // Mark the original page as "co-pilot designed" so the front-end
    // theme-override renderer takes over and presents it full-bleed.
    // ONLY for HTML-based previews from design_page_preview / iterate_page_design.
    // Blocks-kind previews (from redesign_page) must keep rendering through
    // the host theme — that's the whole point of "gentle clean up". Setting
    // _swcp_designed=1 on those would strip the theme stylesheets and ruin
    // the design.
    //
    // CRITICAL: if a page previously got an HTML design (so it already has
    // _swcp_designed=1) and the user now applies a blocks-kind redesign on
    // top, we MUST clear the old meta. Otherwise the fullpage renderer
    // keeps stripping theme CSS from a page that is now block-rendered
    // and depends on the theme for layout.
    if ($preview_kind === 'blocks') {
        delete_post_meta($original_id, '_swcp_designed');
    } else {
        update_post_meta($original_id, '_swcp_designed', 1);
    }

    // If the page was auto-created as Home (via swcp_resolve_page) and the
    // site still uses the blog as front, promote it to the static front
    // page now that real content lives on it. Surprises nobody who already
    // has a homepage configured.
    if (
        get_post_meta($original_id, '_swcp_auto_created_home', true)
        && get_option('show_on_front') !== 'page'
    ) {
        update_option('show_on_front', 'page');
        update_option('page_on_front', $original_id);
    }

    // Trash the preview (recoverable for ~30 days; won't show up anywhere public).
    wp_trash_post($preview_id);

    if (function_exists('swcp_log_remote_event')) {
        swcp_log_remote_event('preview_applied', ['original_id' => $original_id]);
    }

    return [
        'ok'         => true,
        'message'    => 'Live ✓',
        'original_id'=> $original_id,
        'view_url'   => swcp_view_url_for($original_id),
        'edit_url'   => swcp_edit_url_for($original_id),
    ];
}
