<?php

declare(strict_types=1);

namespace ContextPaging;

use Psr\Http\Message\ResponseInterface;

/**
 * LLM-backed summarizer using OpenAI-compatible API.
 */
class LLMSummarizer implements SummarizerInterface
{
    private CompletionsClientInterface $client;
    private string $model;
    private string $systemPrompt;
    private int $maxTokens;
    private float $temperature;

    /**
     * @param CompletionsClientInterface $client The LLM client
     * @param string $model Model to use for summarization
     * @param string $systemPrompt System prompt for summarization
     * @param int $maxTokens Max tokens for summary output
     * @param float $temperature Temperature for generation
     */
    public function __construct(
        CompletionsClientInterface $client,
        string $model = 'HuggingFaceTB/SmolLM3-3B',
        string $systemPrompt = 'You are a summarization assistant. Summarize the given text concisely, preserving key information. Be brief but comprehensive.',
        int $maxTokens = 200,
        float $temperature = 0.3
    ) {
        $this->client = $client;
        $this->model = $model;
        $this->systemPrompt = $systemPrompt;
        $this->maxTokens = $maxTokens;
        $this->temperature = $temperature;
    }

    /**
     * Generate a summary of the content.
     *
     * @param string $content The content to summarize
     * @param array $context Optional context (role, previous messages, etc.)
     * @return string The summary
     */
    public function summarize(string $content, array $context = []): string
    {
        // Build the prompt
        $userPrompt = $this->buildUserPrompt($content, $context);

        $messages = [
            ['role' => 'system', 'content' => $this->systemPrompt],
            ['role' => 'user', 'content' => $userPrompt],
        ];

        $response = $this->client->chat($messages, [
            'model' => $this->model,
            'max_tokens' => $this->maxTokens,
            'temperature' => $this->temperature,
        ]);

        return $this->extractContent($response);
    }

    /**
     * Build the user prompt for summarization.
     */
    private function buildUserPrompt(string $content, array $context): string
    {
        $role = $context['role'] ?? 'unknown';
        $instruction = $context['instruction'] ?? 'Summarize in 2-3 sentences:';

        $prompt = "{$instruction}\n\n";
        
        if ($role !== 'unknown') {
            $prompt .= "[Role: {$role}]\n";
        }

        $prompt .= $content;

        return $prompt;
    }

    /**
     * Extract content from the response.
     */
    private function extractContent(ResponseInterface $response): string
    {
        $body = json_decode($response->getBody()->getContents(), true);

        if (!isset($body['choices'][0]['message']['content'])) {
            throw new \RuntimeException('No content in summarizer response');
        }

        return trim($body['choices'][0]['message']['content']);
    }

    /**
     * Set the model.
     */
    public function setModel(string $model): self
    {
        $this->model = $model;
        return $this;
    }

    /**
     * Set the max tokens for output.
     */
    public function setMaxTokens(int $maxTokens): self
    {
        $this->maxTokens = $maxTokens;
        return $this;
    }

    /**
     * Set the temperature.
     */
    public function setTemperature(float $temperature): self
    {
        $this->temperature = $temperature;
        return $this;
    }

    /**
     * Set the system prompt.
     */
    public function setSystemPrompt(string $prompt): self
    {
        $this->systemPrompt = $prompt;
        return $this;
    }
}
