<?php

$GLOBALS['page_header_scripts'] = $GLOBALS['page_header_scripts'] ?? [];
$GLOBALS['page_footer_scripts'] = $GLOBALS['page_footer_scripts'] ?? [];
$GLOBALS['page_styles']         = $GLOBALS['page_styles'] ?? [];

function app_primary_domain(): string
{
    return defined('APP_DOMAIN_PRIMARY') ? APP_DOMAIN_PRIMARY : 'usbcheck.it';
}

function app_primary_url(): string
{
    $url = defined('APP_URL_PRIMARY') ? APP_URL_PRIMARY : 'https://usbcheck.it';
    return rtrim($url, '/');
}

function app_fakecheck_domain(): string
{
    return defined('APP_DOMAIN_FAKECHECK') ? APP_DOMAIN_FAKECHECK : 'ismyusbfake.com';
}

function app_fakecheck_url(): string
{
    $url = defined('APP_URL_FAKECHECK') ? APP_URL_FAKECHECK : 'https://ismyusbfake.com';
    return rtrim($url, '/');
}

/**
 * Script registrieren
 *
 * @param string      $src      Pfad zur Datei, z. B. '/assets/js/auth.js'
 * @param string      $pos      'header' oder 'footer'
 * @param bool        $defer    standard true
 * @param bool        $async    standard false
 * @param string      $type     z. B. 'module'
 * @param string|null $version  null = nutze ASSET_VERSION (falls definiert),
 *                              ''   = kein ?v=,
 *                              'xyz'= erzwinge diese Version
 */
function tpl_add_script(
    string $src,
    string $pos = 'footer',
    bool $defer = true,
    bool $async = false,
    string $type = '',
    ?string $version = null
): void {
    // Standard-Verhalten: falls Version nicht explizit gesetzt → globale ASSET_VERSION verwenden
    if ($version === null && defined('ASSET_VERSION')) {
        $version = ASSET_VERSION;
    }

    $data = [
        'src'     => $src,
        'defer'   => $defer,
        'async'   => $async,
        'type'    => $type,
        'version' => $version, // kann null, '' oder string sein
    ];

    if ($pos === 'header') {
        $GLOBALS['page_header_scripts'][] = $data;
    } else {
        $GLOBALS['page_footer_scripts'][] = $data;
    }
}

/**
 * CSS registrieren
 *
 * @param string      $href     Pfad zur CSS
 * @param string      $pos      'header' oder 'footer'
 * @param string|null $version  gleiche Logik wie bei Scripts
 */
function tpl_add_style(string $href, string $pos = 'header', ?string $version = null): void
{
    if ($version === null && defined('ASSET_VERSION')) {
        $version = ASSET_VERSION;
    }

    $GLOBALS['page_styles'][] = [
        'href'    => $href,
        'pos'     => $pos,
        'version' => $version,
    ];
}


/**
 * Templating Loader
 *
 * Beispiel:
 * tpl('header');                            // structure/header.php
 * tpl('hero', 'landing', 'main');           // landing/main/hero.php
 * tpl('faq', 'landing', 'fakecheck');       // landing/fakecheck/faq.php
 */

function tpl(string $file, string $type = 'structure', string $site = 'main'): void
{
    $base = __DIR__ . '/../partials/';

    // VALIDIERUNG: Nur einfache Check, kein Path-Traversal
    if (preg_match('/[^a-zA-Z0-9_\-]/', $file)) {
        echo "<!-- tpl(): Ungültiger Template-Name -->";
        return;
    }
    if (preg_match('/[^a-zA-Z0-9_\-]/', $type)) {
        echo "<!-- tpl(): Ungültiger Type -->";
        return;
    }
    if (preg_match('/[^a-zA-Z0-9_\-]/', $site)) {
        echo "<!-- tpl(): Ungültiger Site -->";
        return;
    }

    if ($type === 'landing') {
        $path = $base . "landing/$site/$file.php";
    } else {
        $path = $base . "structure/$file.php";
    }

    extract($GLOBALS, EXTR_SKIP);

    if (file_exists($path)) {
        include $path;
    } else {
        echo "<!-- tpl(): Datei nicht gefunden: $path -->";
    }
}


/**
 * Flash-Meldung setzen (wird genau einmal nach Redirect angezeigt).
 *
 * @param string      $type    z.B. 'success', 'error', 'info', 'warning'
 * @param string      $message Die Meldung für den Nutzer
 * @param string|null $context Optionaler Kontext (z.B. 'login', 'register')
 */
