<?php
/**
 * Server-side render for blocksify/icon.
 *
 * Icon is a fully dynamic block — `save.js` returns `null`, so saved
 * markup is just the comment delimiter and this file builds the entire
 * frontend HTML from `$attributes`. Per-instance CSS comes from
 * `Blocksify_CSS_Pipeline` (single-handle pool at `wp_enqueue_scripts`).
 *
 * Output shape:
 *
 *   At root level (block themes' content-area treatment):
 *     <div class="bsy-block-root">
 *       <{tag} class="bsy-icon-{uid}" ...>
 *         <svg>…</svg>
 *       </{tag}>
 *     </div>
 *
 *   Inside a Blocksify parent (Container / Section / Pro parents):
 *     <{tag} class="bsy-icon-{uid}" ...>
 *       <svg>…</svg>
 *     </{tag}>
 *
 * Wrapper at root is needed because WP core ships
 *   `.is-layout-constrained > * { margin-inline: auto !important }`
 * which centers every direct child of `.entry-content` on block themes.
 * Without the wrapper, our inline-flex Icon either hugs canvas-LEFT
 * (theme rule no-op on inline-level) or gets centered (theme rule
 * applies on block-level) — both visually mismatch sibling text /
 * heading blocks that sit at content-column-LEFT. Wrapper takes the
 * theme treatment; inner inline-flex Icon hugs LEFT of wrapper's line
 * box = at content-column-LEFT. Trade-off: when `tag=div` (default)
 * the DOM has a double-div at root, but the Icon aligns naturally
 * with sibling content blocks across themes. Inside a Blocksify
 * parent, the wrapper is skipped — the parent owns layout positioning.
 *
 * `$tag` resolves to one of `a, button, div, span` (default `div`),
 * with `<a>` swapping to `<div>` when no URL is set so saved markup
 * never emits an empty `<a>` for non-clickable decorative icons.
 *
 * `attributes.icon.svg` is sanitized at JS commit time by IconLibrary's
 * `sanitizeSvg()` (see `src/shared/icon.js`). Echoed without `wp_kses`
 * because the JS-side allowlist is the single source of truth.
 *
 * @package Blocksify
 *
 * @var array    $attributes Block attributes.
 * @var string   $content    Saved block markup (always empty for dynamic).
 * @var WP_Block $block      Parsed block instance.
 */

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

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

$allowed_tags = array( 'a', 'button', 'div', 'span' );
$raw_tag      = isset( $attributes['tagName'] ) && in_array( $attributes['tagName'], $allowed_tags, true )
	? $attributes['tagName']
	: 'div';

$uid          = isset( $attributes['uid'] ) ? (string) $attributes['uid'] : '';
$user_class   = isset( $attributes['className'] ) ? trim( (string) $attributes['className'] ) : '';
$anchor       = isset( $attributes['anchor'] ) ? (string) $attributes['anchor'] : '';
$url          = isset( $attributes['url'] ) ? (string) $attributes['url'] : '';
$link_target  = isset( $attributes['linkTarget'] ) ? (string) $attributes['linkTarget'] : '';
$rel          = isset( $attributes['rel'] ) ? (string) $attributes['rel'] : '';

$tag = ( 'a' === $raw_tag && '' === $url ) ? 'div' : $raw_tag;

$icon     = isset( $attributes['icon'] ) && is_array( $attributes['icon'] ) ? $attributes['icon'] : null;
$icon_svg = Blocksify_Icons::render( $icon );
$icon_url = ( $icon && '' === $icon_svg && isset( $icon['url'] ) && is_string( $icon['url'] ) ) ? $icon['url'] : '';

$classes = array();
if ( '' !== $uid ) {
	$classes[] = 'bsy-icon-' . preg_replace( '/[^a-z0-9_-]/i', '', $uid );
}
if ( '' !== $user_class ) {
	$classes[] = $user_class;
}
$class_attr = esc_attr( implode( ' ', $classes ) );

$attrs_html = 'class="' . $class_attr . '"';
if ( '' !== $anchor ) {
	$attrs_html .= ' id="' . esc_attr( $anchor ) . '"';
}
if ( 'a' === $tag ) {
	if ( '' !== $url ) {
		$attrs_html .= ' href="' . esc_url( $url ) . '"';
	}
	if ( '' !== $link_target ) {
		$attrs_html .= ' target="' . esc_attr( $link_target ) . '"';
	}
	if ( '' !== $rel ) {
		$attrs_html .= ' rel="' . esc_attr( $rel ) . '"';
	}
}

if ( '' !== $icon_svg ) {
	$inner_html = $icon_svg;
} elseif ( '' !== $icon_url ) {
	$inner_html = '<img src="' . esc_url( $icon_url ) . '" alt="" />';
} else {
	$inner_html = '';
}

$is_nested = ! empty( $block->context['blocksify/innerBlock'] );
$open      = $is_nested ? '' : '<div class="bsy-block-root">';
$close     = $is_nested ? '' : '</div>';

echo $open
	. '<' . esc_attr( $tag ) . ' ' . $attrs_html . '>' . $inner_html . '</' . esc_attr( $tag ) . '>'
	. $close; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
