<?php

namespace Limb_Chatbot\Includes\Vector_Dbs\Pinecone\Endpoints;

use Limb_Chatbot\Includes\Data_Objects\Vector;
use Limb_Chatbot\Includes\Exceptions\Exception;
use Limb_Chatbot\Includes\Services\Collection;


/**
 * Class Query_Endpoint
 *
 * Handles querying vectors from the Pinecone vector database.
 *
 * @package Limb_Chatbot\Includes\Vector_Dbs\Pinecone\Endpoints
 *
 * @since 1.0.0
 */
class Query_Endpoint extends Pinecone_Endpoint {

	/**
	 * @var string Host URL for the Pinecone query endpoint
	 *
	 * @since 1.0.0
	 */
	protected string $host;

	/**
	 * Query Pinecone with a vector and get the closest matches.
	 *
	 * @param  Vector  $vector  The vector object containing values to query with.
	 * @param  int  $count  The number of top results to return. Default is 3.
	 *
	 * @return Collection|null Collection of matched vectors or null on failure.
	 *
	 * @throws Exception
	 * @since 1.0.0
	 * @since 1.0.15 Added dimension support
	 */
	public function query( Vector $vector, int $count = 3 ): ?Collection {
		$values = maybe_unserialize( $vector->get_values() );

		if ( ! empty( $vector->dimension ) ) {
			$this->utility->set_dimension( $vector->dimension );
		} elseif ( is_array( $values ) ) {
			// Fallback: infer dimension from values count if not explicitly set
			$this->utility->set_dimension( count( $values ) );
		}

		$http_client = $this->http_client_factory();
		$this->define_host( $this->utility->get_global_utility()->get_vector_index() );

		$url = 'https://' . $this->host . '/query';

		$response = $http_client->post( $url, array(
			'headers' => $this->get_header(),
			'timeout' => $this->utility->get_timeout(),
			'body'    => json_encode( [
				'vector' => $values,
				'topK'   => $count,
				// TODO implement later: 'namespace', 'filter', 'includeValues'
			] ),
		) );

		return ( new Query\Response_Handler( $response, $http_client, $this ) )->get_vectors();
	}
}