<?php
require __DIR__ . '/../config.php';
require FUNCTIONS_ROOT . '/functions_db.php';
require FUNCTIONS_ROOT . '/functions_wecker.php';
require FUNCTIONS_ROOT . '/functions_common.php';

$action = $_GET['action'] ?? $_POST['action'] ?? '';

/**
 * Stoppt den laufenden alarm_player.php-Prozess (inkl. Kindprozesse des Audio-Players).
 */
function alarm_kill_player(array $state): void
{
    if (PHP_OS_FAMILY !== 'Linux') {
        return;
    }
    $pid = isset($state['player_pid']) ? (int) $state['player_pid'] : 0;
    if ($pid > 0) {
        @exec('kill -TERM ' . $pid . ' 2>/dev/null');
        // Kindprozesse (aplay, mpg123, cvlc) die vom player gestartet wurden
        @exec('pkill -P ' . $pid . ' 2>/dev/null');
    }
    // Sicherheits-Fallback: alle alarm_player.php-Prozesse beenden
    @exec('pkill -f alarm_player.php 2>/dev/null');
    // Audio-Player killen die ggf. noch laufen
    foreach (['aplay', 'mpg123'] as $tool) {
        @exec('pkill -x ' . escapeshellarg($tool) . ' 2>/dev/null');
    }
}

function alarm_resolve_local_playback(int $alarmId, ?string $ringDate = null): array
{
    if ($alarmId <= 0) {
        return ['ok' => false, 'error' => 'Ungültige Alarm-ID'];
    }

    if (!function_exists('function_tts_cache_get')) {
        require FUNCTIONS_ROOT . '/functions_tts_cache.php';
    }
    if (!function_exists('function_tts_generieren')) {
        require FUNCTIONS_ROOT . '/functions_tts.php';
    }

    $alarm = function_wecker_hole($alarmId);
    if (!$alarm) {
        return ['ok' => false, 'error' => 'Wecker nicht gefunden'];
    }

    $zeitzone = trim((string) (function_einstellung_hole('zeitzone') ?: 'Europe/Berlin'));
    if ($zeitzone === '') {
        $zeitzone = 'Europe/Berlin';
    }
    $tz = new DateTimeZone($zeitzone);
    $alarmTime = substr((string) ($alarm['weckzeit'] ?? ''), 0, 5);
    if ($alarmTime === '') {
        return ['ok' => false, 'error' => 'Weckzeit fehlt'];
    }

    $ringDateTime = null;
    $ringDate = trim((string) $ringDate);
    if ($ringDate !== '') {
        $ringDateTime = DateTimeImmutable::createFromFormat('Y-m-d H:i', substr($ringDate, 0, 16), $tz) ?: null;
    }
    if (!$ringDateTime && ($alarm['wiederholung'] ?? 'taeglich') === 'einmal' && !empty($alarm['weckdatum'])) {
        $ringDateTime = DateTimeImmutable::createFromFormat('Y-m-d H:i', $alarm['weckdatum'] . ' ' . $alarmTime, $tz) ?: null;
    }
    if (!$ringDateTime) {
        $ringDateTime = (new DateTimeImmutable('now', $tz))->setTime((int) substr($alarmTime, 0, 2), (int) substr($alarmTime, 3, 2), 0);
    }

    $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;
        }
    }

    $resolved = function_exists('function_wecker_audio_urls') ? function_wecker_audio_urls($alarmId) : ['gleichzeitig' => [], 'danach' => []];
    $vorher = $resolved['gleichzeitig'] ?? [];
    $danach = $resolved['danach'] ?? [];
    $ttsText = '';
    $ttsUrl = null;

    try {
        if (!empty($alarm['sprachtext']) && function_exists('function_tts_text_ersetzen')) {
            $occurrence = function_exists('function_tts_occurrence_get')
                ? function_tts_occurrence_get($alarmId, $ringDateTime)
                : null;
            if (is_array($occurrence) && !empty($occurrence['audio_dateiname'])) {
                $ttsText = trim((string) ($occurrence['replaced_text'] ?? ''));
                if ($ttsText === '') {
                    $ttsText = function_tts_text_ersetzen((string) $alarm['sprachtext'], $ringDateTime, $alarmTime);
                }
                $ttsUrl = '/tts_file.php?f=' . rawurlencode(basename((string) $occurrence['audio_dateiname']));
            } else {
                $ttsText = function_tts_text_ersetzen((string) $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));
                    if (function_exists('function_tts_occurrence_set')) {
                        function_tts_occurrence_set($alarmId, $ringDateTime, $cachedFilename, $ttsText);
                    }
                } else {
                    $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) {
        error_log('[api_wecker][alarm_audio] ' . $e->getMessage());
    }

    return [
        'ok' => true,
        'alarm_id' => $alarmId,
        'alarm_time' => $alarmTime,
        'tts_text' => $ttsText,
        'cover_url' => $coverUrl,
        'audio_urls' => array_values(array_filter(array_merge($vorher, $ttsUrl !== null ? [$ttsUrl] : [], $danach))),
    ];
}

