<?php
/**
 * Ability: wp-agent/assign-menu-location
 *
 * Weist ein Menü einer vom aktiven Theme registrierten Position (nav menu
 * location) zu. Positionen sind KEINE Datenbank-Entität: sie kommen aus dem
 * Laufzeit-Array $_wp_registered_nav_menus, das nur ein Theme (oder ein
 * Must-Use-Plugin) über register_nav_menu()/register_nav_menus() befüllt,
 * typischerweise im 'after_setup_theme'-Hook. Die eigentliche Zuordnung
 * Position -> Menü-ID liegt dagegen im Theme-Mod 'nav_menu_locations' (ein
 * assoziatives Array, per get_theme_mod()/set_theme_mod() gelesen/geschrieben)
 * und übersteht damit auch einen Theme-Wechsel nicht automatisch.
 *
 * Permission-Callback wpagent_perm_edit_theme_options ist in create-menu.php
 * definiert (siehe dortiger Kommentar); diese Datei referenziert sie nur.
 *
 * @package WPAgentCompanion
 */

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

function wpagent_ability_assign_menu_location(): array {
	return array(
		'label'               => __( 'Menü einer Position zuweisen', 'wp-agent-companion' ),
		'description'         => __( 'Weist ein Menü einer vom aktiven Theme registrierten Position zu (z. B. "primary"). Die Position wird gegen die tatsächlich registrierten Positionen validiert. Verifiziert per Re-Read über den Theme-Mod nav_menu_locations.', 'wp-agent-companion' ),
		'category'            => 'wp-agent',
		'input_schema'        => array(
			'type'       => 'object',
			'properties' => array(
				'menu_id'  => array( 'type' => 'integer' ),
				'location' => array(
					'type'        => 'string',
					'description' => __( 'Muss eine vom aktiven Theme registrierte Position sein (siehe get_registered_nav_menus()).', 'wp-agent-companion' ),
				),
			),
			'required'   => array( 'menu_id', 'location' ),
		),
		'output_schema'       => array(
			'type'       => 'object',
			'properties' => array(
				'location'         => array( 'type' => 'string' ),
				'menu_id'          => array( 'type' => 'integer' ),
				'previous_menu_id' => array( 'type' => 'integer' ),
				'verified'         => array( 'type' => 'boolean' ),
			),
		),
		'execute_callback'    => 'wpagent_exec_assign_menu_location',
		'permission_callback' => 'wpagent_perm_edit_theme_options',
		'meta'                => array(
			'show_in_rest' => true,
			'annotations'  => array(
				'readonly'    => false,
				'destructive' => false,
				// Ein reiner Set-Vorgang auf eine einzelne assoziative
				// Array-Position: wiederholte Aufrufe mit demselben Input
				// konvergieren immer auf denselben Endzustand.
				'idempotent'  => true,
			),
		),
	);
}

/**
 * @param mixed $input
 * @return array|WP_Error
 */
function wpagent_exec_assign_menu_location( $input ) {
	$input    = is_array( $input ) ? $input : array();
	$menu_id  = (int) ( $input['menu_id'] ?? 0 );
	$location = trim( (string) ( $input['location'] ?? '' ) );

	if ( '' === $location ) {
		return new WP_Error( 'wpagent_missing_location', __( 'location fehlt.', 'wp-agent-companion' ), array( 'status' => 400 ) );
	}

	$registered = get_registered_nav_menus();
	if ( ! array_key_exists( $location, $registered ) ) {
		return new WP_Error(
			'wpagent_bad_location',
			sprintf(
				/* translators: 1: submitted menu location, 2: comma-separated registered locations. */
				__( 'Unbekannte Menü-Position "%1$s". Vom aktiven Theme registriert: %2$s.', 'wp-agent-companion' ),
				$location,
				array() === $registered ? __( '(keine)', 'wp-agent-companion' ) : implode( ', ', array_keys( $registered ) )
			),
			array( 'status' => 400 )
		);
	}

	$menu = wp_get_nav_menu_object( $menu_id );
	if ( ! $menu ) {
		return new WP_Error( 'wpagent_no_menu', __( 'Menü nicht gefunden.', 'wp-agent-companion' ), array( 'status' => 404 ) );
	}

	$locations = get_theme_mod( 'nav_menu_locations', array() );
	if ( ! is_array( $locations ) ) {
		$locations = array();
	}
	$previous                = isset( $locations[ $location ] ) ? (int) $locations[ $location ] : 0;
	$locations[ $location ]  = $menu_id;
	set_theme_mod( 'nav_menu_locations', $locations );

	$fresh    = get_theme_mod( 'nav_menu_locations', array() );
	$verified = ( is_array( $fresh ) && isset( $fresh[ $location ] ) && $menu_id === (int) $fresh[ $location ] );

	return array(
		'location'         => $location,
		'menu_id'          => $menu_id,
		'previous_menu_id' => $previous,
		'verified'         => $verified,
	);
}
