<?php

declare(strict_types=1);

/**
 * Sponsoren-Anzeige in den Bestand aufnehmen oder ihr Motiv erneuern (nur CLI).
 *
 *   php bin/anzeige-add.php <bild-oder-ordner> [-v]
 *
 * Beispiele:
 *   php bin/anzeige-add.php ~/Desktop/anzeigen/          alle Bilder im Ordner
 *   php bin/anzeige-add.php ~/Desktop/eldorado.jpg       nur diese eine
 *
 * DER DATEINAME IST DER SLUG: `eldorado.jpg` wird zu `img/anzeigen/eldorado-*.jpg`
 * und findet damit den bestehenden Eintrag wieder. Ein neues Motiv für einen
 * bekannten Sponsor heißt also einfach wieder `eldorado.jpg`.
 *
 * Anzeigen sind ein DAUERHAFTER Bestand (data/anzeigen.json), kein Zubehör einer
 * einzelnen Ausgabe: Sponsorenmotive ändern sich selten, die Stadionzeitung
 * erscheint oft. bin/stadionzeitung-add.php holt sie sich von hier, pro Heft ist
 * nichts abzuliefern. Vorher lag jede Anzeige als Kopie unter jeder Ausgabe und
 * ihr Alt-Text musste jedes Mal neu geschrieben werden.
 *
 * Das Skript schreibt ausschließlich `base` und `widths`. `sponsor`, `alt`,
 * `aktiv` und die REIHENFOLGE der Liste (= Reihenfolge im Heft) sind
 * chat-gepflegt und überleben jeden Lauf unangetastet — dasselbe Prinzip wie bei
 * bin/veranstaltung-bilder.php. Bei einem neuen Sponsor wird `sponsor` aus dem
 * Dateinamen vorbelegt und muss im Chat richtiggestellt werden; das Skript sagt,
 * bei welchen.
 */
if (PHP_SAPI !== 'cli') {
    exit(1);
}

require dirname(__DIR__) . '/app/bootstrap.php';

$args = array_values(array_filter(array_slice($argv, 1), static fn (string $a): bool => $a !== '-v'));
$verbose = in_array('-v', $argv, true);

$log = static function (string $msg, string $level = 'INFO') use ($verbose): void {
    log_write('stadionzeitung', $level, $msg);
    if ($verbose || $level === 'ERROR' || $level === 'WARN') {
        echo '[' . date('c') . "] {$level}  {$msg}\n";
    }
};

$fail = static function (string $msg) use ($log): never {
    $log("{$msg} — bestehende Daten bleiben unangetastet.", 'ERROR');
    exit(1);
};

if ($args === []) {
    fwrite(STDERR, "Nutzung: php bin/anzeige-add.php <bild-oder-ordner> [-v]\n");
    exit(1);
}

// --- Quelldateien einsammeln ---
$exts = 'jpg,jpeg,png,webp,JPG,JPEG,PNG,WEBP';
$quelle = $args[0];
if (is_dir($quelle)) {
    $sources = glob(rtrim($quelle, '/') . "/*.{{$exts}}", GLOB_BRACE) ?: [];
    natsort($sources);
    $sources = array_values($sources);
} elseif (is_file($quelle)) {
    $sources = [$quelle];
} else {
    $fail("Nicht gefunden: {$quelle}");
}

if ($sources === []) {
    $fail("Keine Bilder in {$quelle} gefunden.");
}

// Selbst-Import verhindern: zeigt jemand auf den Zielordner, wären die Quellen
// die erzeugten Varianten (`eldorado-1440.jpg`), und aus jeder Breite entstünde
// ein eigener Sponsor („eldorado 1440"). Einmal reingelaufen, deshalb der Riegel.
$zielReal = realpath(PUBLIC_PATH . '/assets/img/anzeigen');
foreach ($sources as $src) {
    if ($zielReal !== false && realpath(dirname($src)) === $zielReal) {
        $fail('Quelle liegt im Zielordner public/assets/img/anzeigen/ — das sind die erzeugten Varianten, nicht die Originale.');
    }
}

