<?php
/**
 * Tier 3 — Local provider.
 *
 * The embedding model runs in the shopper's browser via transformers.js, so the
 * PHP side has no actual embedding work to do. The browser submits vectors to
 * the REST API, and this class validates / describes them.
 *
 * @package FindAstra
 */

defined( 'ABSPATH' ) || exit;

final class FindAstra_Provider_Local extends FindAstra_Provider_Base {

	public const KEY   = 'local';
	public const MODEL = 'Xenova/bge-small-en-v1.5';
	public const DIMS  = 384;

	public function key(): string { return self::KEY; }
	public function label(): string { return __( 'Local (in-browser)', 'findastra' ); }
	public function dims(): int { return self::DIMS; }
	public function model(): string { return self::MODEL; }
	public function requires_credentials(): bool { return false; }
	public function is_configured(): bool { return true; }
	public function is_server_side(): bool { return false; }

	/**
	 * Local provider can't embed in PHP. Callers should route through the JS worker.
	 *
	 * @param string[] $inputs
	 */
	public function embed( array $inputs ): array|WP_Error {
		unset( $inputs );
		return new WP_Error(
			'findastra_local_server_embed',
			__( 'The Local provider runs in the browser — server-side embed() is not supported.', 'findastra' )
		);
	}

	/**
	 * Validate a browser-submitted vector. Returns a clean float[] or WP_Error.
	 *
	 * @param mixed $vector
	 */
	public static function validate_vector( $vector ): array|WP_Error {
		if ( ! is_array( $vector ) ) {
			return new WP_Error(
				'findastra_invalid_vector',
				__( 'Vector must be an array.', 'findastra' ),
				array( 'status' => 400 )
			);
		}
		if ( count( $vector ) !== self::DIMS ) {
			return new WP_Error(
				'findastra_wrong_dims',
				/* translators: 1: expected dims, 2: actual dims */
				sprintf( __( 'Vector must have %1$d dimensions, got %2$d.', 'findastra' ), self::DIMS, count( $vector ) ),
				array( 'status' => 400 )
			);
		}
		$clean = array();
		foreach ( $vector as $v ) {
			if ( ! is_numeric( $v ) ) {
				return new WP_Error(
					'findastra_non_numeric_vector',
					__( 'Vector contains non-numeric values.', 'findastra' ),
					array( 'status' => 400 )
				);
			}
			$clean[] = (float) $v;
		}
		return $clean;
	}
}
