<?php
/**
 * Assign Menu to Location Tool.
 *
 * Allows the agent to assign a navigation menu to a theme location. Updates
 * nav_menu_locations theme mod.
 *
 * @package   Agenistrator
 * @since     1.0.0
 * @author    Alex Ruban <alex@maximum.guru>
 * @author    Maximum Software Inc <contact@maximum.software>
 * @license   GPL-3.0-only
 * @link      https://agenistrator.com/
 *
 * SPDX-FileCopyrightText: 2025-2026 Alex Ruban <alex@maximum.guru>
 * SPDX-FileCopyrightText: 2025-2026 Maximum Software Inc <contact@maximum.software>
 * SPDX-License-Identifier: GPL-3.0-only
 */

namespace Agenistrator;

// Direct access prevention
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Assign_Menu_To_Location_Tool class.
 */
class Assign_Menu_To_Location_Tool extends Tool {

	/**
	 * Get the tool ID.
	 *
	 * @return     string The tool ID.
	 * @since     1.0.0
	 */
	public function get_id() {
		return 'assign_menu_to_location';
	}

	/**
	 * Get the tool name.
	 *
	 * @return     string The tool name.
	 * @since     1.0.0
	 */
	public function get_name() {
		return __( 'Assign Menu to Location', 'agenistrator' );
	}

	/**
	 * Get the description of the tool.
	 *
	 * @return     string The description of the tool.
	 * @since     1.0.0
	 */
	public function get_description() {
		return 'Assigns a navigation menu to a theme location.';
	}

	/**
	 * Get the parameters for this tool.
	 *
	 * @return     array Parameters schema in JSON Schema format.
	 * @since     1.0.0
	 */
	public function get_parameters() {
		return array(
			'type'       => 'object',
			'properties' => array(
				'menu_id'  => array(
					'type'        => 'integer',
					'description' => 'The ID of the menu to assign',
				),
				'location' => array(
					'type'        => 'string',
					'description' => 'The theme location slug to assign the menu to',
				),
			),
			'required'   => array( 'menu_id', 'location' ),
		);
	}

	/**
	 * Check if the current user has permission to execute this tool.
	 *
	 * @return     bool Whether the user has permission.
	 * @since     1.0.0
	 */
	public function current_user_can_execute() {
		return current_user_can( 'edit_theme_options' );
	}

	/**
	 * Check if this tool is read-only.
	 *
	 * @return     bool False - this tool modifies data.
	 * @since     1.0.0
	 */
	public function is_read_only() {
		return false;
	}

	/**
	 * Execute the tool with the given arguments.
	 *
	 * @param      array $args The arguments for the tool.
	 * @return     array The result of executing the tool.
	 * @since     1.0.0
	 */
	protected function execute( $args ) {
		$menu_id  = intval( $args['menu_id'] );
		$location = sanitize_text_field( $args['location'] );

		// Verify menu exists.
		$menu = wp_get_nav_menu_object( $menu_id );
		if ( ! $menu ) {
			return $this->error_response( "Menu with ID {$menu_id} not found." );
		}

		// Verify location is registered.
		$registered_locations = get_registered_nav_menus();

		// Check if theme supports classic menus (block themes typically don't register menu locations)
		if ( empty( $registered_locations ) ) {
			$is_block_theme = function_exists( 'wp_is_block_theme' ) && wp_is_block_theme();
			if ( $is_block_theme ) {
				return $this->error_response(
					\__( 'This theme is a block theme and does not use classic menu locations. Block themes use the Navigation block instead. Menus can still be created and used with Navigation blocks, but cannot be assigned to theme locations.', 'agenistrator' )
				);
			}
			return $this->error_response(
				\__( 'No menu locations are registered by the current theme.', 'agenistrator' )
			);
		}

		if ( ! isset( $registered_locations[ $location ] ) ) {
			return $this->error_response( "Location '{$location}' is not registered." );
		}

		// Get current locations and update.
		$locations              = get_nav_menu_locations();
		$locations[ $location ] = $menu_id;

		set_theme_mod( 'nav_menu_locations', $locations );

		return $this->success_response(
			'Menu assigned to location successfully',
			array(
				'menu_id'   => $menu_id,
				'menu_name' => $menu->name,
				'location'  => $location,
				'assigned'  => true,
			)
		);
	}
}
