<?php

namespace AtlasAiDev\Awfah\Abilities;

use WP_Error;
use WP_REST_Request;

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

/**
 * Registers WordPress user CRUD abilities using the Abilities API.
 *
 * @package AtlasAiDev\Awfah\Abilities
 */
class Users_Abilities {

	public static function get_abilities(): array {
		return [
			[
				'id'           => 'awfah-users/wp-users-search',
				'module'       => 'users_manager',
				'label'        => __( 'Search Users', 'ai-workflow-automation-ai-agent-hub' ),
				'description'  => __( 'Search and filter WordPress users with pagination.', 'ai-workflow-automation-ai-agent-hub' ),
				'category'     => 'awfah-users',
				'input_schema' => [
					'type'       => 'object',
					'properties' => [
						'search'   => [
							'type'        => 'string',
							'description' => __( 'Limit results to those matching a string.', 'ai-workflow-automation-ai-agent-hub' ),
						],
						'page'     => [
							'type'    => 'integer',
							'default' => 1,
							'minimum' => 1,
						],
						'per_page' => [
							'type'    => 'integer',
							'default' => 10,
							'minimum' => 1,
							'maximum' => 100,
						],
						'context'  => [
							'type'    => 'string',
							'enum'    => [ 'view', 'embed', 'edit' ],
							'default' => 'view',
						],
						'roles'    => [
							'type'        => 'array',
							'description' => __( 'Limit result set to users matching at least one specific role.', 'ai-workflow-automation-ai-agent-hub' ),
							'items'       => [ 'type' => 'string' ],
						],
						'orderby'  => [
							'type'    => 'string',
							'enum'    => [ 'id', 'include', 'name', 'registered_date', 'slug', 'email', 'url' ],
							'default' => 'name',
						],
						'order'    => [
							'type'    => 'string',
							'enum'    => [ 'asc', 'desc' ],
							'default' => 'asc',
						],
					],
				],
				'meta'         => [
					'show_in_rest' => true,
					'mcp'          => [ 'public' => true ],
					'uri'          => 'wordpress://ai-agent-hub/users',
					'mimeType'     => 'application/json',
				],
			],
			[
				'id'           => 'awfah-users/wp-get-user',
				'module'       => 'users_manager',
				'label'        => __( 'Get User', 'ai-workflow-automation-ai-agent-hub' ),
				'description'  => __( 'Get a WordPress user by ID.', 'ai-workflow-automation-ai-agent-hub' ),
				'category'     => 'awfah-users',
				'input_schema' => [
					'type'       => 'object',
					'required'   => [ 'id' ],
					'properties' => [
						'id'      => [
							'type'        => 'integer',
							'description' => __( 'The ID of the user.', 'ai-workflow-automation-ai-agent-hub' ),
						],
						'context' => [
							'type'    => 'string',
							'enum'    => [ 'view', 'embed', 'edit' ],
							'default' => 'view',
						],
					],
				],
				'meta'         => [
					'show_in_rest' => true,
					'mcp'          => [ 'public' => true ],
					'uri'          => 'wordpress://ai-agent-hub/users/{id}',
					'mimeType'     => 'application/json',
				],
			],
			[
				'id'           => 'awfah-users/wp-add-user',
				'module'       => 'users_manager',
				'label'        => __( 'Add User', 'ai-workflow-automation-ai-agent-hub' ),
				'description'  => __( 'Add a new WordPress user.', 'ai-workflow-automation-ai-agent-hub' ),
				'category'     => 'awfah-users',
				'input_schema' => [
					'type'       => 'object',
					'required'   => [ 'username', 'email', 'password' ],
					'properties' => [
						'username'   => [
							'type' => 'string',
						],
						'name'       => [
							'type' => 'string',
						],
						'first_name' => [
							'type' => 'string',
						],
						'last_name'  => [
							'type' => 'string',
						],
						'email'      => [
							'type'   => 'string',
							'format' => 'email',
						],
						'url'        => [
							'type'   => 'string',
							'format' => 'uri',
						],
						'description' => [
							'type' => 'string',
						],
						'nickname'   => [
							'type' => 'string',
						],
						'slug'       => [
							'type' => 'string',
						],
						'roles'      => [
							'type'  => 'array',
							'items' => [ 'type' => 'string' ],
						],
						'password'   => [
							'type' => 'string',
						],
					],
				],
				'meta'         => [
					'show_in_rest' => true,
					'mcp'          => [ 'public' => true ],
				],
			],
			[
				'id'           => 'awfah-users/wp-update-user',
				'module'       => 'users_manager',
				'label'        => __( 'Update User', 'ai-workflow-automation-ai-agent-hub' ),
				'description'  => __( 'Update a WordPress user by ID.', 'ai-workflow-automation-ai-agent-hub' ),
				'category'     => 'awfah-users',
				'input_schema' => [
					'type'       => 'object',
					'required'   => [ 'id' ],
					'properties' => [
						'id'          => [
							'type'        => 'integer',
							'description' => __( 'The ID of the user to update.', 'ai-workflow-automation-ai-agent-hub' ),
						],
						'name'        => [ 'type' => 'string' ],
						'first_name'  => [ 'type' => 'string' ],
						'last_name'   => [ 'type' => 'string' ],
						'email'       => [ 'type' => 'string', 'format' => 'email' ],
						'url'         => [ 'type' => 'string', 'format' => 'uri' ],
						'description' => [ 'type' => 'string' ],
						'nickname'    => [ 'type' => 'string' ],
						'slug'        => [ 'type' => 'string' ],
						'roles'       => [ 'type' => 'array', 'items' => [ 'type' => 'string' ] ],
						'password'    => [ 'type' => 'string' ],
					],
				],
				'meta'         => [
					'show_in_rest' => true,
					'mcp'          => [ 'public' => true ],
				],
			],
			[
				'id'           => 'awfah-users/wp-delete-user',
				'module'       => 'users_manager',
				'label'        => __( 'Delete User', 'ai-workflow-automation-ai-agent-hub' ),
				'description'  => __( 'Delete a WordPress user by ID.', 'ai-workflow-automation-ai-agent-hub' ),
				'category'     => 'awfah-users',
				'input_schema' => [
					'type'       => 'object',
					'required'   => [ 'id' ],
					'properties' => [
						'id'       => [
							'type'        => 'integer',
							'description' => __( 'The ID of the user to delete.', 'ai-workflow-automation-ai-agent-hub' ),
						],
						'force'    => [
							'type'    => 'boolean',
							'default' => true,
						],
						'reassign' => [
							'type'        => 'integer',
							'description' => __( 'Reassign the deleted user posts and links to this user ID.', 'ai-workflow-automation-ai-agent-hub' ),
						],
					],
				],
				'meta'         => [
					'show_in_rest' => true,
					'mcp'          => [ 'public' => true ],
				],
			],
			[
				'id'           => 'awfah-users/wp-get-current-user',
				'module'       => 'users_manager',
				'label'        => __( 'Get Current User', 'ai-workflow-automation-ai-agent-hub' ),
				'description'  => __( 'Get the current logged-in user.', 'ai-workflow-automation-ai-agent-hub' ),
				'category'     => 'awfah-users',
				'input_schema' => [
					'type'       => 'object',
					'properties' => [
						'context' => [
							'type'    => 'string',
							'enum'    => [ 'view', 'embed', 'edit' ],
							'default' => 'view',
						],
					],
				],
				'meta'         => [
					'show_in_rest' => true,
					'mcp'          => [ 'public' => true ],
					'uri'          => 'wordpress://ai-agent-hub/users/me',
					'mimeType'     => 'application/json',
				],
			],
			[
				'id'           => 'awfah-users/wp-update-current-user',
				'module'       => 'users_manager',
				'label'        => __( 'Update Current User', 'ai-workflow-automation-ai-agent-hub' ),
				'description'  => __( 'Update the current logged-in user.', 'ai-workflow-automation-ai-agent-hub' ),
				'category'     => 'awfah-users',
				'input_schema' => [
					'type'       => 'object',
					'properties' => [
						'name'        => [ 'type' => 'string' ],
						'first_name'  => [ 'type' => 'string' ],
						'last_name'   => [ 'type' => 'string' ],
						'email'       => [ 'type' => 'string', 'format' => 'email' ],
						'url'         => [ 'type' => 'string', 'format' => 'uri' ],
						'description' => [ 'type' => 'string' ],
						'nickname'    => [ 'type' => 'string' ],
						'password'    => [ 'type' => 'string' ],
					],
				],
				'meta'         => [
					'show_in_rest' => true,
					'mcp'          => [ 'public' => true ],
				],
			],
		];
	}

