<?php
/** Verified read and write abilities for Kadence design settings. */

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

/** @param array<string,mixed> $schema @return array<string,mixed> */
function wpagent_kadence_bound_schema( array $schema ): array {
	if ( isset( $schema['properties'] ) && is_array( $schema['properties'] ) ) {
		foreach ( $schema['properties'] as $key => $child ) {
			if ( is_array( $child ) ) {
				$schema['properties'][ $key ] = wpagent_kadence_bound_schema( $child );
			}
		}
	}
	if ( isset( $schema['items'] ) && is_array( $schema['items'] ) ) {
		$schema['items'] = wpagent_kadence_bound_schema( $schema['items'] );
	}
	foreach ( array( 'anyOf', 'oneOf', 'allOf' ) as $keyword ) {
		if ( isset( $schema[ $keyword ] ) && is_array( $schema[ $keyword ] ) ) {
			foreach ( $schema[ $keyword ] as $key => $child ) {
				if ( is_array( $child ) ) {
					$schema[ $keyword ][ $key ] = wpagent_kadence_bound_schema( $child );
				}
			}
		}
	}
	$types = (array) ( $schema['type'] ?? array() );
	if ( in_array( 'object', $types, true ) && isset( $schema['properties'] ) && is_array( $schema['properties'] ) ) {
		$schema['maxProperties']        = count( $schema['properties'] );
		$schema['additionalProperties'] = false;
	}
	if ( in_array( 'array', $types, true ) && ! isset( $schema['maxItems'] ) ) {
		$schema['maxItems'] = 64;
	}
	return $schema;
}

/** @param array<string,mixed> $schema @return array<string,mixed> */
function wpagent_kadence_complete_object_schema( array $schema ): array {
	$schema                  = wpagent_kadence_bound_schema( $schema );
	$schema['required']      = array_keys( $schema['properties'] ?? array() );
	$schema['minProperties'] = count( $schema['required'] );
	return $schema;
}

/** @return array<string,mixed> */
function wpagent_kadence_header_read_device_schema( string $target ): array {
	$properties = array();
	foreach ( wpagent_kadence_header_zones( $target ) as $placements ) {
		foreach ( $placements as $placement ) {
			$properties[ $placement ] = array(
				'type'        => 'array',
				'maxItems'    => 7,
				'uniqueItems' => true,
				'items'       => array( 'type' => 'string', 'enum' => wpagent_kadence_header_components( $target ) ),
			);
		}
	}
	return array( 'type' => 'object', 'minProperties' => count( $properties ), 'maxProperties' => count( $properties ), 'properties' => $properties, 'required' => array_keys( $properties ), 'additionalProperties' => false );
}

/** @return array<string,array<string,mixed>> */
function wpagent_kadence_read_section_schemas(): array {
	$layout  = wpagent_kadence_complete_object_schema( wpagent_kadence_layout_schema() );
	$palette = wpagent_kadence_bound_schema( wpagent_kadence_palette_schema() );
	$palette['properties']['colors'] = wpagent_kadence_complete_object_schema( $palette['properties']['colors'] );
	$palette = wpagent_kadence_complete_object_schema( $palette );
	$colors  = wpagent_kadence_bound_schema( wpagent_kadence_colors_schema() );
	foreach ( $colors['properties'] as $key => $color ) {
		$color['minLength']              = 0;
		$colors['properties'][ $key ] = $color;
	}
	$colors  = wpagent_kadence_complete_object_schema( $colors );
	$buttons = wpagent_kadence_bound_schema( wpagent_kadence_buttons_schema() );
	foreach ( array( 'text', 'text_hover', 'background', 'background_hover' ) as $key ) {
		$buttons['properties'][ $key ]['minLength'] = 0;
	}
	$radius  = $buttons['properties']['border_radius'];
	$radius['properties']['units'] = wpagent_kadence_complete_object_schema( $radius['properties']['units'] );
	$radius['required']      = array( 'desktop', 'tablet', 'mobile', 'units' );
	$radius['minProperties'] = count( $radius['required'] );
	$radius['maxProperties'] = 5;
	$buttons['properties']['border_radius'] = $radius;
	$buttons = wpagent_kadence_complete_object_schema( $buttons );
	$typography = wpagent_kadence_bound_schema( wpagent_kadence_typography_schema() );
	$typography['required']      = array( 'target', 'font_family', 'google_font' );
	$typography['minProperties'] = count( $typography['required'] );
	$header = array(
		'type'                 => 'object',
		'properties'           => array(
			'desktop' => wpagent_kadence_header_read_device_schema( 'desktop' ),
			'mobile'  => wpagent_kadence_header_read_device_schema( 'mobile' ),
		),
		'required'             => array( 'desktop', 'mobile' ),
		'minProperties'        => 2,
		'maxProperties'        => 2,
		'additionalProperties' => false,
	);
	return array(
		'layout'     => $layout,
		'palette'    => $palette,
		'colors'     => $colors,
		'typography' => array( 'type' => 'array', 'minItems' => 7, 'maxItems' => 7, 'items' => $typography ),
		'buttons'    => $buttons,
		'header'     => $header,
	);
}

