<?php

namespace Limb_Chatbot\Includes\Api\V1\Controllers;

use Exception;
use Limb_Chatbot\Includes\Data_Objects\Vector_Index;
use Limb_Chatbot\Includes\Data_Objects\Vector_Index_Meta;
use Limb_Chatbot\Includes\Services\Helper;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

/**
 * REST API controller for managing vector_index metas.
 *
 * Handles retrieval and batch updates of vector_index meta entries.
 *
 * @since 1.0.0
 */
class Vector_Index_Metas_Controller extends Rest_Controller {

	/**
	 * REST base route with vector_index ID parameter.
	 *
	 * @var string
	 * @since 1.0.0
	 */
	protected $rest_base = 'vector_indexes/(?P<vector_index_id>[\d]+)/metas';

	/**
	 * Registers REST API routes for vector_index metas.
	 *
	 * @since 1.0.0
	 */
	public function register_routes(): void {
		register_rest_route( $this->namespace, '/' . $this->rest_base, array(
			array(
				'methods'             => WP_REST_Server::READABLE,
				'callback'            => array( $this, 'get_items' ),
				'permission_callback' => array( $this, 'permission_callback' ),
				'args'                => array_merge( $this->get_vector_index_id_arg(),
					$this->get_collection_params() ),
			),
			array(
				'methods'             => WP_REST_Server::EDITABLE,
				'callback'            => array( $this, 'update_item' ),
				'permission_callback' => array( $this, 'permission_callback' ),
				'args'                => array( $this->get_endpoint_args_for_item_schema() ),
			),
			'schema' => $this->get_item_schema()
		) );
	}

	/**
	 * Returns the argument definition for validating vector_index_id parameter.
	 *
	 * @return array Argument definition.
	 * @since 1.0.0
	 */
	private function get_vector_index_id_arg(): array {
		return array(
			'vector_index_id' => array(
				'type'              => 'integer',
				'validate_callback' => function ( $value, $request, $param ) {
					return ! empty( Vector_Index::count( [ 'id' => $value ] ) );
				}
			)
		);
	}

	/**
	 * Returns collection query parameters including meta_key.
	 *
	 * @return array Collection query parameters.
	 * @since 1.0.0
	 */
	public function get_collection_params() {
		$parent = parent::get_collection_params();

		return array_merge( $parent, array(
			'meta_key' => array(
				'type'              => array( 'string', 'array' ),
				'description'       => __( 'Key of the resource', 'limb-chatbot' ),
				'required'          => true,
				'sanitize_callback' => function ( $value ) {
					if ( is_string( $value ) ) {
						return sanitize_text_field( $value );
					} else {
						return array_map( function ( $item ) {
							return sanitize_text_field( $item );
						}, $value );
					}
				},
				'validate_callback' => function ( $value, $argument, $request ) {
					return is_string( $value ) || is_array( $value );
				}
			),
		) );
	}

	/**
	 * Returns JSON schema for vector_index meta resource.
	 *
	 * Defines structure and validation for vector_index meta.
	 *
	 * @return array JSON schema array.
	 * @since 1.0.0
	 */
	public function get_item_schema(): array {
		if ( $this->schema ) {
			// Since WordPress 5.3, the schema can be cached in the $schema property.
			return $this->schema;
		}
		$this->schema = array(
			'$schema'    => 'http://json-schema.org/draft-04/schema#',
			'title'      => 'Vector_Index Meta',
			'type'       => 'object',
			'properties' => array(
				'id'              => array(
					'description'       => __( 'Unique identifier for the resource.', 'limb-chatbot' ),
					'type'              => 'integer',
					'context'           => array( 'view', 'edit' ),
					'readonly'          => true,
					'sanitize_callback' => 'absint',
				),
				'vector_index_id' => array(
					'description' => __( 'The vector_index id.', 'limb-chatbot' ),
					'type'        => 'integer',
					'context'     => array( 'view', 'edit' ),
					'arg_options' => array(
						'validate_callback' => $this->get_vector_index_id_arg()['vector_index_id']['validate_callback'],
					)
				),
				'meta_key'        => array(
					'description'       => __( 'Key of the resource', 'limb-chatbot' ),
					'type'              => 'string',
					'required'          => true,
					'sanitize_callback' => 'sanitize_text_field',
					'arg_options'       => array(
						'sanitize_callback' => 'sanitize_key',
						'validate_callback' => function ( $value ) {
							return ! empty( $value ) && is_string( $value );
						}
					)
				),
				'meta_value'      => array(
					'description' => __( 'Value of the resource', 'limb-chatbot' ),
					'type'        => array( 'string', 'integer', 'array' ),
					'required'    => true,
				)
			),
		);

		return $this->schema;
	}

	public function update_item( $request ) {
		try {
			$where  = [
				'vector_index_id' => $request->get_param( 'vector_index_id' ),
				'meta_key'        => $request->get_param( 'meta_key' ),
			];
			$update = [
				'meta_value' => $request->get_param( 'meta_value' )
			];

			return rest_ensure_response( Vector_Index_Meta::update( $where, $update ) );
		} catch ( Exception $e ) {
			Helper::log( $e, __METHOD__ );

			return Helper::get_wp_error( $e );
		}
	}

	/**
	 * Retrieves vector_index meta items based on query parameters.
	 *
	 * @param  WP_REST_Request  $request  Incoming REST request.
	 *
	 * @return WP_REST_Response|WP_Error REST response or error.
	 * @since 1.0.0
	 */
	public function get_items( $request ) {
		try {
			return rest_ensure_response( Vector_Index_Meta::where( $request->get_query_params() + [ 'vector_index_id' => $request->get_param( 'vector_index_id' ) ] )->get() );
		} catch ( Exception $e ) {
			Helper::log( $e, __METHOD__ );

			return Helper::get_wp_error( $e );
		}
	}
}