<?php
/**
 * Abstract base for all embedding providers (Tier 1/2/3).
 *
 * Each provider turns an array of source strings into float vectors of `dims()`
 * dimensions. Tier 3 (Local) is unusual in that its `embed()` is called from
 * JavaScript — the PHP implementation only serves metadata and validates
 * incoming vectors.
 *
 * @package FindAstra
 */

defined( 'ABSPATH' ) || exit;

abstract class FindAstra_Provider_Base {

	abstract public function key(): string;
	abstract public function label(): string;
	abstract public function dims(): int;
	abstract public function model(): string;

	abstract public function requires_credentials(): bool;
	abstract public function is_configured(): bool;
	abstract public function is_server_side(): bool;

	/**
	 * @param string[] $inputs
	 * @return array<int,float[]>|WP_Error
	 */
	abstract public function embed( array $inputs ): array|WP_Error;

	/**
	 * Default match-quality gates this provider+model is empirically tuned
	 * for, before any `findastra_min_*` filter overrides. Search_Engine
	 * reads these as the base values for its gating math.
	 *
	 * Different embedding models pack their cosines into different ranges
	 * (`bge-small-en-v1.5` real-match cosines cluster around 0.60–0.68,
	 * `bge-m3` around 0.52–0.65), so a global hardcoded threshold rejects
	 * relevant matches on whichever model wasn't the calibration target.
	 *
	 * Default values here match the original v0.5 calibration on
	 * bge-small. Providers serving other models override.
	 *
	 * @return array{top: float, min: float, window: float}
	 */
	public function default_gates(): array {
		return array(
			'top'    => 0.60,
			'min'    => 0.55,
			'window' => 0.12,
		);
	}
}
