<?php
/**
 * Cronjob: Timer-Prüfung (läuft sekündlich).
 * Prüft ob ein aktiver Wecker klingeln soll und schreibt den Zustand in
 * storage/alarm_ringing.json. Steuert auch Snooze-Ablauf.
 *
 * Wird von cronjob.php per include ausgeführt; $pdo und alle Wecker-Funktionen sind verfügbar.
 */

$stateFile = STORAGE_ROOT . '/alarm_ringing.json';

if (!function_exists('function_tts_generieren')) {
    require defined('FUNCTIONS_ROOT')
        ? FUNCTIONS_ROOT . '/functions_tts.php'
        : dirname(__DIR__) . '/functions/functions_tts.php';
}
if (!function_exists('function_tts_cache_set')) {
    require defined('FUNCTIONS_ROOT')
        ? FUNCTIONS_ROOT . '/functions_tts_cache.php'
        : dirname(__DIR__) . '/functions/functions_tts_cache.php';
}

// Sicherstellen dass storage-Verzeichnis existiert
if (!is_dir(STORAGE_ROOT)) {
    @mkdir(STORAGE_ROOT, 0755, true);
}

// Aktuellen Zustand lesen
$state = [];
if (is_file($stateFile)) {
    $raw = @file_get_contents($stateFile);
    if ($raw !== false && $raw !== '') {
        $state = @json_decode($raw, true) ?: [];
    }
}

$zeitzone = trim((string) (function_einstellung_hole('zeitzone') ?: 'Europe/Berlin'));
if ($zeitzone === '') {
    $zeitzone = 'Europe/Berlin';
}
$nowDateTime    = new DateTimeImmutable('now', new DateTimeZone($zeitzone));
$now            = $nowDateTime->getTimestamp();
$currentTime    = $nowDateTime->format('H:i');
$currentDate    = $nowDateTime->format('Y-m-d');
$currentWeekday = (int) $nowDateTime->format('N'); // 1 = Montag, 7 = Sonntag

// Auto-Expire: Klingeln nach 2 Minuten ohne Reaktion automatisch beenden
if (!empty($state['ringing']) && !empty($state['started_at'])) {
    if (($now - (int) $state['started_at']) > 120) {
        $state = ['ringing' => false];
        @file_put_contents($stateFile, json_encode($state));
    }
}

// Wenn gerade klingelt: nichts tun (Benutzer muss Snooze/Stop drücken)
if (!empty($state['ringing'])) {
    return;
}

// Aktive Wecker holen
if (!function_exists('function_wecker_hole_aktive')) {
    return;
}
$alarms = function_wecker_hole_aktive();