try {
    switch ($action) {
        case 'list': {
            $wecker = function_wecker_hole_alle();
            $wecker_fuer_js = function_wecker_fuer_frontend($wecker);
            function_json_antwort(true, ['wecker' => $wecker_fuer_js]);
        }

        case 'get': {
            $id = (int)($_GET['id'] ?? $_POST['id'] ?? 0);
            if ($id <= 0) {
                function_json_antwort(false, [], 'Ungültige ID');
            }
            $wecker = function_wecker_hole_komplett($id);
            if (!$wecker) {
                function_json_antwort(false, [], 'Wecker nicht gefunden');
            }
            function_json_antwort(true, ['wecker' => $wecker]);
        }

        case 'toggle': {
            $id = (int)($_GET['id'] ?? $_POST['id'] ?? 0);
            $aktiv = isset($_GET['aktiv']) ? (bool)(int)$_GET['aktiv'] : (isset($_POST['aktiv']) ? (bool)(int)$_POST['aktiv'] : null);
            if ($id <= 0 || $aktiv === null) {
                function_json_antwort(false, [], 'id und aktiv erforderlich');
            }
            function_wecker_setze_aktiv($id, $aktiv);
            function_json_antwort(true);
        }

        case 'save': {
            $id = (int)($_POST['id'] ?? 0);
            $weckzeit = trim($_POST['weckzeit'] ?? '');
            $weckdatum = trim($_POST['weckdatum'] ?? '') ?: null;
            $wiederholung = trim($_POST['wiederholung'] ?? 'taeglich');
            if (!in_array($wiederholung, ['einmal', 'taeglich', 'woechentlich'], true)) {
                $wiederholung = 'taeglich';
            }
            $wochentage = isset($_POST['wochentage']) && is_array($_POST['wochentage'])
                ? array_map('intval', $_POST['wochentage'])
                : [];
            $sprachtext = trim($_POST['sprachtext'] ?? '');
            $aktiv = isset($_POST['aktiv']) ? (int)(bool)$_POST['aktiv'] : 1;
            $lautstaerke_tts = isset($_POST['lautstaerke_tts']) ? (int) $_POST['lautstaerke_tts'] : null;
            $lautstaerke_musik = isset($_POST['lautstaerke_musik']) ? (int) $_POST['lautstaerke_musik'] : null;
            $musik_ducking_prozent = isset($_POST['musik_ducking_prozent']) ? (int) $_POST['musik_ducking_prozent'] : null;
            if ($lautstaerke_tts !== null) $lautstaerke_tts = max(0, min(100, $lautstaerke_tts));
            if ($lautstaerke_musik !== null) $lautstaerke_musik = max(0, min(100, $lautstaerke_musik));
            if ($musik_ducking_prozent !== null) $musik_ducking_prozent = max(0, min(100, $musik_ducking_prozent));

            if ($weckzeit === '' || $sprachtext === '') {
                function_json_antwort(false, [], 'Weckzeit und Sprachtext sind Pflichtfelder');
            }

            $daten = [
                'weckzeit'              => $weckzeit,
                'weckdatum'             => $weckdatum,
                'wiederholung'          => $wiederholung,
                'wochentage'            => $wochentage,
                'sprachtext'            => $sprachtext,
                'aktiv'                 => $aktiv,
                'lautstaerke_tts'       => $lautstaerke_tts,
                'lautstaerke_musik'     => $lautstaerke_musik,
                'musik_ducking_prozent' => $musik_ducking_prozent,
            ];

            $audio = [];
            $audioJson = $_POST['audio'] ?? '';
            if ($audioJson !== '') {
                $decoded = json_decode($audioJson, true);
                if (is_array($decoded)) {
                    $audio = $decoded;
                }
            }

            if ($id > 0) {
                $daten['weckdatum'] = $weckdatum;
                function_wecker_aktualisieren($id, $daten);
                function_wecker_setze_audio($id, $audio);
                function_json_antwort(true, ['id' => $id]);
            } else {
                $daten['weckdatum'] = $weckdatum;
                unset($daten['wochentage']);
                function_wecker_anlegen($daten);
                $newId = (int)$GLOBALS['pdo']->lastInsertId();
                if ($wiederholung === 'woechentlich' && !empty($wochentage)) {
                    function_wecker_setze_wochentage($newId, $wochentage);
                }
                function_wecker_setze_audio($newId, $audio);
                function_json_antwort(true, ['id' => $newId]);
            }
        }

        case 'delete': {
            $id = (int)($_GET['id'] ?? $_POST['id'] ?? 0);
            if ($id <= 0) {
                function_json_antwort(false, [], 'Ungültige ID');
            }
            function_wecker_loeschen($id);
            function_json_antwort(true);
        }

        case 'preview': {
            $text = trim($_POST['text'] ?? $_GET['text'] ?? '');
            $id = (int)($_POST['id'] ?? $_GET['id'] ?? 0);
            $weckzeitOverride = trim($_POST['weckzeit'] ?? $_GET['weckzeit'] ?? '');
            $weckzeit = null;
            if ($id > 0) {
                $wecker = function_wecker_hole($id);
                if ($wecker && !empty($wecker['weckzeit'])) {
                    $weckzeit = substr($wecker['weckzeit'], 0, 5);
                }
            }
            if ($weckzeit === null && $weckzeitOverride !== '') {
                $weckzeit = substr($weckzeitOverride, 0, 5);
            }
            $preview = function_tts_text_ersetzen($text, null, $weckzeit !== null && $weckzeit !== '' ? $weckzeit : null);
            function_json_antwort(true, ['preview' => $preview]);
        }

        case 'tts_custom_save': {
            $id = (int)($_POST['id'] ?? 0);
            $platzhalter = trim($_POST['platzhalter'] ?? '');
            $ersetzungstext = trim($_POST['ersetzungstext'] ?? '');
            $beschreibung = trim($_POST['beschreibung'] ?? '') ?: null;
            $aktiv = isset($_POST['aktiv']) ? (int)(bool)$_POST['aktiv'] : 1;
            $sortierung = (int)($_POST['sortierung'] ?? 0);

            if ($platzhalter === '') {
                function_json_antwort(false, [], 'Platzhalter ist Pflicht');
            }
            if (preg_match('/^\{\{[^}]+\}\}$/', $platzhalter) !== 1) {
                $platzhalter = '{{' . $platzhalter . '}}';
            }

            $daten = [
                'platzhalter'    => $platzhalter,
                'ersetzungstext' => $ersetzungstext,
                'beschreibung'   => $beschreibung,
                'aktiv'          => $aktiv,
                'sortierung'     => $sortierung
            ];

            if ($id > 0) {
                function_tts_custom_aktualisieren($id, $daten);
                function_json_antwort(true, ['id' => $id]);
            } else {
                $newId = function_tts_custom_anlegen($daten);
                function_json_antwort(true, ['id' => $newId]);
            }
        }

        case 'tts_custom_list': {
            $items = function_tts_custom_hole_alle();
            function_json_antwort(true, ['items' => $items]);
        }

        case 'tts_custom_delete': {
            $id = (int)($_GET['id'] ?? $_POST['id'] ?? 0);
            if ($id <= 0) {
                function_json_antwort(false, [], 'Ungültige ID');
            }
            function_tts_custom_loeschen($id);
            function_json_antwort(true);
        }

        case 'alarm_state': {
            $stateFile = defined('STORAGE_ROOT')
                ? STORAGE_ROOT . '/alarm_ringing.json'
                : dirname(__DIR__) . '/storage/alarm_ringing.json';
            $state = [];
            if (is_file($stateFile)) {
                $raw = @file_get_contents($stateFile);
                if ($raw !== false && $raw !== '') {
                    $state = @json_decode($raw, true) ?: [];
                }
            }
            $audioUrls = isset($state['audio_urls']) && is_array($state['audio_urls'])
                ? array_values($state['audio_urls'])
                : [];
            function_json_antwort(true, [
                'ringing'    => !empty($state['ringing']),
                'alarm_id'   => $state['alarm_id']   ?? null,
                'alarm_time' => $state['alarm_time'] ?? null,
                'tts_text'   => $state['tts_text']   ?? null,
                'cover_url'  => $state['cover_url']  ?? null,
                'audio_urls' => $audioUrls,
            ]);
        }

        case 'alarm_audio': {
            $alarmId = (int) ($_POST['id'] ?? $_GET['id'] ?? 0);
            $ringDate = trim((string) ($_POST['ring_date'] ?? $_GET['ring_date'] ?? ''));
            $payload = alarm_resolve_local_playback($alarmId, $ringDate !== '' ? $ringDate : null);
            if (!empty($payload['ok'])) {
                function_json_antwort(true, $payload);
            }
            function_json_antwort(false, [], $payload['error'] ?? 'Audio-Auflösung fehlgeschlagen');
        }

        case 'snooze': {
            $minutes   = max(1, min(60, (int) ($_POST['minutes'] ?? $_GET['minutes'] ?? 5)));
            $stateFile = defined('STORAGE_ROOT')
                ? STORAGE_ROOT . '/alarm_ringing.json'
                : dirname(__DIR__) . '/storage/alarm_ringing.json';
            $state = [];
            if (is_file($stateFile)) {
                $raw = @file_get_contents($stateFile);
                if ($raw !== false && $raw !== '') {
                    $state = @json_decode($raw, true) ?: [];
                }
            }
            // Laufenden Audio-Player stoppen
            alarm_kill_player($state);
            $newState = [
                'ringing'         => false,
                'snoozed_until'   => time() + ($minutes * 60),
                'snooze_alarm_id' => $state['alarm_id'] ?? null,
            ];
            @file_put_contents($stateFile, json_encode($newState));
            function_json_antwort(true, ['message' => 'Snoozed für ' . $minutes . ' Minuten.']);
        }

        case 'stop_alarm': {
            $stateFile = defined('STORAGE_ROOT')
                ? STORAGE_ROOT . '/alarm_ringing.json'
                : dirname(__DIR__) . '/storage/alarm_ringing.json';
            $state = [];
            if (is_file($stateFile)) {
                $raw = @file_get_contents($stateFile);
                if ($raw !== false && $raw !== '') {
                    $state = @json_decode($raw, true) ?: [];
                }
            }
            // Laufenden Audio-Player stoppen
            alarm_kill_player($state);
            $alarmId = $state['alarm_id'] ?? null;
            $stopKey = $alarmId . '_' . date('H:i') . '_' . date('Y-m-d');
            $newState = [
                'ringing'     => false,
                'stopped_for' => $stopKey,
            ];
            @file_put_contents($stateFile, json_encode($newState));
            function_json_antwort(true, ['message' => 'Alarm gestoppt.']);
        }

        default:
            function_json_antwort(false, [], 'Unbekannte Action');
    }
} catch (Throwable $e) {
    error_log('[api_wecker] ' . $e->getMessage());
    http_response_code(500);
    function_json_antwort(false, [], 'Serverfehler');
}