	public static function register(): void {
		if ( ! function_exists( 'wp_register_ability' ) ) {
			return;
		}

		$callbacks = [
			'awfah-users/wp-users-search'       => [ __CLASS__, 'execute_search_users' ],
			'awfah-users/wp-get-user'            => [ __CLASS__, 'execute_get_user' ],
			'awfah-users/wp-add-user'            => [ __CLASS__, 'execute_add_user' ],
			'awfah-users/wp-update-user'         => [ __CLASS__, 'execute_update_user' ],
			'awfah-users/wp-delete-user'         => [ __CLASS__, 'execute_delete_user' ],
			'awfah-users/wp-get-current-user'    => [ __CLASS__, 'execute_get_current_user' ],
			'awfah-users/wp-update-current-user' => [ __CLASS__, 'execute_update_current_user' ],
		];

		foreach ( self::get_abilities() as $ability ) {
			$config = $ability;
			$id     = $ability['id'];
			unset( $config['id'], $config['module'] );

			// Workaround: MCP ResourcesHandler calls execute() with no input.
			// Adding default empty object prevents "input is not of type object" validation error.
			if ( isset( $config['meta']['uri'], $config['input_schema']['type'] ) && 'object' === $config['input_schema']['type'] ) {
				$config['input_schema']['default'] = (object) [];
			}

			wp_register_ability(
				$id,
				array_merge(
					$config,
					[
						'execute_callback'    => $callbacks[ $id ],
						'permission_callback' => static function () use ( $id ) {
							return \AtlasAiDev\Awfah\Plugin::check_ability_access( $id, 'list_users' );
						},
					]
				)
			);
		}
	}

