<?php
declare(strict_types=1);

namespace Celena\Module\Settings;

use Celena\Core\Database\Connection;

/**
 * Хранилище настроек по ключам в таблице celena_options.
 * Кеширует autoload-ключи в память на время запроса.
 */
final class Options
{
    /** @var array<string, string> */
    private array $cache = [];
    private bool $loaded = false;

    public function __construct(private readonly Connection $conn)
    {
    }

    public function get(string $key, mixed $default = null): mixed
    {
        $this->loadAutoload();
        if (array_key_exists($key, $this->cache)) {
            return $this->cache[$key];
        }
        $row = $this->conn->builder('celena_options')->where('option_key', '=', $key)->first();
        if ($row === null) {
            return $default;
        }
        $value = (string) ($row['option_value'] ?? '');
        $this->cache[$key] = $value;
        return $value;
    }

    public function set(string $key, mixed $value, bool $autoload = true): void
    {
        $now = date('Y-m-d H:i:s');
        $existing = $this->conn->builder('celena_options')->where('option_key', '=', $key)->first();
        if ($existing === null) {
            $this->conn->builder('celena_options')->insert([
                'option_key' => $key,
                'option_value' => (string) $value,
                'autoload' => $autoload,
                'updated_at' => $now,
            ]);
        } else {
            $this->conn->builder('celena_options')->where('option_key', '=', $key)->update([
                'option_value' => (string) $value,
                'autoload' => $autoload,
                'updated_at' => $now,
            ]);
        }
        $this->cache[$key] = (string) $value;
    }

    /** @return array<string, string> */
    public function all(): array
    {
        $this->loadAutoload();
        return $this->cache;
    }

    private function loadAutoload(): void
    {
        if ($this->loaded) {
            return;
        }
        $rows = $this->conn->builder('celena_options')
            ->select('option_key', 'option_value')
            ->where('autoload', '=', true)
            ->get();
        foreach ($rows as $r) {
            $this->cache[(string) $r['option_key']] = (string) ($r['option_value'] ?? '');
        }
        $this->loaded = true;
    }
}