function flash_set(string $type, string $message, ?string $context = null): void
{
    if (session_status() !== PHP_SESSION_ACTIVE) {
        @session_start();
    }

    $_SESSION['flash'] = [
        'type'    => $type,
        'message' => $message,
        'context' => $context,
    ];
}

/**
 * Flash-Meldung holen und direkt löschen (Einmal-Anzeige).
 *
 * @return array|null ['type' => 'success|error|info|warning', 'message' => '...', 'context' => '...']
 */
function flash_get(): ?array
{
    if (session_status() !== PHP_SESSION_ACTIVE) {
        @session_start();
    }

    if (empty($_SESSION['flash']) || !is_array($_SESSION['flash'])) {
        return null;
    }

    $flash = $_SESSION['flash'];
    unset($_SESSION['flash']);

    $flash['type']    = $flash['type']    ?? 'info';
    $flash['message'] = $flash['message'] ?? '';
    $flash['context'] = $flash['context'] ?? null;

    return $flash;
}

/**
 * Interne Helper-Funktion: traversiert ein Array mit "dot notation"-Segmenten.
 *
 * @param array  $data
 * @param string $key  z.B. 'pages.landing.meta.title'
 * @return mixed|null
 */
function _i18n_traverse_array(array $data, string $key)
{
    $segments = explode('.', $key);
    $node = $data;

    foreach ($segments as $seg) {
        if (!is_array($node) || !array_key_exists($seg, $node)) {
            return null;
        }
        $node = $node[$seg];
    }

    return $node;
}

/**
 * Zentrale Funktion zum Laden eines i18n-Strings mit Fallback.
 *
 * - greift zuerst auf $GLOBALS['i18n']['current'] zu
 * - dann auf $GLOBALS['i18n']['fallback']
 * - unterstützt Platzhalter {key} und {{key}}
 * - eingebaute Platzhalter:
 *      {year}
 *      {{primary_domain}}
 *      {{primary_url}}
 *
 * @param string     $path         z.B. 'pages.login.meta.title'
 * @param mixed      $default      Fallback, falls nichts gefunden wird
 * @param array      $replacements ['name' => 'Lars']
 *
 * @return string
 */
function i18n_get(string $path, $default = null, array $replacements = []): string
{
    if (!isset($GLOBALS['i18n']) || !is_array($GLOBALS['i18n'])) {
        return $default !== null ? (string)$default : '';
    }

    $current  = $GLOBALS['i18n']['current']  ?? [];
    $fallback = $GLOBALS['i18n']['fallback'] ?? [];

    // zuerst in der aktiven Sprache suchen
    $value = _i18n_traverse_array($current, $path);

    // wenn dort nichts → Fallback-Sprache
    if ($value === null && !empty($fallback)) {
        $value = _i18n_traverse_array($fallback, $path);
    }

    if (!is_string($value)) {
        return $default !== null ? (string)$default : '';
    }

    $text = $value;

    // eingebaute Platzhalter
    $builtIn = [
        '{year}'             => date('Y'),
        '{{primary_domain}}' => function_exists('app_primary_domain') ? app_primary_domain() : '',
        '{{primary_url}}'    => function_exists('app_primary_url') ? app_primary_url() : '',
    ];

    foreach ($builtIn as $ph => $val) {
        $text = str_replace($ph, $val, $text);
    }

    // zusätzliche Platzhalter aus $replacements
    foreach ($replacements as $key => $val) {
        $val = (string)$val;
        // Variante {key}
        $text = str_replace('{' . $key . '}', $val, $text);
        // Variante {{key}}
        $text = str_replace('{{' . $key . '}}', $val, $text);
    }

    return $text;
}

/**
 * Convenience-Wrapper für i18n_get, etwas "kürzer" zu tippen
 * und vom bisherigen Code kompatibel genutzt.
 *
 * Beispiel:
 *   i18n_get_fmt('fake_ui.log_capacity_probe_result', 'Fallback', ['size' => '2 GB']);
 */
function i18n_get_fmt(string $path, $default = '', array $vars = []): string
{
    // Falls $default explizit null ist → leere String als Basis
    $def = $default ?? '';

    return i18n_get($path, $def, $vars);
}