// --- Lock gegen parallele Läufe ---
if (!is_dir(STORAGE_PATH . '/cache')) {
    mkdir(STORAGE_PATH . '/cache', 0755, true);
}
$lock = fopen(STORAGE_PATH . '/cache/anzeigen.lock', 'c');
if (!$lock || !flock($lock, LOCK_EX | LOCK_NB)) {
    $log('Läuft bereits (Lock belegt) — Lauf übersprungen.', 'WARN');
    exit(1);
}

$dataFile = DATA_PATH . '/anzeigen.json';
$data = is_file($dataFile)
    ? (json_decode((string) file_get_contents($dataFile), true) ?: ['anzeigen' => []])
    : ['anzeigen' => []];

$destDir = PUBLIC_PATH . '/assets/img/anzeigen';
if (!is_dir($destDir)) {
    mkdir($destDir, 0755, true);
}

$widths = [480, 960, 1440];

/** Dateiname zu Slug: Kleinschreibung, Umlaute weg, alles andere zu Bindestrichen. */
$slugify = static function (string $text): string {
    $text = strtr($text, ['ä' => 'ae', 'ö' => 'oe', 'ü' => 'ue', 'Ä' => 'Ae', 'Ö' => 'Oe', 'Ü' => 'Ue', 'ß' => 'ss']);
    $text = strtolower($text);
    return trim(preg_replace('/[^a-z0-9]+/', '-', $text) ?? '', '-');
};

$neu = [];
$erneuert = [];

foreach ($sources as $src) {
    $slug = $slugify(pathinfo($src, PATHINFO_FILENAME));
    if ($slug === '') {
        $log('Dateiname ergibt keinen Slug, übersprungen: ' . basename($src), 'WARN');
        continue;
    }

    // Alte Varianten dieses Slugs weg, sonst bleiben bei einem kleineren Motiv
    // Breiten von vorher liegen und die JSON verspricht Dateien, die zum Bild
    // nicht mehr passen.
    foreach (glob("{$destDir}/{$slug}-*.jpg") ?: [] as $alt) {
        unlink($alt);
    }

    try {
        // Qualität 82 wie bei den Plakaten: Anzeigen tragen Text, und Ringing um
        // Buchstaben sieht man.
        $variants = resize_image_variants($src, "{$destDir}/{$slug}", $widths, 82);
    } catch (RuntimeException $e) {
        $fail('Anzeige nicht verarbeitbar (' . basename($src) . '): ' . $e->getMessage());
    }
    $generated = array_values(array_unique(array_column($variants, 'width')));
    sort($generated);

    // Bestehenden Eintrag suchen und NUR base/widths ersetzen.
    $index = null;
    foreach ($data['anzeigen'] as $i => $eintrag) {
        if (($eintrag['slug'] ?? '') === $slug) {
            $index = $i;
            break;
        }
    }

    if ($index === null) {
        // Neuer Sponsor: Platzhalter-Name aus dem Slug, im Chat zu ersetzen.
        $data['anzeigen'][] = [
            'slug'    => $slug,
            'sponsor' => str_replace('-', ' ', $slug),
            'aktiv'   => true,
            'base'    => "img/anzeigen/{$slug}",
            'widths'  => $generated,
        ];
        $neu[] = $slug;
    } else {
        $data['anzeigen'][$index]['base'] = "img/anzeigen/{$slug}";
        $data['anzeigen'][$index]['widths'] = $generated;
        $erneuert[] = $slug;
    }

    $log("Anzeige {$slug}: " . implode('/', $generated) . 'px');
}

$payload = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
$tmp = $dataFile . '.tmp';
file_put_contents($tmp, $payload . "\n");
if (!rename($tmp, $dataFile)) {
    $fail('Konnte data/anzeigen.json nicht schreiben.');
}

$log(sprintf('Anzeigen-Bestand aktualisiert: %d neu, %d erneuert.', count($neu), count($erneuert)));

echo 'Anzeigen-Bestand: ' . count($data['anzeigen']) . ' Motive, ' . count($neu) . ' neu, ' . count($erneuert) . " erneuert.\n";
if ($neu !== []) {
    echo "Sponsorenname noch Platzhalter bei: " . implode(', ', $neu) . "\n";
    echo "In data/anzeigen.json richtigstellen (daraus entsteht der Alt-Text „Anzeige: …\").\n";
}
