<?php
declare(strict_types=1);

if (!defined('ABSPATH')) { exit; }

/**
 * Code (raw HTML/JS) element renderer (shared).
 *
 * Phase 1, step 11 of the renderer-unification refactor.
 *
 * The `code` element ships raw HTML/CSS/JS authored in the builder.
 * Frontend trusts the content and echoes it (capability-gated on WP;
 * unconditional on standalone where admin auth gates the builder
 * itself). Editor renders a styled preview chrome that shows the
 * authored content with optional placement indicator (head/footer/
 * body/inline). Pre-extraction the editor's case had a copy-paste
 * artifact where the `footer` placement branch appeared twice (the
 * second elseif was unreachable). Removed.
 *
 * Pre-extraction differences:
 *
 *   - **Capability gate**: frontend checks current_user_can
 *     ('unfiltered_html') on WP, or treats standalone as always-on.
 *     Editor doesn't gate (the builder itself is auth-gated).
 *   - **PHP open-tag strip**: frontend defense-in-depth strips `<?`
 *     before echo. Editor doesn't (preview always shows literal).
 *     → Unified to strip in both contexts. Defense in depth applies
 *     to editor too — if a sanitization slip somehow lets PHP tags
 *     into the preview HTML, they shouldn't execute as PHP in the
 *     preview iframe.
 *   - **head placement**: frontend breaks early (head code is
 *     handled by the page bootstrap, not the inline renderer).
 *     Editor renders a "Injected into <head>" chrome card so the
 *     user sees the block in their canvas. Preserved.
 *   - **footer placement**: same pattern — frontend breaks (page
 *     bootstrap handles it), editor shows chrome.
 *   - **Empty code**: frontend renders nothing. Editor shows a
 *     "Code Block" placeholder card. Preserved.
 *
 * @param array|object $el       Element node.
 * @param array        $settings Element settings.
 * @param string       $context  'frontend' or 'editor'.
 *
 * @return string Inner HTML.
 */
function impulse_element_render_code($el, array $settings, string $context): string {
    if (is_object($el)) $el = (array) $el;
    $isEditor = ($context === 'editor');

    $code      = (string) ($settings['code']      ?? '');
    $placement = (string) ($settings['placement'] ?? ($isEditor ? 'body' : 'inline'));

    // Strip PHP open tags — defense in depth in both contexts.
    $code = preg_replace('/<\?(?:php|=)?/i', '', $code);

    

    // WP.org free build: the Code element is excluded (no arbitrary code
    // insertion, WP.org guideline). Everything above is PRO-stripped from the
    // free zip; return an inert, escaped placeholder so any page still
    // referencing a code block degrades gracefully instead of fataling.
    // Fully functional on standalone/Pro. WP.org round 4.
    return $isEditor
        ? '<div class="impulse-html" style="padding:16px;text-align:center;color:#aaa;font-size:12px">Code block</div>'
        : '';
}
