<?php
/**
 * @package Hafenstudios\Core
 */

namespace Hafenstudios\Core\Ai;

defined( 'ABSPATH' ) || exit;

/**
 * Ergebnis eines LLM-Aufrufs (HANS-KI-KONZEPT Abschnitt 3).
 *
 * Der AiClient liefert IMMER ein AiResult und wirft nie eine Ausnahme nach
 * aussen (Leitplanke "stiller Rueckfall"): Bei jedem Fehler steht `ok` auf
 * false, `error` traegt eine kurze Meldung und `permanent` unterscheidet einen
 * dauerhaften Fehler (kein Retry sinnvoll, z.B. ungueltiger Schluessel) von
 * einem voruebergehenden (Timeout, Ratelimit).
 *
 * Verbrauchszaehler (input_tokens/output_tokens) und Proxy-Kontingent
 * (quota_used/quota_limit) werden mitgefuehrt, soweit der Anbieter sie liefert;
 * -1 bedeutet "nicht bekannt".
 */
final class AiResult {

	/**
	 * Erfolg.
	 *
	 * @var bool
	 */
	public bool $ok;

	/**
	 * Erzeugter Text (bei Erfolg).
	 *
	 * @var string
	 */
	public string $text;

	/**
	 * Fehlermeldung (bei Misserfolg).
	 *
	 * @var string
	 */
	public string $error;

	/**
	 * Dauerhafter Fehler (kein Retry sinnvoll)?
	 *
	 * @var bool
	 */
	public bool $permanent;

	/**
	 * Eingabe-Tokens laut Anbieter (-1 = unbekannt).
	 *
	 * @var int
	 */
	public int $input_tokens;

	/**
	 * Ausgabe-Tokens laut Anbieter (-1 = unbekannt).
	 *
	 * @var int
	 */
	public int $output_tokens;

	/**
	 * Verbrauchtes Proxy-Kontingent (-1 = unbekannt/nicht Proxy).
	 *
	 * @var int
	 */
	public int $quota_used;

	/**
	 * Proxy-Kontingent-Obergrenze (-1 = unbekannt/nicht Proxy).
	 *
	 * @var int
	 */
	public int $quota_limit;

	/**
	 * @param bool   $ok            Erfolg.
	 * @param string $text          Erzeugter Text.
	 * @param string $error         Fehlermeldung.
	 * @param bool   $permanent     Dauerhafter Fehler?
	 * @param int    $input_tokens  Eingabe-Tokens (-1 = unbekannt).
	 * @param int    $output_tokens Ausgabe-Tokens (-1 = unbekannt).
	 * @param int    $quota_used    Verbrauchtes Kontingent (-1 = unbekannt).
	 * @param int    $quota_limit   Kontingent-Obergrenze (-1 = unbekannt).
	 */
	public function __construct( bool $ok, string $text = '', string $error = '', bool $permanent = false, int $input_tokens = -1, int $output_tokens = -1, int $quota_used = -1, int $quota_limit = -1 ) {
		$this->ok            = $ok;
		$this->text          = $text;
		$this->error         = $error;
		$this->permanent     = $permanent;
		$this->input_tokens  = $input_tokens;
		$this->output_tokens = $output_tokens;
		$this->quota_used    = $quota_used;
		$this->quota_limit   = $quota_limit;
	}

	/**
	 * Erfolgreiches Ergebnis.
	 *
	 * @param string $text          Erzeugter Text.
	 * @param int    $input_tokens  Eingabe-Tokens (-1 = unbekannt).
	 * @param int    $output_tokens Ausgabe-Tokens (-1 = unbekannt).
	 * @return AiResult
	 */
	public static function success( string $text, int $input_tokens = -1, int $output_tokens = -1 ): AiResult {
		return new self( true, $text, '', false, $input_tokens, $output_tokens );
	}

	/**
	 * Voruebergehender Fehler (Retry sinnvoll).
	 *
	 * @param string $error Fehlermeldung.
	 * @return AiResult
	 */
	public static function transient( string $error ): AiResult {
		return new self( false, '', $error, false );
	}

	/**
	 * Dauerhafter Fehler (kein Retry sinnvoll).
	 *
	 * @param string $error Fehlermeldung.
	 * @return AiResult
	 */
	public static function permanent( string $error ): AiResult {
		return new self( false, '', $error, true );
	}

	/**
	 * Abgeschaltet: der KI-Hauptschalter ist aus. Kein HTTP-Aufruf.
	 *
	 * Dauerhaft, damit Aufrufer nicht wiederholen; das Fehlerkuerzel "disabled"
	 * erlaubt es, diesen Fall vom echten Anbieterfehler zu unterscheiden.
	 *
	 * @return AiResult
	 */
	public static function disabled(): AiResult {
		return new self( false, '', 'disabled', true );
	}

	/**
	 * Verbleibendes Proxy-Kontingent (-1 = unbekannt).
	 *
	 * @return int
	 */
	public function quota_remaining(): int {
		if ( $this->quota_limit < 0 || $this->quota_used < 0 ) {
			return -1;
		}
		$remaining = $this->quota_limit - $this->quota_used;
		return $remaining > 0 ? $remaining : 0;
	}
}
