<?php
/**
 * LLM Client.
 *
 * Thin client for an OpenAI-compatible chat completions endpoint. Admin-
 * triggered only, with a sane timeout and graceful errors (including the
 * free-tier 429 rate-limit case). Never called on front-end requests.
 *
 * @package Platform\Helm\Core
 */

declare( strict_types = 1 );

namespace Platform\Helm\Core;

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

final class LlmClient {

	/**
	 * Send a chat request. Returns the assistant text, or a WP_Error.
	 *
	 * @param array<int,array{role:string,content:string}> $messages
	 * @param array<string,mixed>                          $opts
	 * @return string|\WP_Error
	 */
	public static function chat( array $messages, array $opts = [] ) {
		$key = LlmSettings::key();
		if ( '' === $key ) {
			return new \WP_Error( 'no_key', __( 'No AI API key configured. Add one under Helm → AI Assistant.', 'platform-helm' ) );
		}

		$endpoint = rtrim( LlmSettings::base_url(), '/' ) . '/chat/completions';
		$body     = [
			'model'       => LlmSettings::model(),
			'messages'    => $messages,
			'temperature' => $opts['temperature'] ?? 0.6,
			'max_tokens'  => (int) ( $opts['max_tokens'] ?? 600 ),
		];

		$resp = wp_remote_post( $endpoint, [
			'timeout' => 30,
			'headers' => [
				'Authorization' => 'Bearer ' . $key,
				'Content-Type'  => 'application/json',
			],
			'body'    => wp_json_encode( $body ),
		] );

		if ( is_wp_error( $resp ) ) {
			return $resp;
		}

		$code = (int) wp_remote_retrieve_response_code( $resp );
		$data = json_decode( (string) wp_remote_retrieve_body( $resp ), true );

		if ( 429 === $code ) {
			return new \WP_Error( 'rate_limit', __( 'AI rate limit reached. Wait a minute and try again (free tiers cap requests per minute).', 'platform-helm' ) );
		}
		if ( $code < 200 || $code >= 300 ) {
			$msg = is_array( $data ) && isset( $data['error']['message'] )
				? (string) $data['error']['message']
				: sprintf( /* translators: %d HTTP code */ __( 'AI request failed (HTTP %d).', 'platform-helm' ), $code );
			return new \WP_Error( 'api_error', $msg );
		}

		$text = $data['choices'][0]['message']['content'] ?? '';
		if ( ! is_string( $text ) || '' === trim( $text ) ) {
			return new \WP_Error( 'empty', __( 'The AI returned an empty response. Try again.', 'platform-helm' ) );
		}
		return trim( $text );
	}
}
