<?php

declare(strict_types=1);


namespace App\Blog\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

/**
 * OpenAI 兼容 LLM 客户端（支持 OpenAI / DeepSeek / 通义 / 自建代理）。
 */
class LlmClient
{
    public function baseUrl(): string
    {
        return rtrim((string) blog_setting('llm_base_url', config('services.llm.base_url', env('LLM_BASE_URL'))), '/');
    }

    public function apiKey(): string
    {
        return (string) blog_setting('llm_api_key', config('services.llm.api_key', env('LLM_API_KEY')));
    }

    public function model(): string
    {
        return (string) blog_setting('llm_model', config('services.llm.model', env('LLM_MODEL', 'gpt-4o-mini')));
    }

    public function isConfigured(): bool
    {
        return $this->baseUrl() !== '' && $this->apiKey() !== '';
    }

    /**
     * 简单的聊天补全。
     *
     * @param  array<int, array{role: string, content: string}>  $messages
     */
    public function chat(array $messages, array $options = []): string
    {
        if (! $this->isConfigured()) {
            throw new \RuntimeException('LLM 未配置：请设置 LLM_BASE_URL 与 LLM_API_KEY');
        }

        $response = Http::timeout(60)
            ->withToken($this->apiKey())
            ->post($this->baseUrl().'/chat/completions', [
                'model' => $options['model'] ?? $this->model(),
                'messages' => $messages,
                'temperature' => $options['temperature'] ?? 0.3,
                'max_tokens' => $options['max_tokens'] ?? 1024,
            ]);

        if ($response->failed()) {
            Log::error('LLM 请求失败', ['status' => $response->status(), 'body' => $response->body()]);

            throw new \RuntimeException('LLM 请求失败：HTTP '.$response->status());
        }

        $content = $response->json('choices.0.message.content', '');

        return is_array($content) ? json_encode($content, JSON_UNESCAPED_UNICODE) : (string) $content;
    }
}