	public static function execute_search_users( $input = null ) {
		return self::dispatch_rest( 'GET', '/wp/v2/users', (array) $input );
	}

	public static function execute_get_user( $input = null ) {
		$input = (array) $input;
		$id    = isset( $input['id'] ) ? (int) $input['id'] : 0;
		unset( $input['id'] );
		return self::dispatch_rest( 'GET', '/wp/v2/users/' . $id, $input );
	}

	public static function execute_add_user( $input = null ) {
		return self::dispatch_rest( 'POST', '/wp/v2/users', (array) $input );
	}

	public static function execute_update_user( $input = null ) {
		$input = (array) $input;
		$id    = isset( $input['id'] ) ? (int) $input['id'] : 0;
		unset( $input['id'] );
		return self::dispatch_rest( 'POST', '/wp/v2/users/' . $id, $input );
	}

	public static function execute_delete_user( $input = null ) {
		$input = (array) $input;
		$id    = isset( $input['id'] ) ? (int) $input['id'] : 0;
		unset( $input['id'] );
		return self::dispatch_rest( 'DELETE', '/wp/v2/users/' . $id, $input );
	}

	public static function execute_get_current_user( $input = null ) {
		return self::dispatch_rest( 'GET', '/wp/v2/users/me', (array) $input );
	}

	public static function execute_update_current_user( $input = null ) {
		return self::dispatch_rest( 'POST', '/wp/v2/users/me', (array) $input );
	}

	private static function dispatch_rest( string $method, string $route, array $params = [] ) {
		$request = new WP_REST_Request( $method, $route );
		foreach ( $params as $key => $value ) {
			$request->set_param( $key, $value );
		}
		$response = rest_do_request( $request );
		if ( $response->is_error() ) {
			$error = $response->as_error();
			return new WP_Error( $error->get_error_code(), $error->get_error_message(), [ 'status' => $response->get_status() ] );
		}
		$data = $response->get_data();
		if ( is_array( $data ) && array_is_list( $data ) ) {
			return [ 'results' => $data ];
		}
		return $data;
	}
}
