<?php
/** Site Context lesen und verwalten. */

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

function wpagent_site_context_schema(): array {
	$properties = array();
	foreach ( wpagent_site_context_limits() as $field => $limit ) {
		$properties[ $field ] = array( 'type' => 'string', 'maxLength' => $limit );
	}
	return array( 'type' => 'object', 'properties' => $properties, 'additionalProperties' => false );
}

/** @return array<string,int> */
function wpagent_site_context_limits(): array {
	return array( 'site_name' => 200, 'audience' => 2000, 'voice' => 2000, 'goals' => 3000, 'constraints' => 3000, 'notes' => 5000 );
}

/** @return array<string,string> */
function wpagent_normalized_site_context( ?array $stored = null ): array {
	$stored  = null === $stored ? wpagent_state_array_option( WPAGENT_COMPANION_OPT_SITE_CONTEXT ) : $stored;
	$context = array();
	foreach ( wpagent_site_context_limits() as $field => $limit ) {
		$value = wpagent_state_text( $stored[ $field ] ?? '', $limit, $field );
		$context[ $field ] = is_wp_error( $value ) ? '' : $value;
	}
	return $context;
}

function wpagent_ability_get_site_context(): array {
	return array(
		'label' => __( 'Site Context lesen', 'wp-agent-companion' ), 'description' => __( 'Liest den zentralen Kontext für Zielgruppe, Tonalität, Ziele und Einschränkungen.', 'wp-agent-companion' ), 'category' => 'wp-agent',
		'input_schema' => array( 'type' => 'object', 'properties' => array(), 'additionalProperties' => false, 'default' => array() ),
		'output_schema' => array( 'type' => 'object', 'properties' => array( 'context' => wpagent_site_context_schema(), 'agent_context' => wpagent_companion_chat_context_schema(), 'state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ) ), 'additionalProperties' => false, 'required' => array( 'context', 'agent_context', 'state_hash' ) ),
		'execute_callback' => 'wpagent_exec_get_site_context', 'permission_callback' => 'wpagent_perm_edit_posts',
		'meta' => array(
			'show_in_rest' => true,
			'annotations'  => array( 'readonly' => true, 'destructive' => false, 'idempotent' => true ),
			'mcp'          => array(
				'uri'         => 'wpagently://site/context',
				'annotations' => array( 'audience' => array( 'assistant' ) ),
			),
		),
	);
}

function wpagent_ability_update_site_context(): array {
	return array(
		'label' => __( 'Site Context aktualisieren', 'wp-agent-companion' ), 'description' => __( 'Speichert den zentralen, begrenzten Site Context für alle Agent-Läufe.', 'wp-agent-companion' ), 'category' => 'wp-agent',
		'input_schema' => array_merge( wpagent_site_context_schema(), array( 'properties' => array_merge( wpagent_site_context_schema()['properties'], array( 'expected_state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ) ) ), 'required' => array( 'expected_state_hash' ) ) ),
		'output_schema' => array( 'type' => 'object', 'properties' => array( 'context' => wpagent_site_context_schema(), 'verified' => array( 'type' => 'boolean' ), 'state_hash' => array( 'type' => 'string', 'pattern' => '^[a-f0-9]{64}$' ) ), 'additionalProperties' => false, 'required' => array( 'context', 'verified', 'state_hash' ) ),
		'execute_callback' => 'wpagent_exec_update_site_context', 'permission_callback' => 'wpagent_perm_manage_options',
		'meta' => array( 'show_in_rest' => true, 'annotations' => array( 'readonly' => false, 'destructive' => false, 'idempotent' => false ) ),
	);
}

/** @return array|WP_Error */
function wpagent_exec_get_site_context( $input = array() ) {
	// This authenticated MCP resource gives every compatible client the same
	// bounded base context as Chat. Prompt-specific memories remain absent
	// because a resource read has no trusted task prompt for relevance ranking.
	// Never bypass the assembler's redaction through the legacy context field.
	return array(
		'context'       => wpagent_companion_chat_context_site_data( array( 'site_name', 'audience', 'voice', 'goals', 'constraints', 'notes' ), true ),
		'agent_context' => wpagent_companion_chat_assemble_context(),
		'state_hash'    => wpagent_state_hash_for_options( array( WPAGENT_COMPANION_OPT_SITE_CONTEXT ) ),
	);
}

/** @return array<string,string>|WP_Error */
function wpagent_validate_site_context( $input, ?array $base = null ) {
	$input   = is_array( $input ) ? $input : array();
	$limits  = wpagent_site_context_limits();
	$context = null === $base ? wpagent_normalized_site_context() : $base;
	foreach ( $limits as $field => $limit ) {
		if ( ! array_key_exists( $field, $input ) ) {
			continue;
		}
		$value = wpagent_state_text( $input[ $field ], $limit, $field );
		if ( is_wp_error( $value ) ) {
			return $value;
		}
		$context[ $field ] = $value;
	}
	return $context;
}

/** @return array|WP_Error */
function wpagent_exec_update_site_context( $input ) {
	$input = is_array( $input ) ? $input : array();
	return wpagent_state_with_scoped_lock(
		'site-context',
		static function ( string $token ) use ( $input ) {
			$snapshot = wpagent_state_option_snapshot( WPAGENT_COMPANION_OPT_SITE_CONTEXT );
			if ( ! $snapshot['readable'] ) {
				return new WP_Error( 'wpagent_site_context_persist_failed', __( 'Site Context konnte nicht verifiziert gespeichert werden.', 'wp-agent-companion' ), array( 'status' => 500, 'recovery_required' => true ) );
			}
			$required = wpagent_state_require_expected_hash( $input, wpagent_state_snapshot_hash( array( WPAGENT_COMPANION_OPT_SITE_CONTEXT => $snapshot ) ) );
			if ( is_wp_error( $required ) ) {
				return $required;
			}
			$context = wpagent_validate_site_context( $input, wpagent_normalized_site_context( is_array( $snapshot['value'] ) ? $snapshot['value'] : array() ) );
			if ( is_wp_error( $context ) ) {
				return $context;
			}
			$persisted = wpagent_state_commit_options( array( WPAGENT_COMPANION_OPT_SITE_CONTEXT => $context ), array( WPAGENT_COMPANION_OPT_SITE_CONTEXT => $snapshot ), 'site-context', $token, 'wpagent_site_context_persist_failed', __( 'Site Context konnte nicht verifiziert gespeichert werden.', 'wp-agent-companion' ) );
			if ( is_wp_error( $persisted ) ) {
				return $persisted;
			}
			$hash = wpagent_state_hash_for_options( array( WPAGENT_COMPANION_OPT_SITE_CONTEXT ) );
			return is_wp_error( $hash ) ? $hash : array( 'context' => $context, 'verified' => true, 'state_hash' => $hash );
		},
		'wpagent_site_context_persist_failed',
		__( 'Site Context konnte nicht verifiziert gespeichert werden.', 'wp-agent-companion' )
	);
}
