<?php

namespace ZenoChatbot\Services\LLMService\AIClient\Config;

use ZenoChatbot\Services\LLMService\AIClient\Providers\Anthropic;
use ZenoChatbot\Services\LLMService\AIClient\Providers\Gemini;
use ZenoChatbot\Services\LLMService\AIClient\Providers\OpenAI;

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

class ConfigBuilder
{
    private array $data = [
        'provider'    => '',
        'model'       => '',
        'api_key'     => '',
        'temperature' => 0.7,
        'max_tokens'  => 1000,
    ];

    /** @return self */
    public static function create(): self
    {
        return new static();
    }


    /** @return self */
    public function fromArray(array $data): self
    {
        foreach (['provider', 'model', 'api_key', 'temperature', 'max_tokens'] as $k) {
            if (array_key_exists($k, $data)) {
                $this->data[$k] = $data[$k];
            }
        }
        if (!empty($this->data['provider'])) {
            $this->data['provider'] = $this->normalizeProvider($this->data['provider']);
        }
        return $this;
    }

    /** @return self */
    public function provider(string $providerClass): self
    {
        $this->data['provider'] = $this->normalizeProvider($providerClass);
        return $this;
    }

    /** @return self */
    public function model(string $model): self
    {
        $this->data['model'] = $model;
        return $this;
    }

    /** @return self */
    public function apiKey(string $apiKey): self
    {
        $this->data['api_key'] = $apiKey;
        return $this;
    }

    /** @return self */
    public function temperature(float $temperature): self
    {
        $this->data['temperature'] = max(0.0, min(1.0, $temperature));
        return $this;
    }

    /** @return self */
    public function maxTokens(int $maxTokens): self
    {
        $this->data['max_tokens'] = max(1, min(10000, $maxTokens));
        return $this;
    }

    public function build(): AiConfig
    {
        $data = $this->data;
        // Provider default model if missing
        if (empty($data['model'])) {
            if ($data['provider'] === OpenAI::class) {
                $data['model'] = OpenAI::MODEL_GPT_4O_MINI;
            } elseif ($data['provider'] === Gemini::class) {
                $data['model'] = Gemini::MODEL_3_5_FLASH;
            } elseif ($data['provider'] === Anthropic::class) {
                $data['model'] = Anthropic::MODEL_SONNET_4_6;
            }
        }
        if (empty($data['api_key'])) {
            throw new \RuntimeException('Missing API key for selected provider.');
        }
        if (empty($data['provider'])) {
            throw new \RuntimeException('Missing provider class.');
        }
        if (empty($data['model'])) {
            throw new \RuntimeException('Missing model for selected provider.');
        }
        return new AiConfig($data);
    }

    private function normalizeProvider(string $provider): string
    {
        $p = strtolower(trim($provider, "\\ "));

        $endsWith = function (string $haystack, string $needle): bool {
            $len = strlen($needle);
            if ($len === 0) {
                return true;
            }
            return substr($haystack, -$len) === $needle;
        };

        if ($p === 'openai' || $endsWith($p, 'providers\\openai')) {
            return OpenAI::class;
        }

        if ($p === 'gemini' || $p === 'google' || $endsWith($p, 'providers\\gemini')) {
            return Gemini::class;
        }

        if ($p === 'anthropic' || $p === 'claude' || $endsWith($p, 'providers\\anthropic')) {
            return Anthropic::class;
        }

        return $provider;
    }
}

