<?php
/*** This text should be at the top of all code files ***
 * app-config.php – used for shared configuration and environment helpers
 * Made by: Morten Pilekær
 * Rev. 0.4.0 Owner: Morten Pilekær
 * Location: /qr-app-lite/app-config.php
 ***/
declare(strict_types=1);

const QR_APP_VERSION = 'v0.4.0';
const QR_OUTPUT_DIR_NAME = 'generated';
const QR_OUTPUT_MAX_AGE_DAYS = 30;
const QR_OUTPUT_MAX_FILES = 200;
const QR_INPUT_MAX_LENGTH = 4096;
const QR_SCAN_HISTORY_MAX_ITEMS = 20;
const QR_PUBLIC_DEMO_HOSTS = ['pilekaer.dk', 'www.pilekaer.dk'];
const QR_PUBLIC_DEMO_BASE_PATH = '/qr-app-lite';

if (!function_exists('appE')) {
    function appE(string $value): string
    {
        return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
    }
}

if (!function_exists('appBasePath')) {
    function appBasePath(string $relativePath = ''): string
    {
        $base = __DIR__;
        if ($relativePath === '') {
            return $base;
        }

        return $base . DIRECTORY_SEPARATOR . str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $relativePath);
    }
}

if (!function_exists('appPublicPath')) {
    function appPublicPath(string $relativePath): string
    {
        return str_replace(DIRECTORY_SEPARATOR, '/', $relativePath);
    }
}

if (!function_exists('isQrPublicDemo')) {
    function isQrPublicDemo(): bool
    {
        $hostHeader = strtolower(trim((string)($_SERVER['HTTP_HOST'] ?? $_SERVER['SERVER_NAME'] ?? '')));
        $host = rtrim(explode(':', $hostHeader, 2)[0], '.');
        $scriptName = '/' . ltrim(str_replace('\\', '/', (string)($_SERVER['SCRIPT_NAME'] ?? '')), '/');
        $basePath = rtrim(QR_PUBLIC_DEMO_BASE_PATH, '/');

        return in_array($host, QR_PUBLIC_DEMO_HOSTS, true)
            && ($scriptName === $basePath || str_starts_with($scriptName, $basePath . '/'));
    }
}

if (!function_exists('ensureQrOutputDirectory')) {
    function ensureQrOutputDirectory(): string
    {
        $dir = appBasePath(QR_OUTPUT_DIR_NAME);

        if (!is_dir($dir)) {
            if (!mkdir($dir, 0775, true) && !is_dir($dir)) {
                throw new RuntimeException('Kunne ikke oprette output-mappen: ' . QR_OUTPUT_DIR_NAME);
            }
        }

        if (!is_writable($dir)) {
            throw new RuntimeException('Output-mappen er ikke skrivbar: ' . QR_OUTPUT_DIR_NAME);
        }

        return $dir;
    }
}

if (!function_exists('getQrOutputFiles')) {
    function getQrOutputFiles(string $dir): array
    {
        $files = [];
        foreach (['png', 'jpeg', 'jpg', 'tiff', 'tif'] as $extension) {
            $matches = glob($dir . DIRECTORY_SEPARATOR . 'qr_*.' . $extension) ?: [];
            $files = array_merge($files, $matches);
        }

        return $files;
    }
}

if (!function_exists('cleanupQrOutputDirectory')) {
    function cleanupQrOutputDirectory(): array
    {
        $dir = ensureQrOutputDirectory();
        $deleted = 0;
        $errors = [];
        $files = getQrOutputFiles($dir);
        $now = time();
        $maxAgeSeconds = QR_OUTPUT_MAX_AGE_DAYS * 86400;
        $remaining = [];

        foreach ($files as $file) {
            if (!is_file($file)) {
                continue;
            }

            $mtime = filemtime($file) ?: $now;
            if (($now - $mtime) > $maxAgeSeconds) {
                if (@unlink($file)) {
                    $deleted++;
                } else {
                    $errors[] = basename($file);
                    $remaining[] = $file;
                }
            } else {
                $remaining[] = $file;
            }
        }

        usort($remaining, static function (string $a, string $b): int {
            return (filemtime($b) ?: 0) <=> (filemtime($a) ?: 0);
        });

        if (count($remaining) > QR_OUTPUT_MAX_FILES) {
            $overflow = array_slice($remaining, QR_OUTPUT_MAX_FILES);
            foreach ($overflow as $file) {
                if (@unlink($file)) {
                    $deleted++;
                } else {
                    $errors[] = basename($file);
                }
            }
        }

        return ['deleted' => $deleted, 'errors' => $errors];
    }
}

if (!function_exists('getQrOutputStats')) {
    function getQrOutputStats(): array
    {
        $dir = appBasePath(QR_OUTPUT_DIR_NAME);
        if (!is_dir($dir)) {
            return ['count' => 0, 'size_bytes' => 0];
        }

        $files = getQrOutputFiles($dir);
        $sizeBytes = 0;
        $count = 0;

        foreach ($files as $file) {
            if (is_file($file)) {
                $count++;
                $sizeBytes += filesize($file) ?: 0;
            }
        }

        return ['count' => $count, 'size_bytes' => $sizeBytes];
    }
}

if (!function_exists('formatBytes')) {
    function formatBytes(int $bytes): string
    {
        if ($bytes < 1024) {
            return $bytes . ' B';
        }

        $units = ['KB', 'MB', 'GB'];
        $value = $bytes / 1024;
        foreach ($units as $unit) {
            if ($value < 1024) {
                return number_format($value, 2, ',', '.') . ' ' . $unit;
            }
            $value /= 1024;
        }

        return number_format($value, 2, ',', '.') . ' TB';
    }
}
