<?php

namespace WeDevs\Wpuf\Pro\AI_Review\Providers;

/**
 * Google AI Provider
 *
 * Handles API calls to Google's Gemini AI services
 *
 * @since 4.2.9
 */
class Google_Provider extends Abstract_Provider {

	/**
	 * Max output tokens for Google API
	 *
	 * @var int
	 */
	protected $max_tokens = 2048;

	/**
	 * Make API call to Google
	 *
	 * @since 4.2.9
	 * @param string $endpoint API endpoint
	 * @param string $api_key  API key
	 * @param string $model    Model to use
	 * @param string $prompt   Review prompt
	 * @return string API response
	 * @throws \Exception
	 */
	public function make_api_call( $endpoint, $api_key, $model, $prompt ) {
		// Google endpoint includes {model} placeholder that needs to be replaced
		$endpoint = str_replace( '{model}', $model, $endpoint );

		$headers = [
			'Content-Type'    => 'application/json',
			'x-goog-api-key'  => $api_key,
		];

		$args = [
			'headers' => $headers,
			'body'    => json_encode( $this->build_request_body( $prompt ) ),
		];

		$response = $this->make_request( $endpoint, $args );

		$body = wp_remote_retrieve_body( $response );

		return $this->parse_response( $body );
	}

	/**
	 * Validate Google API key format
	 *
	 * Google API keys are alphanumeric strings
	 *
	 * @since 4.2.9
	 * @param string $api_key API key to validate
	 * @return bool True if valid format
	 */
	public function validate_api_key( $api_key ) {
		// Google API keys are alphanumeric, typically 39 characters
		return ! empty( $api_key ) && preg_match( '/^[a-zA-Z0-9\-_]{35,45}$/', $api_key );
	}

	/**
	 * Get request headers for Google API
	 *
	 * @since 4.2.9
	 * @return array Request headers
	 */
	protected function get_request_headers() {
		return [
			'Content-Type'    => 'application/json',
			'x-goog-api-key'  => $this->api_key,
		];
	}

	/**
	 * Parse Google API response
	 *
	 * @since 4.2.9
	 * @param string $response_body Response body
	 * @return string Parsed response content
	 * @throws \Exception
	 */
	protected function parse_response( $response_body ) {
		$decoded = json_decode( $response_body, true );

		// Check if we have a valid response with content
		if ( isset( $decoded['candidates'][0]['content']['parts'][0]['text'] ) ) {
			return $decoded['candidates'][0]['content']['parts'][0]['text'];
		}

		// Check for finish reason and handle accordingly
		if ( isset( $decoded['candidates'][0]['finishReason'] ) ) {
			$finish_reason = $decoded['candidates'][0]['finishReason'];

			if ( $finish_reason === 'MAX_TOKENS' ) {
				throw new \Exception( 'Google API response truncated due to max tokens limit. Try reducing the prompt length or increasing maxOutputTokens.' );
			} elseif ( $finish_reason === 'SAFETY' ) {
				throw new \Exception( 'Google API response blocked due to safety concerns' );
			} elseif ( $finish_reason === 'RECITATION' ) {
				throw new \Exception( 'Google API response blocked due to recitation concerns' );
			} else {
				throw new \Exception( 'Google API response finished with reason: ' . $finish_reason );
			}
		}

		// Check if there's an error in the response
		if ( isset( $decoded['error'] ) ) {
			$error_message = isset( $decoded['error']['message'] ) ? $decoded['error']['message'] : 'Unknown error';
			throw new \Exception( 'Google API error: ' . $error_message );
		}

		throw new \Exception( 'Invalid Google API response - no content found' );
	}

	/**
	 * Build request body for Google API
	 *
	 * @since 4.2.9
	 * @param string $prompt Review prompt
	 * @return array Request body
	 */
	protected function build_request_body( $prompt ) {
		return [
			'contents'         => [
				[
					'parts' => [
						[
							'text' => $prompt,
						],
					],
				],
			],
			'generationConfig' => [
				'maxOutputTokens' => $this->max_tokens,
				'temperature'     => $this->temperature,
			],
		];
	}
}
