<?php
declare(strict_types=1);

namespace Celena\Core;

/**
 * Конфигурация приложения с поддержкой dot-нотации.
 * Ленивая загрузка из /config/*.php, переопределение через .env.
 */
final class Config
{
    /** @var array<string, mixed> */
    private array $items = [];

    public function __construct(string $configDir, ?string $envFile = null)
    {
        if ($envFile !== null && is_file($envFile)) {
            $this->loadEnv($envFile);
        }
        $this->loadDir($configDir);
    }

    public function get(string $key, mixed $default = null): mixed
    {
        $segments = explode('.', $key);
        $value = $this->items;
        foreach ($segments as $seg) {
            if (!is_array($value) || !array_key_exists($seg, $value)) {
                return $default;
            }
            $value = $value[$seg];
        }
        return $value;
    }

    public function set(string $key, mixed $value): void
    {
        $segments = explode('.', $key);
        $arr = &$this->items;
        foreach ($segments as $seg) {
            if (!isset($arr[$seg]) || !is_array($arr[$seg])) {
                $arr[$seg] = [];
            }
            $arr = &$arr[$seg];
        }
        $arr = $value;
    }

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

    private function loadDir(string $configDir): void
    {
        if (!is_dir($configDir)) {
            return;
        }
        foreach (glob($configDir . '/*.php') ?: [] as $file) {
            $name = basename($file, '.php');
            $data = require $file;
            if (is_array($data)) {
                $this->items[$name] = $data;
            }
        }
    }

    private function loadEnv(string $file): void
    {
        $lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) ?: [];
        foreach ($lines as $line) {
            if (str_starts_with(trim($line), '#')) {
                continue;
            }
            if (!str_contains($line, '=')) {
                continue;
            }
            [$k, $v] = explode('=', $line, 2);
            $k = trim($k);
            $v = trim($v);
            // снять кавычки
            if (strlen($v) > 1 && (
                ($v[0] === '"' && $v[-1] === '"') ||
                ($v[0] === "'" && $v[-1] === "'")
            )) {
                $v = substr($v, 1, -1);
            }
            if (getenv($k) === false) {
                putenv("$k=$v");
                $_ENV[$k] = $v;
                $_SERVER[$k] = $v;
            }
        }
    }
}
