<?php

namespace App\Services\Ai;

use App\Models\Setting;
use Illuminate\Support\Facades\Crypt;

class AiSettingsManager
{
    public function all(): array
    {
        $settings = Setting::where('group', 'ai')->get()->keyBy('key');

        return [
            'enabled' => (bool) (($settings['enabled']->value ?? '0') === '1'),
            'provider' => $settings['provider']->value ?? 'local',
            'endpoint' => $settings['endpoint']->value ?? 'https://api.openai.com/v1/chat/completions',
            'model' => $settings['model']->value ?? 'gpt-4o-mini',
            'temperature' => (float) ($settings['temperature']->value ?? 0.2),
            'timeout' => (int) ($settings['timeout']->value ?? 45),
            'api_key' => $this->decryptValue($settings['api_key']->value ?? null),
        ];
    }

    public function save(array $data): void
    {
        $plain = [
            'enabled' => ! empty($data['enabled']) ? '1' : '0',
            'provider' => $data['provider'] ?? 'local',
            'endpoint' => $data['endpoint'] ?? 'https://api.openai.com/v1/chat/completions',
            'model' => $data['model'] ?? 'gpt-4o-mini',
            'temperature' => (string) ($data['temperature'] ?? 0.2),
            'timeout' => (string) ($data['timeout'] ?? 45),
        ];

        foreach ($plain as $key => $value) {
            Setting::updateOrCreate(
                ['group' => 'ai', 'key' => $key],
                ['value' => $value, 'is_encrypted' => false]
            );
        }

        if (array_key_exists('api_key', $data) && filled($data['api_key'])) {
            Setting::updateOrCreate(
                ['group' => 'ai', 'key' => 'api_key'],
                ['value' => Crypt::encryptString($data['api_key']), 'is_encrypted' => true]
            );
        }
    }

    public function maskedApiKey(): string
    {
        $key = $this->all()['api_key'] ?? '';

        if ($key === '') {
            return '';
        }

        return substr($key, 0, 6) . str_repeat('*', max(strlen($key) - 10, 8)) . substr($key, -4);
    }

    private function decryptValue(?string $value): string
    {
        if (! $value) {
            return '';
        }

        try {
            return Crypt::decryptString($value);
        } catch (\Throwable) {
            return '';
        }
    }
}
