<?php
/**
 * My Block linked vs independent placement (content + styles).
 *
 * @package JOCBM
 */

namespace JOCBM\Services;

defined( 'ABSPATH' ) || exit;

/**
 * Class InstanceScope
 */
final class InstanceScope {

	private const BLOCK_SCOPE_KEY = '__block__';

	/** @var array<int, string> */
	private const NON_CONTENT_KEYS = array(
		'cssVars',
		'styleScopeChoices',
		'librarySaveRev',
		'allowedPostTypes',
		'align',
		'className',
		'anchor',
	);

	/**
	 * @param mixed $style_scope_choices Attribute map.
	 */
	public static function is_independent( $style_scope_choices ): bool {
		return is_array( $style_scope_choices )
			&& isset( $style_scope_choices[ self::BLOCK_SCOPE_KEY ] )
			&& 'instance' === $style_scope_choices[ self::BLOCK_SCOPE_KEY ];
	}

	/**
	 * Content field keys from field_schema (+ elementsVisibility).
	 *
	 * @param array<int, mixed> $field_schema Schema.
	 * @return array<int, string>
	 */
	public static function content_keys( array $field_schema ): array {
		$keys = array();
		$skip = array_fill_keys( self::NON_CONTENT_KEYS, true );
		foreach ( $field_schema as $field ) {
			if ( ! is_array( $field ) ) {
				continue;
			}
			$key = isset( $field['key'] ) ? (string) $field['key'] : '';
			if ( '' === $key || isset( $skip[ $key ] ) ) {
				continue;
			}
			$keys[] = $key;
		}
		$keys[] = 'elementsVisibility';
		return array_values( array_unique( $keys ) );
	}

	/**
	 * Merge defaults + attributes for frontend render.
	 * Linked My Blocks use live default_attrs for content keys.
	 *
	 * @param array<string, mixed> $defaults     My Block default_attrs.
	 * @param array<string, mixed> $attributes   Placement attributes.
	 * @param array<int, mixed>    $field_schema Field schema.
	 * @return array<string, mixed>
	 */
	public static function merge_render_attrs( array $defaults, array $attributes, array $field_schema ): array {
		$scope       = isset( $attributes['styleScopeChoices'] ) && is_array( $attributes['styleScopeChoices'] )
			? $attributes['styleScopeChoices']
			: array();
		$independent = self::is_independent( $scope );
		$merged      = array_merge( $defaults, $attributes );

		if ( $independent ) {
			return $merged;
		}

		foreach ( self::content_keys( $field_schema ) as $key ) {
			if ( array_key_exists( $key, $defaults ) ) {
				$merged[ $key ] = $defaults[ $key ];
			}
		}

		return $merged;
	}
}
