<?php
/** Read-only Elementor widget discovery and targeted element access. */

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

function wpagent_ability_list_elementor_widgets(): array {
	return array(
		'label' => __( 'Elementor-Widgets auflisten', 'wp-agent-companion' ),
		'description' => __( 'Listet die in der aktiven Elementor-Installation registrierten und über den sicheren Pfad erlaubten Widgets paginiert auf.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object',
			'properties' => array(
				'search' => array( 'type' => 'string', 'maxLength' => 200 ),
				'category' => array( 'type' => 'string', 'maxLength' => 100 ),
				'page' => array( 'type' => 'integer', 'minimum' => 1, 'default' => 1 ),
				'per_page' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => 200, 'default' => 50 ),
			),
			'additionalProperties' => false,
		),
		'output_schema' => array(
			'type' => 'object',
			'properties' => array(
				'widgets' => array( 'type' => 'array', 'maxItems' => 200, 'items' => wpagent_elementor_widget_summary_schema() ),
				'total' => array( 'type' => 'integer', 'minimum' => 0 ),
				'page' => array( 'type' => 'integer', 'minimum' => 1 ),
				'per_page' => array( 'type' => 'integer', 'minimum' => 1, 'maximum' => 200 ),
				'total_pages' => array( 'type' => 'integer', 'minimum' => 0 ),
				'elementor_version' => array( 'type' => 'string', 'maxLength' => 64 ),
			),
			'required' => array( 'widgets', 'total', 'page', 'per_page', 'total_pages', 'elementor_version' ),
			'additionalProperties' => false,
		),
		'execute_callback' => 'wpagent_exec_list_elementor_widgets',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

function wpagent_ability_get_elementor_widget_schema(): array {
	return array(
		'label' => __( 'Elementor-Widget-Schema lesen', 'wp-agent-companion' ),
		'description' => __( 'Liest die schreibbaren Controls eines sicheren Elementor-Widgets aus der aktiven Anbieter-Registry.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object',
			'properties' => array( 'widget_type' => array( 'type' => 'string', 'pattern' => '^[A-Za-z0-9_-]{1,128}$' ) ),
			'required' => array( 'widget_type' ),
			'additionalProperties' => false,
		),
		'output_schema' => wpagent_elementor_widget_schema_output_schema(),
		'execute_callback' => 'wpagent_exec_get_elementor_widget_schema',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

function wpagent_ability_get_elementor_element(): array {
	return array(
		'label' => __( 'Elementor-Element lesen', 'wp-agent-companion' ),
		'description' => __( 'Liest ein einzelnes Elementor-Element anhand seiner ID samt Pfad und Dokument-Konflikt-Hash.', 'wp-agent-companion' ),
		'category' => 'wp-agent',
		'input_schema' => array(
			'type' => 'object',
			'properties' => array(
				'post_id' => array( 'type' => 'integer', 'minimum' => 1 ),
				'element_id' => array( 'type' => 'string', 'pattern' => '^[A-Za-z0-9_-]{1,64}$' ),
			),
			'required' => array( 'post_id', 'element_id' ),
			'additionalProperties' => false,
		),
		'output_schema' => wpagent_elementor_element_output_schema(),
		'execute_callback' => 'wpagent_exec_get_elementor_element',
		'permission_callback' => 'wpagent_perm_edit_posts',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ) ),
	);
}

/** @return array<string,mixed> */
function wpagent_elementor_widget_summary_schema(): array {
	return array(
		'type' => 'object',
		'properties' => array(
			'name' => array( 'type' => 'string', 'maxLength' => 128 ),
			'title' => array( 'type' => 'string', 'maxLength' => 500 ),
			'categories' => array( 'type' => 'array', 'maxItems' => WPAGENT_ELEMENTOR_MAX_WIDGET_CATEGORIES, 'items' => array( 'type' => 'string', 'maxLength' => 100 ) ),
			'keywords' => array( 'type' => 'array', 'maxItems' => 50, 'items' => array( 'type' => 'string', 'maxLength' => 100 ) ),
			'controls_count' => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => WPAGENT_ELEMENTOR_MAX_PROVIDER_CONTROLS ),
			'controls_truncated' => array( 'type' => 'boolean' ),
			'safe' => array( 'type' => 'boolean' ),
		),
		'required' => array( 'name', 'title', 'categories', 'keywords', 'controls_count', 'controls_truncated', 'safe' ),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_elementor_widget_schema_output_schema(): array {
	return array(
		'type' => 'object',
		'properties' => array(
			'widget_type' => array( 'type' => 'string', 'maxLength' => 128 ),
			'title' => array( 'type' => 'string', 'maxLength' => 500 ),
			'categories' => array( 'type' => 'array', 'maxItems' => WPAGENT_ELEMENTOR_MAX_WIDGET_CATEGORIES, 'items' => array( 'type' => 'string', 'maxLength' => 100 ) ),
			'controls' => array(
				'type' => 'array',
				'maxItems' => WPAGENT_ELEMENTOR_MAX_CONTROLS,
				'items' => array(
					'type' => 'object',
					'properties' => array(
						'name' => array( 'type' => 'string', 'maxLength' => 191 ),
						'type' => array( 'type' => 'string', 'maxLength' => 64 ),
						'label' => array( 'type' => 'string', 'maxLength' => 500 ),
						'tab' => array( 'type' => 'string', 'maxLength' => 64 ),
						'section' => array( 'type' => 'string', 'maxLength' => 191 ),
						'responsive' => array( 'type' => 'boolean' ),
						'style' => array( 'type' => 'boolean' ),
						'devices' => array( 'type' => 'array', 'maxItems' => 3, 'items' => array( 'type' => 'string', 'enum' => array( 'desktop', 'tablet', 'mobile' ) ) ),
						'value_type' => array( 'type' => 'string', 'maxLength' => 64 ),
						'dynamic' => array( 'type' => 'boolean' ),
						'default_json' => array( 'type' => 'string', 'maxLength' => 65535 ),
						'options' => array(
							'type' => 'array',
							'maxItems' => WPAGENT_ELEMENTOR_MAX_CONTROL_OPTIONS,
							'items' => array( 'type' => 'object', 'properties' => array( 'value' => array( 'type' => 'string', 'maxLength' => 500 ), 'label' => array( 'type' => 'string', 'maxLength' => 500 ) ), 'required' => array( 'value', 'label' ), 'additionalProperties' => false ),
						),
					),
					'required' => array( 'name', 'type', 'label', 'tab', 'section', 'responsive', 'style', 'devices', 'value_type', 'dynamic', 'default_json', 'options' ),
					'additionalProperties' => false,
				),
			),
			'controls_count' => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => WPAGENT_ELEMENTOR_MAX_CONTROLS ),
			'controls_total' => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => WPAGENT_ELEMENTOR_MAX_PROVIDER_CONTROLS ),
			'controls_truncated' => array( 'type' => 'boolean' ),
			'elementor_version' => array( 'type' => 'string', 'maxLength' => 64 ),
		),
		'required' => array( 'widget_type', 'title', 'categories', 'controls', 'controls_count', 'controls_total', 'controls_truncated', 'elementor_version' ),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed> */
function wpagent_elementor_element_output_schema(): array {
	return array(
		'type' => 'object',
		'properties' => array(
			'post_id' => array( 'type' => 'integer', 'minimum' => 1 ),
			'element_id' => array( 'type' => 'string', 'maxLength' => 64 ),
			'path' => array( 'type' => 'array', 'maxItems' => WPAGENT_ELEMENTOR_MAX_DEPTH, 'items' => array( 'type' => 'integer', 'minimum' => 0, 'maximum' => WPAGENT_ELEMENTOR_MAX_ELEMENTS ) ),
			'element' => wpagent_elementor_json_document_schema(),
			'document_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
			'elementor_version' => array( 'type' => 'string', 'maxLength' => 64 ),
		),
		'required' => array( 'post_id', 'element_id', 'path', 'element', 'document_hash', 'elementor_version' ),
		'additionalProperties' => false,
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_list_elementor_widgets( $input ) {
	if ( ! current_user_can( 'edit_posts' ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$input = is_array( $input ) ? $input : array();
	$manager = wpagent_elementor_widget_manager();
	if ( is_wp_error( $manager ) ) {
		return $manager;
	}
	$search = is_string( $input['search'] ?? null ) ? trim( $input['search'] ) : '';
	$raw_category = is_string( $input['category'] ?? null ) ? $input['category'] : '';
	$category = sanitize_key( $raw_category );
	$search_length = function_exists( 'mb_strlen' ) ? mb_strlen( $search, 'UTF-8' ) : strlen( $search );
	if ( $search_length > 200 || strlen( $raw_category ) > 100 ) {
		return new WP_Error( 'wpagent_elementor_filter_length', __( 'search oder category ist zu lang.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	if ( '' !== $raw_category && '' === $category ) {
		return new WP_Error( 'wpagent_elementor_bad_category', __( 'category ist ungültig.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}
	$page = max( 1, absint( $input['page'] ?? 1 ) );
	$per_page = min( 200, max( 1, absint( $input['per_page'] ?? 50 ) ) );
	$rows = array();
	try {
		$widgets = $manager->get_widget_types();
	} catch ( Throwable ) {
		return new WP_Error( 'wpagent_elementor_widgets_failed', __( 'Elementor konnte die Widget-Liste nicht laden.', 'wp-agent-companion' ), array( 'status' => 500 ) );
	}
	foreach ( is_array( $widgets ) ? $widgets : array() as $name => $widget ) {
		try {
			$name = is_string( $name ) ? $name : ( is_object( $widget ) && method_exists( $widget, 'get_name' ) ? (string) $widget->get_name() : '' );
			if ( ! preg_match( '/^[A-Za-z0-9_-]{1,128}$/', $name ) || wpagent_elementor_widget_type_is_unsafe( $name ) || ! is_object( $widget ) || ! method_exists( $widget, 'get_controls' ) ) {
				continue;
			}
		} catch ( Throwable ) {
			continue;
		}
		$metadata = wpagent_elementor_widget_metadata( $widget, $name );
		if ( is_wp_error( $metadata ) ) {
			continue;
		}
		$title = $metadata['title'];
		$categories = $metadata['categories'];
		$keywords = $metadata['keywords'];
		if ( '' !== $search && false === stripos( $name . ' ' . $title . ' ' . implode( ' ', $keywords ), $search ) ) {
			continue;
		}
		if ( '' !== $category && ! in_array( $category, $categories, true ) ) {
			continue;
		}
		$controls_total = 0;
		$controls = wpagent_elementor_writable_controls( $widget, $controls_total );
		if ( is_wp_error( $controls ) ) {
			continue;
		}
		$rows[] = array(
			'name' => $name,
			'title' => wp_html_excerpt( $title, 500, '' ),
			'categories' => $categories,
			'keywords' => array_slice( $keywords, 0, 50 ),
			'controls_count' => $controls_total,
			'controls_truncated' => $controls_total > count( $controls ),
			'safe' => true,
		);
	}
	usort( $rows, static fn( array $a, array $b ): int => strcmp( $a['name'], $b['name'] ) );
	$total = count( $rows );
	$total_pages = 0 === $total ? 0 : (int) ceil( $total / $per_page );
	$paged_rows = $page > $total_pages ? array() : array_slice( $rows, ( $page - 1 ) * $per_page, $per_page );
	return array(
		'widgets' => $paged_rows,
		'total' => $total,
		'page' => $page,
		'per_page' => $per_page,
		'total_pages' => $total_pages,
		'elementor_version' => defined( 'ELEMENTOR_VERSION' ) ? (string) ELEMENTOR_VERSION : '',
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_elementor_widget_schema( $input ) {
	if ( ! current_user_can( 'edit_posts' ) ) {
		return new WP_Error( 'wpagent_forbidden', __( 'Keine Berechtigung.', 'wp-agent-companion' ), array( 'status' => 403 ) );
	}
	$input = is_array( $input ) ? $input : array();
	$widget_type = is_string( $input['widget_type'] ?? null ) ? $input['widget_type'] : '';
	$widget = wpagent_elementor_widget( $widget_type );
	if ( is_wp_error( $widget ) ) {
		return $widget;
	}
	$controls_total = 0;
	$controls = wpagent_elementor_writable_controls( $widget, $controls_total );
	if ( is_wp_error( $controls ) ) {
		return $controls;
	}
	$registered_controls = wpagent_elementor_registered_controls( $widget );
	if ( is_wp_error( $registered_controls ) ) {
		return $registered_controls;
	}
	$metadata = wpagent_elementor_widget_metadata( $widget, $widget_type );
	if ( is_wp_error( $metadata ) ) {
		return $metadata;
	}
	$result = array();
	foreach ( $controls as $name => $control ) {
		$result[] = wpagent_elementor_control_summary( $name, $control, $registered_controls );
	}
	return array(
		'widget_type' => $widget_type,
		'title' => $metadata['title'],
		'categories' => $metadata['categories'],
		'controls' => $result,
		'controls_count' => count( $result ),
		'controls_total' => $controls_total,
		'controls_truncated' => $controls_total > count( $result ),
		'elementor_version' => defined( 'ELEMENTOR_VERSION' ) ? (string) ELEMENTOR_VERSION : '',
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_elementor_element( $input ) {
	$input = is_array( $input ) ? $input : array();
	$post_id = absint( $input['post_id'] ?? 0 );
	$element_id = is_string( $input['element_id'] ?? null ) ? $input['element_id'] : '';
	$loaded = wpagent_elementor_editable_document( $post_id );
	if ( is_wp_error( $loaded ) ) {
		return $loaded;
	}
	$state = wpagent_elementor_document_state( $post_id, $loaded['document'] );
	$located = wpagent_elementor_locate_element( $state['elements'], $element_id );
	if ( is_wp_error( $located ) ) {
		return $located;
	}
	return array(
		'post_id' => $post_id,
		'element_id' => $element_id,
		'path' => $located['path'],
		'element' => wpagent_elementor_json_document_output( $located['element'], 'wpagent_elementor_validate_single_element' ),
		'document_hash' => $state['hash'],
		'elementor_version' => $state['elementor_version'],
	);
}
