<?php
declare(strict_types=1);

namespace App\Core;

final class Config
{
    private array $data = [];

    public function loadAll(): void
    {
        $configDir = Autoloader::basePath() . '/config';
        $files = glob($configDir . '/*.php');
        if ($files === false) {
            return;
        }

        foreach ($files as $file) {
            $key = basename($file, '.php');
            $values = require $file;
            if (is_array($values)) {
                $this->data[$key] = $values;
            }
        }
    }

    public function loadFromDatabase(Database $db): void
    {
        try {
            if (!$db->tableExists('system_config')) {
                return;
            }
            $rows = $db->select("SELECT config_key, config_value, config_type FROM system_config");
            foreach ($rows as $row) {
                $value = $this->castValue($row['config_value'], $row['config_type']);
                $this->set($row['config_key'], $value);
            }
        } catch (\Exception $e) {
            // DB config loading is optional - silently continue
        }
    }

    private function castValue(?string $value, string $type)
    {
        if ($value === null) {
            return null;
        }

        return match ($type) {
            'integer' => (int) $value,
            'float'   => (float) $value,
            'boolean' => in_array(strtolower($value), ['1', 'true', 'yes']),
            'json'    => json_decode($value, true),
            default   => $value,
        };
    }

    public function get(string $key, $default = null)
    {
        $keys = explode('.', $key);
        $value = $this->data;

        foreach ($keys as $k) {
            if (!is_array($value) || !array_key_exists($k, $value)) {
                return $default;
            }
            $value = $value[$k];
        }

        return $value;
    }

    public function set(string $key, $value): void
    {
        $keys = explode('.', $key);
        $data = &$this->data;

        foreach ($keys as $i => $k) {
            if ($i === count($keys) - 1) {
                $data[$k] = $value;
            } else {
                if (!isset($data[$k]) || !is_array($data[$k])) {
                    $data[$k] = [];
                }
                $data = &$data[$k];
            }
        }
    }

    public function all(): array
    {
        return $this->data;
    }
}