<?php
/** Maschinenlesbare, ehrliche Builder-Kompatibilitätsmatrix. */

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

function wpagent_ability_get_builder_compatibility(): array {
	$ids = array( 'gutenberg', 'spectra-one', 'kadence', 'spectra', 'spectra-blocks', 'generateblocks', 'elementor', 'beaver-builder', 'bricks', 'breakdance', 'oxygen', 'wpbakery' );
	$item = array( 'type' => 'object', 'additionalProperties' => false, 'properties' => array(
		'id' => array( 'type' => 'string', 'enum' => $ids ), 'installed' => array( 'type' => 'boolean' ), 'version' => array( 'type' => 'string', 'maxLength' => 100 ),
		'native_write' => array( 'type' => 'boolean' ), 'cache_refresh' => array( 'type' => 'boolean' ),
		'validation' => array( 'type' => 'string', 'enum' => array( 'practical', 'practical-bounded', 'unsupported', 'defensive' ) ),
		'storage' => array( 'type' => 'string', 'enum' => array( 'post_content', 'wp_global_styles+site-editor', 'postmeta-json', 'postmeta-objects', 'postmeta', 'postmeta-shortcodes', 'post_content-shortcodes' ) ), 'reason' => array( 'type' => 'string', 'minLength' => 1, 'maxLength' => 1024 ),
	), 'required' => array( 'id', 'installed', 'version', 'native_write', 'cache_refresh', 'validation', 'storage', 'reason' ) );
	return array(
		'label' => __( 'Builder-Kompatibilität lesen', 'wp-agent-companion' ),
		'description' => __( 'Liefert die tatsächliche Schreib-, Cache- und Testabdeckung pro Builder. Nicht unterstützte native Writes werden ausdrücklich als fail-closed gemeldet.', 'wp-agent-companion' ),
		'category' => 'wp-agent', 'input_schema' => array( 'type' => 'object', 'properties' => array(), 'additionalProperties' => false ),
		'output_schema' => array( 'type' => 'object', 'additionalProperties' => false, 'properties' => array(
			'builders' => array( 'type' => 'array', 'minItems' => 1, 'maxItems' => 16, 'items' => $item ),
			'summary' => array( 'type' => 'object', 'additionalProperties' => false, 'properties' => array(
				'native_write' => array( 'type' => 'array', 'maxItems' => 16, 'items' => array( 'type' => 'string', 'enum' => $ids ) ),
				'fail_closed' => array( 'type' => 'array', 'maxItems' => 16, 'items' => array( 'type' => 'string', 'enum' => $ids ) ),
			), 'required' => array( 'native_write', 'fail_closed' ) ),
		), 'required' => array( 'builders', 'summary' ) ),
		'execute_callback' => 'wpagent_exec_get_builder_compatibility', 'permission_callback' => 'wpagent_perm_edit_posts',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @return array{builders:array<int,array<string,mixed>>,summary:array<string,string[]>}|WP_Error */
function wpagent_exec_get_builder_compatibility( $input = array() ) {
	$input_valid = wpagent_builder_read_empty_object_input( $input );
	if ( is_wp_error( $input_valid ) ) {
		return $input_valid;
	}
	$spectra_one_theme   = wp_get_theme( 'spectra-one' );
	$spectra_one_active  = 'spectra-one' === get_template() || 'spectra-one' === get_stylesheet();
	$spectra_one_version = $spectra_one_theme->exists() ? (string) $spectra_one_theme->get( 'Version' ) : '';
	$spectra_blocks_native_write = defined( 'SPECTRA_BLOCKS_VER' ) && hash_equals( WPAGENT_SPECTRA_BLOCKS_SEPARATOR_VERSION, (string) SPECTRA_BLOCKS_VER );
	$definitions = array(
		'gutenberg' => array( true, true, 'practical', 'post_content', true, defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : get_bloginfo( 'version' ), __( 'Core-Blöcke werden ausschließlich aus Markdown oder deklarativen Abschnitten serverseitig erzeugt und per Read-back sowie Render-Verify geprüft.', 'wp-agent-companion' ) ),
		'spectra-one' => array( true, true, 'practical', 'wp_global_styles+site-editor', $spectra_one_active, $spectra_one_version, __( 'Das aktive Spectra-One-Block-Theme nutzt die nativen WordPress-Pfade für Global Styles, Stilvarianten, Templates, Template-Teile und Navigationen. Konflikt-Hash, Kurzzeitsperre, exakter Read-back und Rollback schützen Designänderungen.', 'wp-agent-companion' ) ),
		'kadence' => array( true, true, 'practical-bounded', 'post_content', defined( 'KADENCE_BLOCKS_VERSION' ) || class_exists( 'Kadence_Blocks_Frontend' ), defined( 'KADENCE_BLOCKS_VERSION' ) ? KADENCE_BLOCKS_VERSION : '', __( 'Registrierte Blocktypen, Attribute und Dokumentstrukturen werden live gelesen. Rohes Block-Markup wird nicht geschrieben; der Cache-Pfad ist praktisch geprüft.', 'wp-agent-companion' ) ),
		'spectra' => array( true, true, 'practical-bounded', 'post_content', defined( 'UAGB_VER' ) || class_exists( 'UAGB_Loader' ), defined( 'UAGB_VER' ) ? UAGB_VER : '', __( 'Sichtbare dynamische Spectra-Blöcke mit serverseitig registriertem Schema erlauben gezielte begrenzte Attributänderungen samt Konflikthash, Revision, Renderprüfung, Cache-Invalidierung und Rollback. Rohes Block-Markup, statische JavaScript-Schemas, Objektattribute, HTML und freie CSS-Deklarationen bleiben gesperrt.', 'wp-agent-companion' ) ),
		'spectra-blocks' => array( $spectra_blocks_native_write, false, 'practical-bounded', 'post_content', defined( 'SPECTRA_BLOCKS_VER' ), defined( 'SPECTRA_BLOCKS_VER' ) ? SPECTRA_BLOCKS_VER : '', __( 'Das getrennte Spectra-Blocks-Plugin wird am eigenen spectra-Namensraum erkannt. Genau Version 1.0.4 unterstützt den serverseitig registrierten Separator mit Bloghash, atomarem Vergleich, Revision, erneuerbarer Sperre und Rückleseprüfung. Andere Providerstände bleiben im nativen Write fail-closed.', 'wp-agent-companion' ) ),
		'generateblocks' => array( true, true, 'practical-bounded', 'post_content', defined( 'GENERATEBLOCKS_VERSION' ) || class_exists( 'GenerateBlocks_Enqueue_CSS' ), defined( 'GENERATEBLOCKS_VERSION' ) ? GENERATEBLOCKS_VERSION : '', __( 'Registrierte Blocktypen, Attribute und Dokumentstrukturen werden live gelesen. Rohes Block-Markup wird nicht geschrieben; dynamisches CSS kann über die Plugin-API invalidiert werden.', 'wp-agent-companion' ) ),
		'elementor' => array( true, true, 'practical', 'postmeta-json', defined( 'ELEMENTOR_VERSION' ) || class_exists( '\\Elementor\\Plugin' ), defined( 'ELEMENTOR_VERSION' ) ? ELEMENTOR_VERSION : '', __( 'Strukturen und Seiteneinstellungen werden über Elementors öffentliche Dokument-API gelesen, erstellt, konfliktgeschützt geschrieben, im Frontend geprüft und über Elementor-Revisionen wiederhergestellt.', 'wp-agent-companion' ) ),
		'beaver-builder' => array( true, true, 'practical', 'postmeta-objects', defined( 'FL_BUILDER_VERSION' ) || class_exists( 'FLBuilderModel' ), defined( 'FL_BUILDER_VERSION' ) ? FL_BUILDER_VERSION : '', __( 'Zeilen, Spalten, sichere Module und responsive Einstellungen werden über Beaver Builders Modell-API gelesen, erstellt und konfliktgeschützt geändert. Pflichtrevision, Cache-Invalidierung, Frontend-Read-back und Rollback sind praktisch geprüft.', 'wp-agent-companion' ) ),
		'bricks' => array( false, false, 'unsupported', 'postmeta', defined( 'BRICKS_VERSION' ) || class_exists( 'Bricks\\Database' ), defined( 'BRICKS_VERSION' ) ? BRICKS_VERSION : '', __( 'Erkennung ist vorhanden. Native Writes und ein verifizierter Cache-Pfad fehlen und werden abgelehnt.', 'wp-agent-companion' ) ),
		'breakdance' => array( false, true, 'defensive', 'postmeta', defined( '__BREAKDANCE_VERSION' ) || function_exists( 'Breakdance\\Render\\getRenderedPost' ), defined( '__BREAKDANCE_VERSION' ) ? constant( '__BREAKDANCE_VERSION' ) : '', __( 'Erkennung und defensive Cache-Integration sind vorhanden. Es gibt keine dokumentierte stabile Remote-Schreib-API für Seiten.', 'wp-agent-companion' ) ),
		'oxygen' => array( false, true, 'defensive', 'postmeta-shortcodes', defined( 'CT_VERSION' ) || function_exists( 'oxygen_vsb_cache_delete' ), defined( 'CT_VERSION' ) ? CT_VERSION : '', __( 'Erkennung und defensive Cache-Integration sind vorhanden. Es gibt keine dokumentierte stabile Remote-Schreib-API für Designs.', 'wp-agent-companion' ) ),
		'wpbakery' => array( false, true, 'defensive', 'post_content-shortcodes', defined( 'WPB_VC_VERSION' ) || class_exists( 'Vc_Manager' ), defined( 'WPB_VC_VERSION' ) ? WPB_VC_VERSION : '', __( 'Shortcodes werden erkannt. WPAgently erzeugt keine proprietären Shortcode-Strukturen und lehnt native Writes ab.', 'wp-agent-companion' ) ),
	);
	$builders = array();
	foreach ( $definitions as $id => $row ) {
		$builders[] = array( 'id' => $id, 'native_write' => $row[0], 'cache_refresh' => $row[1], 'validation' => $row[2], 'storage' => $row[3], 'installed' => (bool) $row[4], 'version' => (string) $row[5], 'reason' => $row[6] );
	}
	$result = array(
		'builders' => $builders,
		'summary' => array(
			'native_write' => array_values( array_column( array_filter( $builders, static fn( array $row ): bool => $row['native_write'] ), 'id' ) ),
			'fail_closed' => array_values( array_column( array_filter( $builders, static fn( array $row ): bool => ! $row['native_write'] ), 'id' ) ),
		),
	);
	$output_valid = wpagent_builder_compatibility_validate_output( $result );
	return is_wp_error( $output_valid ) ? $output_valid : $result;
}

/** @return true|WP_Error */
function wpagent_builder_compatibility_validate_output( array $result ) {
	$ids = array( 'gutenberg', 'spectra-one', 'kadence', 'spectra', 'spectra-blocks', 'generateblocks', 'elementor', 'beaver-builder', 'bricks', 'breakdance', 'oxygen', 'wpbakery' );
	if ( array( 'builders', 'summary' ) !== array_keys( $result ) || ! is_array( $result['builders'] ) || count( $result['builders'] ) < 1 || count( $result['builders'] ) > 16 || ! is_array( $result['summary'] ) || array( 'native_write', 'fail_closed' ) !== array_keys( $result['summary'] ) ) {
		return wpagent_builder_read_invalid_output();
	}
	foreach ( $result['builders'] as $row ) {
		if ( ! is_array( $row ) || array( 'id', 'native_write', 'cache_refresh', 'validation', 'storage', 'installed', 'version', 'reason' ) !== array_keys( $row ) || ! in_array( $row['id'], $ids, true ) || ! is_bool( $row['native_write'] ) || ! is_bool( $row['cache_refresh'] ) || ! is_bool( $row['installed'] ) || ! in_array( $row['validation'], array( 'practical', 'practical-bounded', 'unsupported', 'defensive' ), true ) || ! in_array( $row['storage'], array( 'post_content', 'wp_global_styles+site-editor', 'postmeta-json', 'postmeta-objects', 'postmeta', 'postmeta-shortcodes', 'post_content-shortcodes' ), true ) || ! wpagent_builder_read_valid_text( $row['version'], 0, 100 ) || ! wpagent_builder_read_valid_text( $row['reason'], 1, 1024 ) ) {
			return wpagent_builder_read_invalid_output();
		}
	}
	foreach ( $result['summary'] as $ids_by_status ) {
		if ( ! is_array( $ids_by_status ) || count( $ids_by_status ) > 16 || count( $ids_by_status ) !== count( array_unique( $ids_by_status ) ) ) {
			return wpagent_builder_read_invalid_output();
		}
		foreach ( $ids_by_status as $id ) {
			if ( ! is_string( $id ) || ! in_array( $id, $ids, true ) ) {
				return wpagent_builder_read_invalid_output();
			}
		}
	}
	return true;
}