foreach ($alarms as $alarm) {
    $alarmId   = (int) $alarm['id'];
    $alarmTime = substr((string) $alarm['weckzeit'], 0, 5); // HH:MM
    $ringDateTime = $nowDateTime->setTime((int) substr($alarmTime, 0, 2), (int) substr($alarmTime, 3, 2), 0);
    if (($alarm['wiederholung'] ?? 'taeglich') === 'einmal' && !empty($alarm['weckdatum'])) {
        $ringDateTime = DateTimeImmutable::createFromFormat('Y-m-d H:i', $alarm['weckdatum'] . ' ' . $alarmTime, new DateTimeZone($zeitzone))
            ?: $ringDateTime;
    }

    // Prüfen ob dieser Wecker jetzt klingeln soll
    $shouldRing = false;

    switch ($alarm['wiederholung'] ?? 'taeglich') {
        case 'einmal':
            $shouldRing = ($alarm['weckdatum'] === $currentDate && $alarmTime === $currentTime);
            break;

        case 'taeglich':
            $shouldRing = ($alarmTime === $currentTime);
            break;

        case 'woechentlich':
            $wochentage = function_wecker_hole_wochentage($alarmId);
            $shouldRing = in_array($currentWeekday, array_map('intval', $wochentage), true)
                       && ($alarmTime === $currentTime);
            break;
    }

    if (!$shouldRing) {
        continue;
    }

    // Snooze-Check: noch in der Snooze-Phase?
    if (
        !empty($state['snoozed_until'])
        && $now < (int) $state['snoozed_until']
        && ((int) ($state['snooze_alarm_id'] ?? 0)) === $alarmId
    ) {
        continue;
    }

    // Stop-Check: in dieser Minute bereits gestoppt?
    $stopKey = $alarmId . '_' . $currentTime . '_' . $currentDate;
    if (!empty($state['stopped_for']) && $state['stopped_for'] === $stopKey) {
        continue;
    }

    // Cover-URL ermitteln (erste Audio-Quelle)
    $coverUrl = null;
    if (function_exists('function_wecker_hole_audio')) {
        $audioEntries = function_wecker_hole_audio($alarmId);
        foreach ($audioEntries as $a) {
            $datei = trim((string) ($a['datei'] ?? ''));
            if ($datei === '') {
                continue;
            }
            if (strpos($datei, 'playlist:') === 0) {
                $pid = (int) substr($datei, 9);
                if ($pid > 0) {
                    $coverUrl = '/album_cover.php?album_id=' . $pid;
                }
            } else {
                $coverUrl = '/audio_cover.php?f=' . rawurlencode(basename($datei));
            }
            break;
        }
    }

    // Audio-URLs für Browser-Player berechnen
    // Reihenfolge: gleichzeitig (vor TTS) → TTS → danach
    $audioUrls = [];
    $ttsUrl    = null;
    $ttsText   = null;

    if (function_exists('function_wecker_audio_urls')) {
        $resolved = function_wecker_audio_urls($alarmId);
        $vorher   = $resolved['gleichzeitig'] ?? [];
        $danach   = $resolved['danach']       ?? [];

        // TTS-URL aus Cache holen
        try {
            if (function_exists('function_tts_text_ersetzen') && !empty($alarm['sprachtext'])) {
                $occurrence = function_exists('function_tts_occurrence_get')
                    ? function_tts_occurrence_get($alarmId, $ringDateTime)
                    : null;
                if (is_array($occurrence) && !empty($occurrence['audio_dateiname'])) {
                    $cachedFilename = (string) $occurrence['audio_dateiname'];
                    $ttsText = trim((string) ($occurrence['replaced_text'] ?? ''));
                    if ($ttsText === '') {
                        $ttsText = function_tts_text_ersetzen($alarm['sprachtext'], $ringDateTime, $alarmTime);
                    }
                } else {
                    $ttsText = function_tts_text_ersetzen($alarm['sprachtext'], $ringDateTime, $alarmTime);
                    $cachedFilename = function_exists('function_tts_cache_get')
                        ? function_tts_cache_get($ttsText)
                        : null;
                }
                if (!empty($cachedFilename)) {
                    $ttsUrl = '/tts_file.php?f=' . rawurlencode(basename($cachedFilename));
                } elseif (function_exists('function_tts_generieren')) {
                    $generated = function_tts_generieren($ttsText, null, ['skip_placeholder_replace' => true]);
                    if (!empty($generated['ok']) && !empty($generated['url'])) {
                        $ttsUrl = $generated['url'];
                        if (!empty($generated['file']) && function_exists('function_tts_cache_set')) {
                            function_tts_cache_set($ttsText, $generated['file']);
                        }
                        if (!empty($generated['file']) && function_exists('function_tts_occurrence_set')) {
                            function_tts_occurrence_set($alarmId, $ringDateTime, $generated['file'], $ttsText);
                        }
                    }
                }
            }
        } catch (Throwable $e) {
            // TTS-Cache nicht verfügbar – kein Fehler
        }

        // Geordnete Abspielliste aufbauen
        $audioUrls = array_values(array_filter(array_merge(
            $vorher,
            $ttsUrl !== null ? [$ttsUrl] : [],
            $danach
        )));
    }

    // Klingel-Zustand schreiben
    $newState = [
        'ringing'    => true,
        'alarm_id'   => $alarmId,
        'alarm_time' => $alarmTime,
        'tts_text'   => $ttsText,
        'cover_url'  => $coverUrl,
        'audio_urls' => $audioUrls,
        'started_at' => $now,
    ];
    @file_put_contents($stateFile, json_encode($newState));

    // Letzten Auslösezeitpunkt in DB aktualisieren
    try {
        $GLOBALS['pdo']
            ->prepare('UPDATE wecker SET zuletzt_ausgeloest = NOW() WHERE id = ?')
            ->execute([$alarmId]);
    } catch (Throwable $e) {
        // Nicht kritisch
    }

    break; // Nur ein Alarm gleichzeitig
}
