<?php

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

class Sabriel_AI_Provider_Gemini extends Sabriel_AI_Provider {

	const DEFAULT_MODEL = 'gemini-3.1-flash-lite';

	const ALIAS_MODELLI = [
		'gemini-3.1-pro' => 'gemini-3.1-pro-preview',
		'gemini-3-flash' => 'gemini-3-flash-preview',
	];

	public static function modello() {
		$sab_modello = self::modello_sicuro( Sabriel_Base::get( 'ai_model_gemini', '' ), self::DEFAULT_MODEL );
		return self::ALIAS_MODELLI[ $sab_modello ] ?? $sab_modello;
	}

	public function generate( $system_text, $contents, $generation_config ) {

		$sab_chiave = self::chiave_o_errore( 'sabriel_gemini_api_key', 'Gemini' );
		if ( isset( $sab_chiave['errore'] ) ) {
			return $sab_chiave['errore'];
		}
		$apikey = $sab_chiave['chiave'];

		$chiedi_json = ! empty( $generation_config[ self::CHIAVE_JSON ] )
			&& ! get_transient( self::chiave_profilo() );

		$url  = 'https://generativelanguage.googleapis.com/v1beta/models/' . rawurlencode( self::modello() ) . ':generateContent';
		$code = 0;
		$data = null;

		for ( $tentativo = 1; $tentativo <= 2; $tentativo++ ) {
			$payload = [
				'system_instruction' => [ 'parts' => [ [ 'text' => $system_text ] ] ],
				'contents'           => $contents,
				'generationConfig'   => self::config_generazione( $generation_config, $chiedi_json ),
			];

			$res = wp_remote_post( $url, [
				'headers'   => [
					'Content-Type'   => 'application/json',
					'x-goog-api-key' => $apikey,
				],
				'body'      => wp_json_encode( $payload ),
				'timeout'   => 22,
				'sslverify' => true,
			] );

			if ( is_wp_error( $res ) ) {
				return [ 'ok' => false, 'error' => $res->get_error_message(), 'http_status' => 502 ];
			}

			$code = wp_remote_retrieve_response_code( $res );
			$data = json_decode( wp_remote_retrieve_body( $res ), true );

			if ( 400 === $code && $chiedi_json && self::errore_sul_formato( $data ) ) {
				set_transient( self::chiave_profilo(), 1, WEEK_IN_SECONDS );
				$chiedi_json = false;
				continue;
			}
			break;
		}

		if ( 429 === $code || 503 === $code ) {
			return [ 'ok' => false, 'ai_overload' => true, 'error' => __( 'The AI service is very busy right now.', 'sabriel-ai' ), 'http_status' => 429 ];
		}

		if ( $code < 200 || $code >= 300 ) {
			$msg = self::errore_leggibile( 'Google Gemini', $code, $data, self::modello() );
			return [ 'ok' => false, 'error' => $msg, 'http_status' => $code ];
		}

		return [ 'ok' => true, 'data' => self::normalizza_risposta( $data ), 'http_status' => $code ?: 200 ];
	}

	private static function chiave_profilo() {
		return 'sabriel_ai_gem_json_' . md5( self::modello() );
	}

	private static function errore_sul_formato( $data ) {
		$msg = ( is_array( $data ) && isset( $data['error']['message'] ) && is_scalar( $data['error']['message'] ) )
			? (string) $data['error']['message']
			: '';
		if ( '' === $msg ) {
			return false;
		}
		return false !== stripos( $msg, 'responsemimetype' ) || false !== stripos( $msg, 'response_mime_type' );
	}

	private static function config_generazione( $generation_config, $chiedi_json = false ) {
		$config = array_merge(
			[ 'maxOutputTokens' => 700 ],
			is_array( $generation_config ) ? $generation_config : []
		);
		unset( $config['temperature'], $config['topP'], $config['topK'], $config[ self::CHIAVE_JSON ] );

		if ( $chiedi_json ) {
			$config['responseMimeType'] = 'application/json';
		}
		return $config;
	}

	private static function normalizza_risposta( $data ) {
		if ( ! is_array( $data ) || ! isset( $data['candidates'][0]['content']['parts'] ) ) {
			return $data;
		}

		$parti = $data['candidates'][0]['content']['parts'];
		if ( ! is_array( $parti ) || count( $parti ) < 2 ) {
			return $data;
		}

		$testo = '';
		foreach ( $parti as $parte ) {
			if ( isset( $parte['text'] ) && is_scalar( $parte['text'] ) ) {
				$testo .= (string) $parte['text'];
			}
		}

		$data['candidates'][0]['content']['parts'] = [ [ 'text' => $testo ] ];

		return $data;
	}
}
