<?php

declare(strict_types=1);

namespace WhmcsMigrate;

use Dotenv\Dotenv;
use RuntimeException;

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

    public function __construct(string $basePath)
    {
        $dotenv = Dotenv::createImmutable($basePath);
        $dotenv->safeLoad();
    }

    /**
     * Set a runtime override (e.g., from CLI flags).
     */
    public function override(string $key, mixed $value): void
    {
        $this->overrides[$key] = $value;
    }

    /**
     * Get a config value with optional default.
     */
    public function get(string $key, mixed $default = null): mixed
    {
        if (array_key_exists($key, $this->overrides)) {
            return $this->overrides[$key];
        }

        $value = $_ENV[$key] ?? $_SERVER[$key] ?? getenv($key);

        if ($value === false) {
            return $default;
        }

        return $value;
    }

    /**
     * Get a required config value. Throws if missing.
     */
    public function getRequired(string $key): string
    {
        $value = $this->get($key);

        if ($value === null || $value === '') {
            throw new RuntimeException("Required configuration key '{$key}' is not set.");
        }

        return (string) $value;
    }

    /**
     * Whether the migration is running in dry-run mode.
     */
    public function isDryRun(): bool
    {
        $value = $this->get('DRY_RUN', 'false');

        return filter_var($value, FILTER_VALIDATE_BOOLEAN);
    }

    /**
     * Number of records to process per batch.
     *
     * WHMCS API supports limitnum up to 250. Default raised from 100 to 250.
     */
    public function getBatchSize(): int
    {
        return (int) $this->get('BATCH_SIZE', 250);
    }

    /**
     * Whether the migration is in export-only mode (fetch from API and save to JSONL files).
     */
    public function isExportOnly(): bool
    {
        return filter_var($this->get('EXPORT_ONLY', 'false'), FILTER_VALIDATE_BOOLEAN);
    }

    /**
     * Whether the migration should read from exported JSONL files instead of the API.
     */
    public function isFromExport(): bool
    {
        return filter_var($this->get('FROM_EXPORT', 'false'), FILTER_VALIDATE_BOOLEAN);
    }

    /**
     * Monolog log level string.
     */
    public function getLogLevel(): string
    {
        return (string) $this->get('LOG_LEVEL', 'info');
    }

    /**
     * Get the Laravel APP_KEY as raw binary (decoded from base64).
     */
    public function getLaravelAppKey(): string
    {
        $key = $this->getRequired('LARAVEL_APP_KEY');

        // Strip the 'base64:' prefix if present
        if (str_starts_with($key, 'base64:')) {
            $key = substr($key, 7);
        }

        $decoded = base64_decode($key, strict: true);

        if ($decoded === false) {
            throw new RuntimeException('LARAVEL_APP_KEY is not valid base64.');
        }

        return $decoded;
    }
}
