<?php
/**
 * Server-side render for blocksify/container.
 *
 * Container is fully server-rendered per FOUNDATION §9.5 — `save.js`
 * returns bare `<InnerBlocks.Content />` and this file builds the
 * entire frontend markup from `$attributes`:
 *
 *   <{tag} class="bsy-container-{uid}" [id="…"]>
 *     [image scroll layer]
 *     [per-device video layers]
 *     [overlay div]
 *     [shape edge top]
 *     [shape edge bottom]
 *     {inner blocks via $content}
 *   </{tag}>
 *
 * Container's wrapper IS the inner-blocks container directly — no
 * `__inner` nested div like Section. Children land inside the
 * wrapper at flex flow. See `src/blocks/container/style.css` for the
 * flex defaults; per-instance flex CSS (direction / justify / align /
 * gap) emits via the per-instance pipeline.
 *
 * Per-instance CSS emit lives in `Blocksify_CSS_Pipeline` (single-
 * handle inline `<style>` pool at `wp_enqueue_scripts`). This file
 * owns DOM only — no CSS rules emitted here.
 *
 * @package Blocksify
 *
 * @var array    $attributes Block attributes.
 * @var string   $content    Serialized inner blocks (from
 *                           `<InnerBlocks.Content />` slot).
 * @var WP_Block $block      Parsed block instance.
 */

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

// Container shares the scroll-effect runtime handle with Section —
// same `blocksify-section-scroll-effect` registration covers both.
// Gate is the `effect` value (parallax / zoom), mirroring
// `Blocksify_Background_Render::is_scroll_active()` + JS
// `isScrollEffectActive()` — no separate `enabled` flag.
$scroll_bag = isset( $attributes['backgroundScrollEffect'] ) && is_array( $attributes['backgroundScrollEffect'] )
	? $attributes['backgroundScrollEffect']
	: null;
if ( $scroll_bag
	&& isset( $scroll_bag['effect'] )
	&& in_array( $scroll_bag['effect'], array( 'parallax', 'zoom' ), true )
	&& wp_script_is( 'blocksify-section-scroll-effect', 'registered' ) ) {
	wp_enqueue_script( 'blocksify-section-scroll-effect' );
}

// Resolve wrapper tag — whitelist mirrors `ALLOWED_TAGS` in
// `src/blocks/container/save.js` (defensive resolve for stale
// attributes from before the whitelist tightening). Default 'div'.
$allowed_tags = array( 'div', 'section', 'article', 'header', 'footer', 'main', 'aside', 'nav' );
$tag          = isset( $attributes['tagName'] ) && in_array( $attributes['tagName'], $allowed_tags, true )
	? $attributes['tagName']
	: 'div';

// Per-instance class only — FOUNDATION §11 forbids hand-emitting
// `wp-block-blocksify-*` on frontend. Editor still gets that class
// via `useBlockProps()` for editor-only chrome targeting; the block's
// `supports.className: false` flag strips it from frontend output
// declaratively. Static CSS anchors via `[class*="bsy-container-"]`
// attribute selector — no shared base class needed.
// `supports.align: false` so no `align*` class either.
//
// `attributes.className` carries user-authored "Additional CSS
// classes" from Inspector → Advanced (`supports.customClassName`
// defaults to true and isn't opted out). In hybrid save the field
// was auto-merged by `useBlockProps.save`; pure-dynamic save has no
// wrapper so render.php merges manually — cf. Button's render.php for
// the same pattern.
$uid        = isset( $attributes['uid'] ) ? $attributes['uid'] : '';
$user_class = isset( $attributes['className'] ) ? trim( (string) $attributes['className'] ) : '';
$class_set  = array();
if ( '' !== $uid ) {
	$class_set[] = 'bsy-container-' . $uid;
}
if ( '' !== $user_class ) {
	$class_set[] = $user_class;
}
$class_attr = implode( ' ', $class_set );

// Custom HTML id — `supports.anchor: true`.
$id_attr = isset( $attributes['anchor'] ) && '' !== $attributes['anchor']
	? ' id="' . esc_attr( $attributes['anchor'] ) . '"'
	: '';

// Background DOM layer order mirrors save.js (siblings of inner
// content, all positioned absolute so DOM order is z-stack-irrelevant;
// z-index decides visual stack).
$scroll_effect = isset( $attributes['backgroundScrollEffect'] ) ? $attributes['backgroundScrollEffect'] : null;
$bg_image      = Blocksify_Background_Render::image(
	isset( $attributes['backgroundImage'] ) ? $attributes['backgroundImage'] : null,
	array( 'scrollEffect' => $scroll_effect )
);
$bg_videos = Blocksify_Background_Render::videos(
	$attributes,
	array( 'scrollEffect' => $scroll_effect )
);
$show_overlay =
	Blocksify_Background_Render::has_overlay_content( isset( $attributes['backgroundOverlay'] ) ? $attributes['backgroundOverlay'] : null )
	|| Blocksify_Background_Render::has_overlay_content( isset( $attributes['backgroundOverlayTablet'] ) ? $attributes['backgroundOverlayTablet'] : null )
	|| Blocksify_Background_Render::has_overlay_content( isset( $attributes['backgroundOverlayMobile'] ) ? $attributes['backgroundOverlayMobile'] : null );
$bg_overlay = Blocksify_Background_Render::overlay( $show_overlay );
$shape      = isset( $attributes['backgroundShape'] ) && is_array( $attributes['backgroundShape'] )
	? $attributes['backgroundShape']
	: array();
$shape_top    = Blocksify_Background_Render::shape_edge( 'top', isset( $shape['top'] ) ? $shape['top'] : null );
$shape_bottom = Blocksify_Background_Render::shape_edge( 'bottom', isset( $shape['bottom'] ) ? $shape['bottom'] : null );

if ( isset( $_GET['blocksify_debug'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
	$debug_css = Blocksify_CSS_Generator::generate_block_css( 'blocksify/container', $attributes );
	echo "\n<!-- Blocksify Container CSS:\n" . esc_html( $debug_css ) . "\n-->\n";
}

// Build markup. `$content` is the serialized inner-blocks markup.
echo '<' . $tag . ' class="' . esc_attr( $class_attr ) . '"' . $id_attr . '>';
echo $bg_image; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $bg_videos; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $bg_overlay; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $shape_top; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $shape_bottom; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '</' . $tag . '>';