/** @return array<string,mixed> */
function wpagent_kadence_update_settings_schema(): array {
	$schemas = array();
	foreach ( wpagent_kadence_section_schemas() as $schema ) {
		$schemas[] = wpagent_kadence_bound_schema( $schema );
	}
	return array( 'anyOf' => $schemas );
}

/** @return array<string,mixed> */
function wpagent_kadence_current_section_schema(): array {
	return array( 'anyOf' => array_values( wpagent_kadence_read_section_schemas() ) );
}

/** @return array<string,mixed> */
function wpagent_kadence_sections_schema(): array {
	$properties = wpagent_kadence_read_section_schemas();
	return array( 'type' => 'object', 'minProperties' => 0, 'maxProperties' => count( $properties ), 'properties' => $properties, 'additionalProperties' => false );
}

function wpagent_ability_get_kadence_design(): array {
	return array(
		'label'               => __( 'Kadence-Design lesen', 'wp-agent-companion' ),
		'description'         => __( 'Liest sechs begrenzte Kadence-Designbereiche einschließlich Header Builder und einen Konflikt-Hash.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array( 'type' => 'object', 'properties' => array(), 'maxProperties' => 0, 'additionalProperties' => false, 'default' => array() ),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'active'     => array( 'type' => 'boolean' ),
				'version'    => array( 'type' => 'string', 'maxLength' => 64 ),
				'sections'   => wpagent_kadence_sections_schema(),
				'state_hash' => array( 'type' => array( 'string', 'null' ), 'pattern' => '^[a-f0-9]{64}$' ),
			),
			'required'             => array( 'active', 'version', 'sections', 'state_hash' ),
			'maxProperties'        => 4,
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_get_kadence_design',
		'permission_callback' => 'wpagent_perm_manage_options',
		'meta'                => array(
			'show_in_rest' => true,
			'annotations'  => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ),
			'mcp'          => array(
				'uri'         => 'wpagently://integrations/kadence',
				'annotations' => array( 'audience' => array( 'assistant' ) ),
			),
		),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_get_kadence_design( $input = array() ) {
	$version = wpagent_kadence_version();
	if ( ! wpagent_kadence_is_active() ) {
		return array( 'active' => false, 'version' => $version, 'sections' => new stdClass(), 'state_hash' => null );
	}
	if ( ! wpagent_kadence_runtime_ready() ) {
		return new WP_Error( 'wpagent_kadence_runtime_missing', __( 'Die aktive Kadence-Version stellt den geprüften Einstellungsweg nicht bereit. Unterstützt wird Kadence ab Version 1.5.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$snapshot = wpagent_kadence_snapshot();
	if ( is_wp_error( $snapshot ) ) {
		return $snapshot;
	}
	$sections = array();
	foreach ( array_keys( wpagent_kadence_section_schemas() ) as $section ) {
		$current = wpagent_kadence_read_section( $section, $snapshot );
		if ( is_wp_error( $current ) ) {
			return $current;
		}
		$sections[ $section ] = $current;
	}
	return array(
		'active'     => true,
		'version'    => $version,
		'sections'   => $sections,
		'state_hash' => wpagent_kadence_state_hash( $snapshot ),
	);
}

function wpagent_ability_update_kadence_design(): array {
	return array(
		'label'               => __( 'Kadence-Design aktualisieren', 'wp-agent-companion' ),
		'description'         => __( 'Ändert einen begrenzten Kadence-Designbereich mit Konfliktschutz, erneuerbarer Sperre, Readback und bytegenauem Compare-and-Swap für Schreiben und Rollback.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'                 => 'object',
			'properties'           => array(
				'expected_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'section'       => array( 'type' => 'string', 'enum' => array_keys( wpagent_kadence_section_schemas() ) ),
				'settings'      => wpagent_kadence_update_settings_schema(),
			),
			'required'             => array( 'expected_hash', 'section', 'settings' ),
			'maxProperties'        => 3,
			'additionalProperties' => false,
		),
		'output_schema'       => array(
			'type'                 => 'object',
			'properties'           => array(
				'section'       => array( 'type' => 'string', 'enum' => array_keys( wpagent_kadence_section_schemas() ) ),
				'current'       => wpagent_kadence_current_section_schema(),
				'previous_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'state_hash'    => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ),
				'verified'      => array( 'type' => 'boolean' ),
			),
			'required'             => array( 'section', 'current', 'previous_hash', 'state_hash', 'verified' ),
			'maxProperties'        => 5,
			'additionalProperties' => false,
		),
		'execute_callback'    => 'wpagent_exec_update_kadence_design',
		'permission_callback' => 'wpagent_perm_manage_options',
		'meta'                => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ) ),
	);
}

/** @return array<string,mixed>|WP_Error */
function wpagent_exec_update_kadence_design( $input ) {
	if ( ! wpagent_kadence_is_active() ) {
		return new WP_Error( 'wpagent_kadence_inactive', __( 'Kadence oder ein Kadence-Child-Theme ist nicht aktiv.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	if ( ! wpagent_kadence_runtime_ready() ) {
		return new WP_Error( 'wpagent_kadence_runtime_missing', __( 'Die aktive Kadence-Version stellt den geprüften Einstellungsweg nicht bereit. Unterstützt wird Kadence ab Version 1.5.', 'wp-agent-companion' ), array( 'status' => 409 ) );
	}
	$section = is_array( $input ) ? (string) ( $input['section'] ?? '' ) : '';
	$lock    = wpagent_kadence_acquire_lock();
	if ( is_wp_error( $lock ) ) {
		return $lock;
	}
	try {
		$previous = wpagent_kadence_snapshot();
		if ( is_wp_error( $previous ) ) {
			return $previous;
		}
		$previous_hash = wpagent_kadence_state_hash( $previous );
		$expected_hash = strtolower( (string) ( $input['expected_hash'] ?? '' ) );
		if ( ! preg_match( '/^[a-f0-9]{64}$/', $expected_hash ) || ! hash_equals( $previous_hash, $expected_hash ) ) {
			return new WP_Error( 'wpagent_kadence_conflict', __( 'Die Kadence-Einstellungen haben sich seit dem Lesen geändert. Lies sie neu und wiederhole den Vorgang.', 'wp-agent-companion' ), array( 'status' => 409, 'current_hash' => $previous_hash ) );
		}
		foreach ( array_keys( wpagent_kadence_section_schemas() ) as $provider_section ) {
			$provider_state = wpagent_kadence_read_section( $provider_section, $previous );
			if ( is_wp_error( $provider_state ) ) {
				return $provider_state;
			}
		}
		$settings = wpagent_kadence_validate_settings( $section, $input['settings'] ?? null );
		if ( is_wp_error( $settings ) ) {
			return $settings;
		}
		$next = wpagent_kadence_apply_settings( $section, $previous, $settings );
		if ( is_wp_error( $next ) ) {
			return $next;
		}
		$requested_current = wpagent_kadence_read_section( $section, $next );
		if ( is_wp_error( $requested_current ) ) {
			return $requested_current;
		}
		$next = wpagent_kadence_prepare_next_for_write( $section, $previous, $next );
		if ( is_wp_error( $next ) ) {
			return $next;
		}
		$expected_current = wpagent_kadence_read_section( $section, $next );
		if ( is_wp_error( $expected_current ) ) {
			return $expected_current;
		}
		if ( maybe_serialize( $requested_current ) !== maybe_serialize( $expected_current ) ) {
			return new WP_Error( 'wpagent_kadence_provider_rejected_change', __( 'Kadence hat die angeforderte Änderung bereits vor dem Schreiben verändert oder abgelehnt.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		if ( ! wpagent_kadence_is_active() ) {
			return new WP_Error( 'wpagent_kadence_theme_changed', __( 'Das aktive Theme wurde während der Vorbereitung gewechselt. Lies die Kadence-Einstellungen erneut.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		if ( ! current_user_can( 'manage_options' ) || ! wpagent_kadence_runtime_ready() || ! wpagent_kadence_refresh_lock( $lock ) ) {
			return new WP_Error( 'wpagent_kadence_write_precondition_changed', __( 'Berechtigung, Kadence-Laufzeit oder exklusive Sperre ging vor dem Schreiben verloren. Es wurde nichts geändert.', 'wp-agent-companion' ), array( 'status' => 409 ) );
		}
		$written = wpagent_kadence_write_next( $section, $previous, $next );
		if ( is_wp_error( $written ) ) {
			$write_error = $written->get_error_data();
			if ( is_array( $write_error ) && false === ( $write_error['mutation_started'] ?? true ) ) {
				return $written;
			}
			return wpagent_kadence_fail_after_rollback( $section, $previous, $next, $previous_hash, $lock );
		}
		if ( ! current_user_can( 'manage_options' ) || ! wpagent_kadence_refresh_lock( $lock ) ) {
			return wpagent_kadence_recovery_required();
		}
		$current = wpagent_kadence_read_section( $section, $written );
		if ( is_wp_error( $current ) || maybe_serialize( $expected_current ) !== maybe_serialize( $current ) ) {
			return wpagent_kadence_fail_after_rollback( $section, $previous, $next, $previous_hash, $lock );
		}

		$fresh = wpagent_kadence_snapshot();
		if ( is_wp_error( $fresh ) ) {
			return wpagent_kadence_recovery_required();
		}
		if ( ! current_user_can( 'manage_options' ) || ! wpagent_kadence_runtime_ready() || ! wpagent_kadence_refresh_lock( $lock ) ) {
			return wpagent_kadence_recovery_required();
		}
		if ( ! wpagent_kadence_snapshot_matches( $fresh, $written ) ) {
			return wpagent_kadence_recovery_required();
		}
		return array(
			'section'       => $section,
			'current'       => $current,
			'previous_hash' => $previous_hash,
			'state_hash'    => wpagent_kadence_state_hash( $fresh ),
			'verified'      => true,
		);
	} finally {
		wpagent_kadence_release_lock( $lock );
	}
}
