<?php
if (!defined('ABSPATH')) exit;

/**
 * Kern-Helfer (Asset-URLs, Cache-Busting, Contrast).
 * CE_PD_VERSION/DIR/URL werden in der Plugin-Hauptdatei gesetzt, bevor dieses File geladen wird
 * (nur dort ist __FILE__ zuverlässig auf dem Plugin-Root).
 */

/**
 * URL zu einer SVG-Grafik in /assets mit Cache-Busting über filemtime (Fallback: CE_PD_VERSION über ce_pd_asset_ver()).
 * Wird von Toolbar-Buttons (Legende, Datentabelle, Vollbild enter/exit, PNG-Download) genutzt.
 */
function ce_pd_asset_url($filename) {
    $path = CE_PD_DIR . 'assets/' . $filename;
    $url  = CE_PD_URL . 'assets/' . $filename;
    $ver  = is_readable($path) ? filemtime($path) : ce_pd_asset_ver();
    return add_query_arg('ver', (string) $ver, $url);
}

/**
 * Rekursiv höchstes filemtime unter einem Verzeichnis (nur relevante Endungen).
 * Überspringt typische Dev-/Dep-Ordner, damit ein versehentliches node_modules nicht die Laufzeit sprengt.
 *
 * @param string   $dir
 * @param int      $max   Referenz: wird mit max(filemtime) aktualisiert
 * @param array<string, true> $ext_allow Keys: Kleinbuchstaben-Extension ohne Punkt
 * @param array<string, true> $skip_dir  Verzeichnisnamen (exakt), die nicht betreten werden
 */
function ce_pd_dir_max_mtime($dir, &$max, $ext_allow, $skip_dir) {
    if (!is_dir($dir)) {
        return;
    }
    $items = @scandir($dir);
    if ($items === false) {
        return;
    }
    foreach ($items as $item) {
        if ($item === '.' || $item === '..') {
            continue;
        }
        if (isset($skip_dir[$item])) {
            continue;
        }
        $path = $dir . DIRECTORY_SEPARATOR . $item;
        if (is_dir($path)) {
            ce_pd_dir_max_mtime($path, $max, $ext_allow, $skip_dir);
            continue;
        }
        $ext = strtolower((string) pathinfo($item, PATHINFO_EXTENSION));
        if ($ext === '' || !isset($ext_allow[$ext])) {
            continue;
        }
        $t = @filemtime($path);
        if ($t !== false && $t > $max) {
            $max = $t;
        }
    }
}

/**
 * Cache-Busting: max. filemtime aller auslieferungsrelevanten Plugin-Dateien (rekursiv).
 * Ändert sich, sobald irgendwo unter Block, Assets, Includes, Sprachen oder gebündeltem three.js etwas angepasst wird.
 */
function ce_pd_asset_ver() {
    static $ver = null;
    if ($ver !== null) {
        return $ver;
    }
    $m = 0;
    $ext_allow = [
        'js'    => true,
        'mjs'   => true,
        'css'   => true,
        'svg'   => true,
        'json'  => true,
        'php'   => true,
    ];
    $skip_dir = [
        'node_modules' => true,
        '.git'         => true,
        '.svn'         => true,
        '.hg'          => true,
    ];
    $roots = [
        CE_PD_DIR . 'assets',
        CE_PD_DIR . 'blocks/pop3d-diagram',
        CE_PD_DIR . 'includes',
        CE_PD_DIR . 'languages',
        CE_PD_DIR . 'vendor/three',
        CE_PD_DIR . 'vendor/troika',
    ];
    foreach ($roots as $root) {
        ce_pd_dir_max_mtime(rtrim($root, '/\\'), $m, $ext_allow, $skip_dir);
    }
    $main = CE_PD_DIR . 'pop3d-charts.php';
    if (is_readable($main)) {
        $t = @filemtime($main);
        if ($t !== false && $t > $m) {
            $m = $t;
        }
    }
    $ver = $m > 0 ? (string) $m : CE_PD_VERSION;
    return $ver;
}

/**
 * Query-Arg ?ver= an alle Plugin-Asset-URLs (Styles/Scripts), damit CDNs/Browser-Cache nicht alte Bundles halten.
 */
function ce_pd_bust_plugin_src($src) {
    if (!is_string($src) || $src === '') {
        return $src;
    }
    if (strpos($src, CE_PD_URL) !== 0) {
        return $src;
    }
    return add_query_arg('ver', ce_pd_asset_ver(), remove_query_arg('ver', $src));
}

/**
 * WCAG relative luminance → '#000' on light backgrounds, '#fff' on dark ones.
 */
function ce_pd_contrast_text_color( $hex_bg ) {
    $s = ltrim( trim( (string) $hex_bg ), '#' );
    if ( strlen( $s ) === 3 ) {
        $s = $s[0] . $s[0] . $s[1] . $s[1] . $s[2] . $s[2];
    }
    if ( ! preg_match( '/^[0-9a-fA-F]{6}$/', $s ) ) {
        return '';
    }
    $lin = function ( $c ) {
        return $c <= 0.03928 ? $c / 12.92 : pow( ( $c + 0.055 ) / 1.055, 2.4 );
    };
    $L = 0.2126 * $lin( hexdec( substr( $s, 0, 2 ) ) / 255 )
       + 0.7152 * $lin( hexdec( substr( $s, 2, 2 ) ) / 255 )
       + 0.0722 * $lin( hexdec( substr( $s, 4, 2 ) ) / 255 );
    return $L > 0.179 ? '#000' : '#fff';
}
