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

$wecker = wecker_hole_alle();
$platzhalter_system = tts_hole_aktive_platzhalter();
$platzhalter_custom = tts_custom_hole_alle();
$tts_models = [];
$models_file = APP_ROOT . '/debug/tts_models.json';
if (file_exists($models_file)) {
    $cache = json_decode(file_get_contents($models_file), true);
    if (isset($cache['models']) && is_array($cache['models'])) {
        $tts_models = $cache['models'];
    }
}
$wochentage_labels = [1 => 'Mo', 2 => 'Di', 3 => 'Mi', 4 => 'Do', 5 => 'Fr', 6 => 'Sa', 7 => 'So'];
$wecker_fuer_js = [];
foreach ($wecker as $w) {
    $wochentage = ($w['wiederholung'] ?? '') === 'woechentlich' ? wecker_hole_wochentage((int)$w['id']) : [];
    $wecker_fuer_js[] = [
        'id' => (int)$w['id'],
        'weckzeit' => substr($w['weckzeit'], 0, 5),
        'weckdatum' => $w['weckdatum'] ?: null,
        'wiederholung' => $w['wiederholung'] ?? 'taeglich',
        'wochentage' => $wochentage,
        'sprachtext' => $w['sprachtext'] ?? '',
        'aktiv' => (bool)($w['aktiv'] ?? 0)
    ];
}
$zeitzonen = timezone_identifiers_list();
sort($zeitzonen);
?>
<!DOCTYPE html>
<html lang="de" id="htmlRoot">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<meta name="theme-color" content="#ffffff" id="metaThemeColor">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="apple-mobile-web-app-title" content="Wecker">
<title>Wecker</title>
<link rel="manifest" href="/manifest.json">
<link rel="apple-touch-icon" href="/icons/icon.svg">
<script>
(function(){
    var t = localStorage.getItem('wecker-theme');
    if (t !== 'light' && t !== 'dark') {
        t = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
    }
    document.documentElement.setAttribute('data-theme', t);
    var m = document.getElementById('metaThemeColor');
    if (m) m.content = t === 'dark' ? '#0d1117' : '#ffffff';
})();
</script>
<style>
:root, [data-theme="light"] {
    --bg: #ffffff;
    --card: #ffffff;
    --card-border: #eaeaea;
    --card-hover: #f5f5f5;
    --input-bg: #f5f5f5;
    --text: #1a1a1a;
    --text-muted: #6b6b6b;
    --text-inactive: #b0b0b0;
    --accent: #2563eb;
    --toggle-on: #7c3aed;
    --danger: #dc2626;
    --safe-top: env(safe-area-inset-top, 0);
    --safe-bottom: env(safe-area-inset-bottom, 0);
    --touch: 48px;
}

[data-theme="dark"] {
    --bg: #0d1117;
    --card: #161b22;
    --card-border: #30363d;
    --card-hover: #21262d;
    --input-bg: #0d1117;
    --text: #e6edf3;
    --text-muted: #8b949e;
    --text-inactive: #6e7681;
    --accent: #58a6ff;
    --toggle-on: #7c3aed;
    --danger: #f85149;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    min-height: 100vh;
    min-height: 100dvh;
    padding-bottom: calc(56px + var(--safe-bottom));
}

/* Header – „Alarm in X Minuten“ + Datum */
header {
    padding: 20px 16px;
    padding-top: max(20px, var(--safe-top));
    background: var(--bg);
    border-bottom: 1px solid var(--card-border);
    position: relative;
}

.header-top {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
}

.header-title {
    font-size: clamp(1.5rem, 6vw, 1.75rem);
    font-weight: 700;
    color: var(--text);
    margin: 0;
    line-height: 1.2;
}

.header-subtitle {
    font-size: 0.9375rem;
    color: var(--text-muted);
    margin: 4px 0 0 0;
}

.header-actions {
    display: flex;
    gap: 4px;
}

.header-btn {
    min-width: 44px;
    min-height: 44px;
    padding: 0;
    background: transparent;
    border: none;
    color: var(--text-muted);
    font-size: 1.5rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
}
.header-btn:hover { color: var(--text); background: var(--card-hover); }
.header-btn:active { transform: scale(0.96); }
.header-btn.danger { color: var(--danger); }

/* Alarm-Liste */
.main {
    padding: 12px 16px;
    max-width: 600px;
    margin: 0 auto;
}

.wecker {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 0;
    border-bottom: 1px solid var(--card-border);
    cursor: pointer;
    transition: background 0.15s;
    min-height: 72px;
}
.wecker:hover { background: var(--card-hover); }
.wecker:last-child { border-bottom: none; }

.wecker-left { flex: 1; min-width: 0; }
.wecker-label {
    font-size: 0.875rem;
    color: var(--text);
    margin: 0 0 2px 0;
    display: block;
}
.wecker.inaktiv .wecker-label { color: var(--text-inactive); }
.weckzeit {
    font-size: 1.75rem;
    font-weight: 400;
    letter-spacing: 0.02em;
    color: var(--text);
}
.wecker.inaktiv .weckzeit { color: var(--text-inactive); }

.wecker-meta {
    font-size: 0.8125rem;
    color: var(--text-muted);
    margin-top: 2px;
}
.wecker.inaktiv .wecker-meta { color: var(--text-inactive); }

.toggle {
    flex-shrink: 0;
}
.toggle input { display: none; }
.toggle span {
    display: block;
    width: 51px;
    height: 31px;
    background: #d1d5db;
    border-radius: 31px;
    position: relative;
    transition: background 0.2s;
}
.toggle span::after {
    content: '';
    position: absolute;
    width: 27px;
    height: 27px;
    background: #fff;
    border-radius: 50%;
    top: 2px;
    left: 2px;
    transition: transform 0.2s;
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
.toggle input:checked + span { background: var(--toggle-on); }
.toggle input:checked + span::after { transform: translateX(20px); }

/* Panels */
.panel { display: none; padding-bottom: calc(56px + var(--safe-bottom)); }
.panel.active { display: block; }
.panel .panel-inner { padding: 12px 16px; max-width: 600px; margin: 0 auto; }
.panel .panel-header { padding: 20px 16px; padding-top: max(20px, var(--safe-top)); background: var(--bg); border-bottom: 1px solid var(--card-border); }
.panel h2.panel-heading { font-size: 1.1rem; margin: 0 0 12px 0; color: var(--text-muted); }

.weltuhr-list { list-style: none; margin: 0; padding: 0; }
.weltuhr-list li { display: flex; justify-content: space-between; align-items: center; padding: 14px 0; border-bottom: 1px solid var(--card-border); }
.weltuhr-list li .ort { font-weight: 500; color: var(--text); }
.weltuhr-list li .zeit { font-size: 1.25rem; color: var(--accent); }
.weltuhr-list li button { padding: 4px 10px; font-size: 0.8rem; background: var(--card-hover); border: 1px solid var(--card-border); border-radius: 6px; color: var(--text); cursor: pointer; }
.weltuhr-add-form { margin-top: 12px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.weltuhr-add-form input { padding: 8px 10px; background: var(--input-bg); border: 1px solid var(--card-border); border-radius: 8px; color: var(--text); min-width: 120px; }
.stoppuhr-inner { text-align: center; padding-top: 24px; }
.stoppuhr-anzeige { font-size: 2.5rem; font-weight: 700; letter-spacing: 0.05em; color: var(--text); margin-bottom: 24px; font-variant-numeric: tabular-nums; }
.stoppuhr-buttons { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.timer-inner { text-align: center; padding-top: 24px; }
.timer-set { display: flex; align-items: center; justify-content: center; gap: 8px; margin-bottom: 16px; }
.timer-set input { width: 64px; padding: 10px; text-align: center; font-size: 1.25rem; background: var(--input-bg); border: 1px solid var(--card-border); border-radius: 8px; color: var(--text); }
.timer-anzeige { font-size: 2.5rem; font-weight: 700; letter-spacing: 0.05em; color: var(--text); margin-bottom: 16px; font-variant-numeric: tabular-nums; }
.timer-buttons { display: flex; gap: 10px; justify-content: center; }
.wetter-suche { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.wetter-suche input { flex: 1; min-width: 100px; padding: 10px 12px; background: var(--input-bg); border: 1px solid var(--card-border); border-radius: 8px; color: var(--text); }
.wetter-ergebnis { font-size: 0.95rem; color: var(--text); }
.wetter-ergebnis .wetter-aktuell { font-size: 1.25rem; margin-bottom: 12px; }
.wetter-ergebnis .wetter-vorhersage { margin-top: 12px; }
.wetter-ergebnis .tag { padding: 8px 0; border-bottom: 1px solid var(--card-border); }

/* Bottom Navigation */
.bottom-nav {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    height: calc(56px + var(--safe-bottom));
    padding-bottom: var(--safe-bottom);
    background: var(--bg);
    border-top: 1px solid var(--card-border);
    display: flex;
    justify-content: space-around;
    align-items: center;
    z-index: 20;
}

.bottom-nav a, .bottom-nav span, .bottom-nav button {
    font-size: 0.75rem;
    color: var(--text-muted);
    text-decoration: none;
    padding: 8px 6px;
    border: none;
    background: none;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    font-family: inherit;
}
.bottom-nav a:hover, .bottom-nav button:hover { color: var(--text); }
.bottom-nav a.active, .bottom-nav span.active, .bottom-nav button.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
    font-weight: 500;
}

/* Overlays */
.overlay {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.5);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 100;
    padding: var(--safe-top) 0 var(--safe-bottom);
    overflow-y: auto;
}

.overlay-box {
    background: var(--bg);
    border: 1px solid var(--card-border);
    padding: 20px;
    border-radius: 16px;
    width: 94%;
    max-width: 440px;
    max-height: 85vh;
    max-height: 85dvh;
    overflow-y: auto;
    margin: auto;
    box-shadow: 0 4px 24px rgba(0,0,0,0.12);
}

.overlay-box h2 { margin-top: 0; margin-bottom: 18px; font-size: 1.25rem; color: var(--text); }

.form-row { margin-bottom: 14px; }
.form-row label { display: block; margin-bottom: 6px; color: var(--text-muted); font-size: 0.875rem; }
.form-row input[type="time"],
.form-row input[type="date"],
.form-row input[type="text"],
.form-row select,
.form-row textarea {
    width: 100%;
    min-height: var(--touch);
    padding: 12px 14px;
    background: var(--input-bg);
    border: 1px solid var(--card-border);
    border-radius: 12px;
    color: var(--text);
    font-size: 1rem;
}
.form-row textarea { min-height: 88px; resize: vertical; }

.wochentage-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 8px; }
.wochentage-row label {
    display: flex; align-items: center; gap: 8px; margin: 0;
    cursor: pointer;
    min-height: var(--touch);
    padding: 4px 0;
    color: var(--text);
}
.wochentage-row input[type="checkbox"] { width: 22px; height: 22px; }

.form-actions { margin-top: 22px; display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.form-actions .header-btn { min-height: var(--touch); padding: 0 18px; background: var(--card-hover); border: 1px solid var(--card-border); color: var(--text); border-radius: 10px; font-size: 1rem; }
.form-actions .header-btn:hover { opacity: 0.9; }
.form-actions .header-btn.danger { background: rgba(220,38,38,0.15); color: var(--danger); border-color: transparent; }
[data-theme="dark"] .form-actions .header-btn.danger { background: rgba(248,81,73,0.2); }

.platzhalter-hint { font-size: 0.8rem; color: var(--text-muted); margin-top: 6px; line-height: 1.4; }

.audio-section .audio-groups { margin-top: 10px; }
.audio-group { margin-bottom: 14px; }
.audio-group-title { font-size: 0.875rem; font-weight: 600; color: var(--text); display: block; margin-bottom: 6px; }
.audio-list { list-style: none; margin: 0 0 8px 0; padding: 0; }
.audio-list li { display: flex; align-items: center; justify-content: space-between; padding: 6px 10px; background: var(--input-bg); border-radius: 8px; margin-bottom: 4px; font-size: 0.875rem; }
.audio-list li span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.audio-list li button { flex-shrink: 0; margin-left: 8px; padding: 2px 8px; font-size: 0.8rem; background: var(--card-hover); border: 1px solid var(--card-border); border-radius: 6px; color: var(--text); cursor: pointer; }
.audio-add { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.audio-add input[type="text"] { flex: 1; min-width: 120px; padding: 8px 10px; font-size: 0.875rem; background: var(--input-bg); border: 1px solid var(--card-border); border-radius: 8px; }

#settingsOverlay .overlay-box { max-width: 520px; }
.settings-section { margin-bottom: 22px; }
.settings-section h3 { margin: 0 0 10px 0; font-size: 0.95rem; color: var(--accent); }
.tts-custom-list { margin: 10px 0; }
.tts-custom-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 14px;
    background: var(--input-bg);
    border-radius: 12px;
    margin-bottom: 8px;
    border: 1px solid var(--card-border);
    gap: 10px;
}
.tts-custom-item span { font-size: 0.9rem; flex: 1; min-width: 0; color: var(--text); }
.tts-custom-item code { color: var(--accent); }
.tts-custom-item .btn-small { min-height: 40px; padding: 0 14px; font-size: 0.875rem; background: var(--card-hover); border: 1px solid var(--card-border); color: var(--text); border-radius: 8px; }
.settings-msg { margin-top: 12px; font-size: 0.9rem; color: var(--accent); }
.settings-msg.error { color: var(--danger); }

.zeitzone-dropdown-wrap { position: relative; }
.zeitzone-list {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin: 2px 0 0 0;
    padding: 0;
    list-style: none;
    max-height: 220px;
    overflow-y: auto;
    background: var(--card);
    border: 1px solid var(--card-border);
    border-radius: 10px;
    box-shadow: 0 4px 16px rgba(0,0,0,0.15);
    z-index: 50;
    display: none;
}
.zeitzone-list[aria-hidden="false"] { display: block; }
.zeitzone-list li {
    padding: 10px 12px;
    font-size: 0.9rem;
    color: var(--text);
    cursor: pointer;
    border-bottom: 1px solid var(--card-border);
}
.zeitzone-list li:last-child { border-bottom: none; }
.zeitzone-list li:hover { background: var(--card-hover); }
.zeitzone-list li.zeitzone-hidden { display: none; }
</style>
</head>
<body>

<div id="panelAlarm" class="panel active">
<header class="panel-header">
    <div class="header-top">
        <div>
            <h1 class="header-title" id="headerTitle">Alarm</h1>
            <p class="header-subtitle" id="headerSubtitle">–</p>
        </div>
        <div class="header-actions">
            <button type="button" class="header-btn" id="themeToggle" aria-label="Dark/Light Mode" title="Dark/Light Mode">🌙</button>
            <button type="button" class="header-btn" id="btnNeuWecker" aria-label="Neuer Alarm">＋</button>
            <button type="button" class="header-btn" id="btnOpenSettings" aria-label="Einstellungen">⋮</button>
        </div>
    </div>
</header>
<main class="main" id="weckerListe">
<?php
foreach ($wecker as $w):
    $aktiv = (bool)($w['aktiv'] ?? 0);
    $wochentage = ($w['wiederholung'] ?? '') === 'woechentlich' ? wecker_hole_wochentage((int)$w['id']) : [];
    if (($w['wiederholung'] ?? '') === 'woechentlich' && !empty($wochentage)) {
        $meta = implode(' ', array_map(function ($t) use ($wochentage_labels) { return $wochentage_labels[$t][0] ?? ''; }, $wochentage));
    } elseif (($w['wiederholung'] ?? '') === 'einmal' && !empty($w['weckdatum'])) {
        $d = DateTime::createFromFormat('Y-m-d', $w['weckdatum']);
        $monate = [1=>'Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'];
        $tage_kurz = ['Sun'=>'So','Mon'=>'Mo','Tue'=>'Di','Wed'=>'Mi','Thu'=>'Do','Fri'=>'Fr','Sat'=>'Sa'];
        if ($d) {
            $meta = ($tage_kurz[$d->format('D')] ?? $d->format('D')) . ', ' . $d->format('j') . '. ' . ($monate[(int)$d->format('n')] ?? $d->format('F'));
        } else {
            $meta = '';
        }
    } else {
        $meta = 'Täglich';
    }
    $label = $w['sprachtext'] ? (mb_strlen($w['sprachtext']) > 25 ? mb_substr($w['sprachtext'], 0, 22) . '…' : $w['sprachtext']) : '';
?>
    <div class="wecker <?= $aktiv ? '' : 'inaktiv' ?>" data-id="<?= (int)$w['id'] ?>" onclick="editWecker(<?= (int)$w['id'] ?>)">
        <div class="wecker-left">
            <?php if ($label !== ''): ?><span class="wecker-label"><?= htmlspecialchars($label) ?></span><?php endif; ?>
            <div class="weckzeit"><?= htmlspecialchars(substr($w['weckzeit'], 0, 5)) ?></div>
            <div class="wecker-meta"><?= htmlspecialchars($meta) ?></div>
        </div>
        <label class="toggle" onclick="event.stopPropagation()">
            <input type="checkbox" <?= $aktiv ? 'checked' : '' ?> onchange="toggleWecker(<?= (int)$w['id'] ?>, this.checked)">
            <span></span>
        </label>
    </div>
<?php endforeach; ?>
</main>
</div>

<div id="panelWeltuhr" class="panel">
    <header class="panel-header">
        <div class="header-top">
            <div>
                <h1 class="header-title">Weltuhr</h1>
                <p class="header-subtitle">Eigene Standorte</p>
            </div>
            <div class="header-actions">
                <button type="button" class="header-btn" id="themeToggle2" aria-label="Dark/Light Mode">🌙</button>
                <button type="button" class="header-btn" id="btnWeltuhrAdd" aria-label="Standort hinzufügen">＋</button>
            </div>
        </div>
    </header>
    <div class="panel-inner">
        <ul id="weltuhrListe" class="weltuhr-list"></ul>
        <div id="weltuhrAddForm" class="weltuhr-add-form" style="display:none;">
            <input type="text" id="weltuhrLabel" placeholder="z.B. New York">
            <input type="text" id="weltuhrZeitzone" placeholder="Zeitzone suchen…" list="weltuhrZeitzoneList">
            <datalist id="weltuhrZeitzoneList"></datalist>
            <button type="button" class="header-btn" id="btnWeltuhrSave">Hinzufügen</button>
            <button type="button" class="header-btn" id="btnWeltuhrCancel">Abbrechen</button>
        </div>
    </div>
</div>

<div id="panelStoppuhr" class="panel">
    <header class="panel-header">
        <div class="header-top">
            <div>
                <h1 class="header-title">Stoppuhr</h1>
            </div>
            <div class="header-actions">
                <button type="button" class="header-btn" id="themeToggle3" aria-label="Dark/Light Mode">🌙</button>
            </div>
        </div>
    </header>
    <div class="panel-inner stoppuhr-inner">
        <div id="stoppuhrAnzeige" class="stoppuhr-anzeige">00:00:00.00</div>
        <div class="stoppuhr-buttons">
            <button type="button" class="header-btn" id="stoppuhrStart">Start</button>
            <button type="button" class="header-btn" id="stoppuhrStop" disabled>Stop</button>
            <button type="button" class="header-btn" id="stoppuhrReset">Zurücksetzen</button>
        </div>
    </div>
</div>

<div id="panelTimer" class="panel">
    <header class="panel-header">
        <div class="header-top">
            <div>
                <h1 class="header-title">Timer</h1>
            </div>
            <div class="header-actions">
                <button type="button" class="header-btn" id="themeToggle4" aria-label="Dark/Light Mode">🌙</button>
            </div>
        </div>
    </header>
    <div class="panel-inner timer-inner">
        <div class="timer-set">
            <input type="number" id="timerMin" min="0" max="99" value="5" placeholder="Min">
            <span>:</span>
            <input type="number" id="timerSek" min="0" max="59" value="0" placeholder="Sek">
        </div>
        <div id="timerAnzeige" class="timer-anzeige" style="display:none;">05:00</div>
        <div class="timer-buttons">
            <button type="button" class="header-btn" id="timerStart">Start</button>
            <button type="button" class="header-btn" id="timerStop" style="display:none;">Stop</button>
        </div>
    </div>
</div>

<div id="panelWetter" class="panel">
    <header class="panel-header">
        <div class="header-top">
            <div>
                <h1 class="header-title">Wetter</h1>
                <p class="header-subtitle">Nach PLZ (Deutschland)</p>
            </div>
            <div class="header-actions">
                <button type="button" class="header-btn" id="themeToggle5" aria-label="Dark/Light Mode">🌙</button>
            </div>
        </div>
    </header>
    <div class="panel-inner">
        <div class="wetter-suche">
            <input type="text" id="wetterPlz" placeholder="PLZ (z.B. 10115)" maxlength="5">
            <button type="button" class="header-btn" id="wetterAktualisieren">Aktualisieren</button>
        </div>
        <div id="wetterErgebnis" class="wetter-ergebnis"></div>
    </div>
</div>

<nav class="bottom-nav" aria-label="Hauptnavigation">
    <button type="button" data-panel="panelAlarm" class="active">Alarm</button>
    <button type="button" data-panel="panelWeltuhr">Weltuhr</button>
    <button type="button" data-panel="panelStoppuhr">Stoppuhr</button>
    <button type="button" data-panel="panelTimer">Timer</button>
    <button type="button" data-panel="panelWetter">Wetter</button>
</nav>

<!-- Edit Overlay -->
<div id="editOverlay" class="overlay" onclick="closeEdit()">
    <div id="editBox" class="overlay-box" onclick="event.stopPropagation()">
        <h2 id="editTitle">Wecker bearbeiten</h2>
        <form id="editForm" onsubmit="return saveWecker(event)">
            <input type="hidden" name="id" id="editId" value="0">
            <div class="form-row">
                <label>Weckzeit</label>
                <input type="time" name="weckzeit" id="editWeckzeit" required>
            </div>
            <div class="form-row">
                <label>Wiederholung</label>
                <select name="wiederholung" id="editWiederholung" onchange="toggleWochentageVisibility()">
                    <option value="einmal">Einmal</option>
                    <option value="taeglich">Täglich</option>
                    <option value="woechentlich">Wöchentlich</option>
                </select>
            </div>
            <div class="form-row" id="rowWeckdatum">
                <label>Datum (nur bei „Einmal“)</label>
                <input type="date" name="weckdatum" id="editWeckdatum">
            </div>
            <div class="form-row" id="rowWochentage" style="display:none">
                <label>Wochentage</label>
                <div class="wochentage-row">
                    <?php foreach ($wochentage_labels as $num => $label): ?>
                    <label><input type="checkbox" name="wochentage[]" value="<?= $num ?>"> <?= $label ?></label>
                    <?php endforeach; ?>
                </div>
            </div>
            <div class="form-row">
                <label>Sprachtext (TTS)</label>
                <textarea name="sprachtext" id="editSprachtext" required></textarea>
                <p class="platzhalter-hint">
                    System: <?= htmlspecialchars(implode(', ', array_column($platzhalter_system, 'platzhalter'))) ?>
                    <?php if (!empty($platzhalter_custom)): ?>
                    · Eigen: <?= htmlspecialchars(implode(', ', array_column($platzhalter_custom, 'platzhalter'))) ?>
                    <?php endif; ?>
                </p>
            </div>
            <div class="form-row audio-section">
                <label>Musik / Lieder</label>
                <p class="platzhalter-hint">Optional: Lieder, die vor dem TTS, gleichzeitig oder danach abgespielt werden.</p>
                <div class="audio-groups">
                    <div class="audio-group">
                        <span class="audio-group-title">Vorher</span>
                        <ul id="audioListVorher" class="audio-list"></ul>
                        <div class="audio-add">
                            <input type="text" id="audioPfadVorher" placeholder="Pfad oder URL (z.B. /WAV/song.mp3)">
                            <input type="text" id="audioTitelVorher" placeholder="Titel (optional)">
                            <button type="button" class="header-btn btn-small" onclick="addAudio('vorher')">+</button>
                        </div>
                    </div>
                    <div class="audio-group">
                        <span class="audio-group-title">Gleichzeitig mit TTS</span>
                        <ul id="audioListGleichzeitig" class="audio-list"></ul>
                        <div class="audio-add">
                            <input type="text" id="audioPfadGleichzeitig" placeholder="Pfad oder URL">
                            <input type="text" id="audioTitelGleichzeitig" placeholder="Titel (optional)">
                            <button type="button" class="header-btn btn-small" onclick="addAudio('gleichzeitig')">+</button>
                        </div>
                    </div>
                    <div class="audio-group">
                        <span class="audio-group-title">Danach</span>
                        <ul id="audioListDanach" class="audio-list"></ul>
                        <div class="audio-add">
                            <input type="text" id="audioPfadDanach" placeholder="Pfad oder URL">
                            <input type="text" id="audioTitelDanach" placeholder="Titel (optional)">
                            <button type="button" class="header-btn btn-small" onclick="addAudio('danach')">+</button>
                        </div>
                    </div>
                </div>
                <input type="hidden" name="audio" id="editAudio" value="[]">
            </div>
            <div class="form-actions">
                <button type="submit" class="header-btn">Speichern</button>
                <button type="button" class="header-btn" onclick="closeEdit()">Abbrechen</button>
                <button type="button" id="btnDeleteWecker" class="header-btn danger" onclick="deleteWecker()" style="display:none">Löschen</button>
            </div>
        </form>
    </div>
</div>

<!-- Settings Overlay -->
<div id="settingsOverlay" class="overlay" onclick="closeSettings(event)">
    <div class="overlay-box" onclick="event.stopPropagation()">
        <h2>Einstellungen</h2>
        <div class="settings-section">
            <h3>TTS</h3>
            <div class="form-row">
                <label>Ihr Name (für TTS)</label>
                <input type="text" id="settingTtsName" placeholder="z.B. Max" maxlength="100" autocomplete="name">
                <p class="platzhalter-hint">Im Sprachtext können Sie <code>{{name}}</code> verwenden – wird beim Abspielen durch Ihren Namen ersetzt.</p>
            </div>
            <div class="form-row">
                <label>Sprachmodell</label>
                <select id="settingTtsModell">
                    <?php foreach ($tts_models as $m): ?>
                    <option value="<?= htmlspecialchars($m['id']) ?>"><?= htmlspecialchars($m['label']) ?></option>
                    <?php endforeach; ?>
                </select>
            </div>
            <div class="form-row">
                <label>TTS-Lautstärke (0–100)</label>
                <input type="range" id="settingLautstaerke" min="0" max="100" value="100">
                <span id="settingLautstaerkeVal">100</span> %
            </div>
            <div class="form-row">
                <label>Musik-/Audio-Lautstärke (0–100)</label>
                <input type="range" id="settingLautstaerkeMusik" min="0" max="100" value="80">
                <span id="settingLautstaerkeMusikVal">80</span> %
            </div>
            <div class="form-row">
                <label>Während TTS: Musik dämpfen auf … %</label>
                <input type="range" id="settingMusikDucking" min="0" max="100" value="20">
                <span id="settingMusikDuckingVal">20</span> %
                <p class="platzhalter-hint">Beim TTS-Spruch wird die Musik auf diesen Wert reduziert, damit die Ansage gut hörbar ist.</p>
            </div>
        </div>
        <div class="settings-section">
            <h3>Zeitzone</h3>
            <div class="form-row zeitzone-dropdown-wrap">
                <input type="text" id="settingZeitzone" placeholder="Suchen oder auswählen…" autocomplete="off" role="combobox" aria-expanded="false" aria-autocomplete="list">
                <ul id="zeitzoneList" class="zeitzone-list" role="listbox" aria-hidden="true"></ul>
            </div>
        </div>
        <div class="settings-section">
            <h3>Benutzerdefinierte TTS-Platzhalter</h3>
            <p class="platzhalter-hint">Diese Platzhalter können Sie im Wecker-Sprachtext verwenden (z.B. {{name}}).</p>
            <div id="ttsCustomList" class="tts-custom-list"></div>
            <div class="form-row">
                <label>Platzhalter (z.B. weckername → {{weckername}})</label>
                <input type="text" id="customPlatzhalter" placeholder="weckername">
            </div>
            <div class="form-row">
                <label>Ersetzungstext</label>
                <input type="text" id="customErsetzungstext" placeholder="Guten Morgen">
            </div>
            <div class="form-row">
                <label>Beschreibung (optional)</label>
                <input type="text" id="customBeschreibung" placeholder="Begrüßung">
            </div>
            <input type="hidden" id="customId" value="0">
            <button type="button" class="header-btn" id="btnCustomSave">Hinzufügen / Speichern</button>
        </div>
        <div id="settingsMsg" class="settings-msg"></div>
        <div class="form-actions" style="margin-top:16px">
            <button type="button" class="header-btn" onclick="saveSettings()">Einstellungen speichern</button>
            <button type="button" class="header-btn" onclick="closeSettings()">Schließen</button>
        </div>
    </div>
</div>

<script>
const API_WECKER = 'api_wecker.php';
const API_EINSTELLUNGEN = 'api_einstellungen.php';
const WECKER_LISTE = <?= json_encode($wecker_fuer_js) ?>;
const ZEITZONEN = <?= json_encode($zeitzonen) ?>;

let audioList = [];
let zeitzoneListCloseTimer = null;

function initZeitzoneDropdown() {
    var input = document.getElementById('settingZeitzone');
    var list = document.getElementById('zeitzoneList');
    if (!input || !list) return;

    if (list.children.length === 0) {
        ZEITZONEN.forEach(function(z) {
            var li = document.createElement('li');
            li.setAttribute('role', 'option');
            li.textContent = z;
            li.dataset.value = z;
            li.addEventListener('click', function() {
                input.value = z;
                list.setAttribute('aria-hidden', 'true');
                input.setAttribute('aria-expanded', 'false');
            });
            list.appendChild(li);
        });
    }

    function filterList() {
        var q = (input.value || '').toLowerCase();
        var items = list.querySelectorAll('li');
        items.forEach(function(li) {
            var show = !q || li.dataset.value.toLowerCase().indexOf(q) !== -1;
            li.classList.toggle('zeitzone-hidden', !show);
        });
        list.setAttribute('aria-hidden', 'false');
        input.setAttribute('aria-expanded', 'true');
    }

    function closeList() {
        zeitzoneListCloseTimer = setTimeout(function() {
            list.setAttribute('aria-hidden', 'true');
            input.setAttribute('aria-expanded', 'false');
        }, 200);
    }

    input.addEventListener('focus', filterList);
    input.addEventListener('input', filterList);
    input.addEventListener('keydown', function(e) {
        if (e.key === 'Escape') { list.setAttribute('aria-hidden', 'true'); input.setAttribute('aria-expanded', 'false'); }
    });
    input.addEventListener('blur', closeList);
    list.addEventListener('mousedown', function(e) { e.preventDefault(); });
}

function getTheme() {
    var t = document.documentElement.getAttribute('data-theme');
    return (t === 'light' || t === 'dark') ? t : 'light';
}

function setTheme(theme) {
    theme = theme === 'dark' ? 'dark' : 'light';
    document.documentElement.setAttribute('data-theme', theme);
    localStorage.setItem('wecker-theme', theme);
    var meta = document.getElementById('metaThemeColor');
    if (meta) meta.content = theme === 'dark' ? '#0d1117' : '#ffffff';
    var btn = document.getElementById('themeToggle');
    if (btn) btn.textContent = theme === 'dark' ? '☀️' : '🌙';
}

function toggleTheme() {
    setTheme(getTheme() === 'dark' ? 'light' : 'dark');
}

(function updateThemeButton() {
    var btn = document.getElementById('themeToggle');
    if (btn) btn.textContent = getTheme() === 'dark' ? '☀️' : '🌙';
})();

function showPanel(panelId) {
    if (weltuhrInterval) { clearInterval(weltuhrInterval); weltuhrInterval = null; }
    document.querySelectorAll('.panel').forEach(function(p) { p.classList.remove('active'); });
    document.querySelectorAll('.bottom-nav button[data-panel]').forEach(function(b) { b.classList.remove('active'); });
    var p = document.getElementById(panelId);
    var btn = document.querySelector('.bottom-nav button[data-panel="' + panelId + '"]');
    if (p) p.classList.add('active');
    if (btn) btn.classList.add('active');
    if (panelId === 'panelWeltuhr') weltuhrTick();
    if (panelId === 'panelWetter') loadWetterFromStorage();
}

document.addEventListener('DOMContentLoaded', function() {
    initZeitzoneDropdown();
    var btnTheme = document.getElementById('themeToggle');
    if (btnTheme) btnTheme.addEventListener('click', toggleTheme);
    ['themeToggle2','themeToggle3','themeToggle4','themeToggle5'].forEach(function(id) {
        var b = document.getElementById(id);
        if (b) b.addEventListener('click', toggleTheme);
    });
    var btnNeu = document.getElementById('btnNeuWecker');
    if (btnNeu) btnNeu.addEventListener('click', neuWecker);
    var btnSettings = document.getElementById('btnOpenSettings');
    if (btnSettings) btnSettings.addEventListener('click', openSettings);

    document.querySelectorAll('.bottom-nav button[data-panel]').forEach(function(btn) {
        btn.addEventListener('click', function() { showPanel(btn.getAttribute('data-panel')); });
    });

    initWeltuhr();
    initStoppuhr();
    initTimer();
    initWetter();
});

function renderAudioLists() {
    ['vorher', 'gleichzeitig', 'danach'].forEach(function(pos) {
        const ul = document.getElementById('audioList' + pos.charAt(0).toUpperCase() + pos.slice(1));
        ul.innerHTML = '';
        audioList.filter(function(a) { return a.position === pos; }).forEach(function(a, i) {
            const idx = audioList.indexOf(a);
            const li = document.createElement('li');
            li.innerHTML = '<span title="' + escapeHtml(a.datei) + '">' + escapeHtml(a.titel || a.datei) + '</span><button type="button" onclick="removeAudio(' + idx + ')">Entfernen</button>';
            ul.appendChild(li);
        });
    });
    document.getElementById('editAudio').value = JSON.stringify(audioList);
}

function addAudio(position) {
    const pfadId = 'audioPfad' + position.charAt(0).toUpperCase() + position.slice(1);
    const titelId = 'audioTitel' + position.charAt(0).toUpperCase() + position.slice(1);
    const pfad = (document.getElementById(pfadId).value || '').trim();
    if (!pfad) return;
    audioList.push({ datei: pfad, titel: (document.getElementById(titelId).value || '').trim() || null, position: position });
    document.getElementById(pfadId).value = '';
    document.getElementById(titelId).value = '';
    renderAudioLists();
}

function removeAudio(index) {
    audioList.splice(index, 1);
    renderAudioLists();
}

function getNextAlarm() {
    const now = new Date();
    let next = null;
    const tag = now.getDay() || 7;
    const heute = now.toISOString().slice(0, 10);
    WECKER_LISTE.forEach(function(w) {
        if (!w.aktiv) return;
        const [h, m] = (w.weckzeit || '00:00').split(':').map(Number);
        if (w.wiederholung === 'einmal') {
            if (!w.weckdatum) return;
            const d = new Date(w.weckdatum + 'T' + (h < 10 ? '0' : '') + h + ':' + (m < 10 ? '0' : '') + m + ':00');
            if (d > now && (!next || d < next.dateTime)) next = { dateTime: d, label: w.sprachtext || w.weckzeit };
        } else if (w.wiederholung === 'woechentlich' && w.wochentage && w.wochentage.length) {
            for (let i = 0; i <= 7; i++) {
                const d = new Date(now);
                d.setDate(d.getDate() + i);
                const t = d.getDay() || 7;
                if (w.wochentage.indexOf(t) === -1) continue;
                d.setHours(h, m, 0, 0);
                if (d > now && (!next || d < next.dateTime)) next = { dateTime: d, label: w.sprachtext || w.weckzeit };
            }
        } else {
            const d = new Date(now);
            d.setHours(h, m, 0, 0);
            if (d <= now) d.setDate(d.getDate() + 1);
            if (!next || d < next.dateTime) next = { dateTime: d, label: w.sprachtext || w.weckzeit };
        }
    });
    return next;
}

function updateHeader() {
    const next = getNextAlarm();
    const titleEl = document.getElementById('headerTitle');
    const subEl = document.getElementById('headerSubtitle');
    if (!next) {
        titleEl.textContent = 'Kein Alarm';
        subEl.textContent = '–';
        return;
    }
    const min = Math.round((next.dateTime - new Date()) / 60000);
    if (min < 0) { updateHeader(); return; }
    if (min < 60) titleEl.textContent = 'Alarm in ' + min + ' Minute' + (min !== 1 ? 'n' : '');
    else if (min < 1440) titleEl.textContent = 'Alarm in ' + Math.round(min / 60) + ' Stunde' + (Math.round(min / 60) !== 1 ? 'n' : '');
    else titleEl.textContent = 'Alarm in ' + Math.round(min / 1440) + ' Tag' + (Math.round(min / 1440) !== 1 ? 'en' : '');
    const opts = { weekday: 'short', day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' };
    subEl.textContent = next.dateTime.toLocaleDateString('de-DE', opts);
}
updateHeader();
setInterval(updateHeader, 60000);

function toggleWochentageVisibility() {
    const w = document.getElementById('editWiederholung').value;
    document.getElementById('rowWochentage').style.display = w === 'woechentlich' ? 'block' : 'none';
    document.getElementById('rowWeckdatum').style.display = w === 'einmal' ? 'block' : 'none';
}

function editWecker(id) {
    fetch(API_WECKER + '?action=get&id=' + encodeURIComponent(id))
        .then(r => r.json())
        .then(data => {
            if (!data.ok) { alert(data.error || 'Fehler'); return; }
            const w = data.wecker;
            document.getElementById('editTitle').textContent = 'Wecker bearbeiten';
            document.getElementById('editId').value = w.id;
            document.getElementById('editWeckzeit').value = (w.weckzeit || '').substring(0, 5);
            document.getElementById('editWeckdatum').value = w.weckdatum || '';
            document.getElementById('editWiederholung').value = w.wiederholung || 'taeglich';
            document.getElementById('editSprachtext').value = w.sprachtext || '';
            const wochentage = w.wochentage || [];
            document.querySelectorAll('#editForm input[name="wochentage[]"]').forEach(cb => {
                cb.checked = wochentage.indexOf(parseInt(cb.value, 10)) !== -1;
            });
            toggleWochentageVisibility();
            audioList = Array.isArray(w.audio) ? w.audio.map(function(a) { return { datei: a.datei, titel: a.titel || null, position: a.position || 'danach' }; }) : [];
            renderAudioLists();
            document.getElementById('btnDeleteWecker').style.display = '';
            document.getElementById('editOverlay').style.display = 'flex';
        })
        .catch(() => alert('Fehler beim Laden'));
}

function neuWecker() {
    document.getElementById('editTitle').textContent = 'Neuer Wecker';
    document.getElementById('editId').value = '0';
    document.getElementById('editWeckzeit').value = '07:00';
    document.getElementById('editWeckdatum').value = '';
    document.getElementById('editWiederholung').value = 'taeglich';
    document.getElementById('editSprachtext').value = '';
    document.querySelectorAll('#editForm input[name="wochentage[]"]').forEach(cb => { cb.checked = false; });
    audioList = [];
    renderAudioLists();
    toggleWochentageVisibility();
    document.getElementById('btnDeleteWecker').style.display = 'none';
    document.getElementById('editOverlay').style.display = 'flex';
}

function closeEdit() {
    document.getElementById('editOverlay').style.display = 'none';
}

function toggleWecker(id, aktiv) {
    const card = document.querySelector('.wecker[data-id="' + id + '"]');
    const checkbox = card ? card.querySelector('input[type="checkbox"]') : null;
    const prev = !aktiv;
    if (card) card.classList.toggle('inaktiv', !aktiv);
    fetch(API_WECKER + '?action=toggle&id=' + encodeURIComponent(id) + '&aktiv=' + (aktiv ? '1' : '0'))
        .then(r => r.json())
        .then(data => {
            if (!data.ok && checkbox) { checkbox.checked = prev; if (card) card.classList.toggle('inaktiv', prev); alert(data.error || 'Fehler'); }
            else if (data.ok) updateHeader();
        })
        .catch(() => { if (checkbox) checkbox.checked = prev; if (card) card.classList.toggle('inaktiv', prev); alert('Netzwerkfehler'); });
}

function saveWecker(e) {
    e.preventDefault();
    document.getElementById('editAudio').value = JSON.stringify(audioList);
    const form = document.getElementById('editForm');
    const fd = new FormData(form);
    fd.set('action', 'save');
    fetch(API_WECKER, { method: 'POST', body: fd })
        .then(r => r.json())
        .then(data => {
            if (!data.ok) { alert(data.error || 'Fehler'); return; }
            closeEdit();
            location.reload();
        })
        .catch(() => alert('Fehler beim Speichern'));
    return false;
}

function deleteWecker() {
    const id = document.getElementById('editId').value;
    if (!id || id === '0') return;
    if (!confirm('Wecker wirklich löschen?')) return;
    const fd = new FormData();
    fd.set('action', 'delete');
    fd.set('id', id);
    fetch(API_WECKER, { method: 'POST', body: fd })
        .then(r => r.json())
        .then(data => {
            if (!data.ok) { alert(data.error || 'Fehler'); return; }
            closeEdit();
            location.reload();
        })
        .catch(() => alert('Fehler beim Löschen'));
}

function openSettings() {
    document.getElementById('settingsOverlay').style.display = 'flex';
    document.getElementById('settingsMsg').textContent = '';
    fetch(API_EINSTELLUNGEN)
        .then(r => r.json())
        .then(data => {
            if (!data.ok) return;
            const e = data.einstellungen || {};
            document.getElementById('settingTtsName').value = e.tts_name || '';
            document.getElementById('settingTtsModell').value = e.tts_modell || 'de_DE-thorsten-high';
            document.getElementById('settingLautstaerke').value = e.lautstaerke || '100';
            document.getElementById('settingLautstaerkeVal').textContent = e.lautstaerke || '100';
            document.getElementById('settingLautstaerkeMusik').value = e.lautstaerke_musik || '80';
            document.getElementById('settingLautstaerkeMusikVal').textContent = e.lautstaerke_musik || '80';
            document.getElementById('settingMusikDucking').value = e.musik_ducking_prozent || '20';
            document.getElementById('settingMusikDuckingVal').textContent = e.musik_ducking_prozent || '20';
            document.getElementById('settingZeitzone').value = e.zeitzone || 'Europe/Berlin';
        });
    loadTtsCustomList();
}

function closeSettings(ev) {
    if (ev && ev.target !== ev.currentTarget) return;
    document.getElementById('settingsOverlay').style.display = 'none';
}

document.getElementById('settingLautstaerke').addEventListener('input', function() {
    document.getElementById('settingLautstaerkeVal').textContent = this.value;
});

function loadTtsCustomList() {
    fetch(API_WECKER + '?action=tts_custom_list')
        .then(r => r.json())
        .then(data => {
            const list = document.getElementById('ttsCustomList');
            list.innerHTML = '';
            if (!data.ok || !data.items || data.items.length === 0) {
                list.innerHTML = '<p class="platzhalter-hint">Keine benutzerdefinierten Platzhalter.</p>';
                return;
            }
            data.items.forEach(item => {
                const div = document.createElement('div');
                div.className = 'tts-custom-item';
                div.innerHTML = '<span><code>' + escapeHtml(item.platzhalter) + '</code> → ' + escapeHtml(item.ersetzungstext) + '</span>' +
                    '<div><button type="button" class="header-btn btn-small" onclick="editCustom(' + item.id + ')">Bearb.</button> ' +
                    '<button type="button" class="header-btn btn-small danger" onclick="deleteCustom(' + item.id + ')">Löschen</button></div>';
                list.appendChild(div);
            });
        });
}

function escapeHtml(s) {
    const d = document.createElement('div');
    d.textContent = s;
    return d.innerHTML;
}

function editCustom(id) {
    fetch(API_WECKER + '?action=tts_custom_list')
        .then(r => r.json())
        .then(data => {
            if (!data.ok || !data.items) return;
            const item = data.items.find(i => parseInt(i.id, 10) === id);
            if (!item) return;
            document.getElementById('customId').value = item.id;
            document.getElementById('customPlatzhalter').value = (item.platzhalter || '').replace(/^\{\{|\}\}$/g, '');
            document.getElementById('customErsetzungstext').value = item.ersetzungstext || '';
            document.getElementById('customBeschreibung').value = item.beschreibung || '';
            document.getElementById('btnCustomSave').textContent = 'Speichern';
        });
}

function deleteCustom(id) {
    if (!confirm('Platzhalter löschen?')) return;
    const fd = new FormData();
    fd.set('action', 'tts_custom_delete');
    fd.set('id', id);
    fetch(API_WECKER, { method: 'POST', body: fd })
        .then(r => r.json())
        .then(data => {
            if (data.ok) loadTtsCustomList();
            else document.getElementById('settingsMsg').textContent = data.error || 'Fehler';
            document.getElementById('settingsMsg').className = 'settings-msg' + (data.ok ? '' : ' error');
        });
}

document.getElementById('btnCustomSave').addEventListener('click', function() {
    const id = document.getElementById('customId').value;
    const platzhalter = (document.getElementById('customPlatzhalter').value || '').trim();
    const ersetzungstext = (document.getElementById('customErsetzungstext').value || '').trim();
    const beschreibung = (document.getElementById('customBeschreibung').value || '').trim();
    if (!platzhalter) { document.getElementById('settingsMsg').textContent = 'Platzhalter eingeben'; document.getElementById('settingsMsg').className = 'settings-msg error'; return; }
    const fd = new FormData();
    fd.set('action', 'tts_custom_save');
    if (id && id !== '0') fd.set('id', id);
    fd.set('platzhalter', platzhalter);
    fd.set('ersetzungstext', ersetzungstext);
    fd.set('beschreibung', beschreibung);
    fd.set('aktiv', '1');
    fetch(API_WECKER, { method: 'POST', body: fd })
        .then(r => r.json())
        .then(data => {
            if (!data.ok) { document.getElementById('settingsMsg').textContent = data.error || 'Fehler'; document.getElementById('settingsMsg').className = 'settings-msg error'; return; }
            document.getElementById('customId').value = '0';
            document.getElementById('customPlatzhalter').value = '';
            document.getElementById('customErsetzungstext').value = '';
            document.getElementById('customBeschreibung').value = '';
            document.getElementById('btnCustomSave').textContent = 'Hinzufügen / Speichern';
            document.getElementById('settingsMsg').textContent = 'Gespeichert.';
            document.getElementById('settingsMsg').className = 'settings-msg';
            loadTtsCustomList();
        });
});

function saveSettings() {
    const fd = new FormData();
    fd.set('tts_name', document.getElementById('settingTtsName').value);
    fd.set('tts_modell', document.getElementById('settingTtsModell').value);
    fd.set('lautstaerke', document.getElementById('settingLautstaerke').value);
    fd.set('lautstaerke_musik', document.getElementById('settingLautstaerkeMusik').value);
    fd.set('musik_ducking_prozent', document.getElementById('settingMusikDucking').value);
    fd.set('zeitzone', document.getElementById('settingZeitzone').value);
    fetch(API_EINSTELLUNGEN, { method: 'POST', body: fd })
        .then(r => r.json())
        .then(data => {
            const msg = document.getElementById('settingsMsg');
            msg.textContent = data.ok ? 'Einstellungen gespeichert.' : (data.error || 'Fehler');
            msg.className = 'settings-msg' + (data.ok ? '' : ' error');
        })
        .catch(() => {
            document.getElementById('settingsMsg').textContent = 'Netzwerkfehler';
            document.getElementById('settingsMsg').className = 'settings-msg error';
        });
}

var weltuhrInterval = null;
function initWeltuhr() {
    var list = document.getElementById('weltuhrListe');
    var addForm = document.getElementById('weltuhrAddForm');
    var btnAdd = document.getElementById('btnWeltuhrAdd');
    var btnSave = document.getElementById('btnWeltuhrSave');
    var btnCancel = document.getElementById('btnWeltuhrCancel');
    var inputLabel = document.getElementById('weltuhrLabel');
    var inputTz = document.getElementById('weltuhrZeitzone');
    var dlist = document.getElementById('weltuhrZeitzoneList');
    if (dlist && ZEITZONEN) { ZEITZONEN.forEach(function(z) { var o = document.createElement('option'); o.value = z; dlist.appendChild(o); }); }
    function getOrte() { try { return JSON.parse(localStorage.getItem('weltuhr_orte') || '[]'); } catch(e) { return []; } }
    function setOrte(arr) { localStorage.setItem('weltuhr_orte', JSON.stringify(arr)); }
    function render() {
        list.innerHTML = '';
        getOrte().forEach(function(o, i) {
            var li = document.createElement('li');
            li.innerHTML = '<span class="ort">' + escapeHtml(o.label) + '</span><span class="zeit" data-tz="' + escapeHtml(o.timezone) + '">--:--</span><button type="button" data-index="' + i + '">Entfernen</button>';
            li.querySelector('button').addEventListener('click', function() {
                var arr = getOrte(); arr.splice(parseInt(this.dataset.index, 10), 1); setOrte(arr); render(); weltuhrTick();
            });
            list.appendChild(li);
        });
    }
    function tick() {
        list.querySelectorAll('.zeit[data-tz]').forEach(function(el) {
            try {
                el.textContent = new Date().toLocaleTimeString('de-DE', { timeZone: el.dataset.tz, hour: '2-digit', minute: '2-digit', second: '2-digit' });
            } catch(e) { el.textContent = '–'; }
        });
    }
    window.weltuhrTick = function() {
        if (weltuhrInterval) clearInterval(weltuhrInterval);
        tick();
        weltuhrInterval = setInterval(tick, 1000);
    };
    if (btnAdd) btnAdd.addEventListener('click', function() { addForm.style.display = addForm.style.display === 'none' ? 'flex' : 'none'; });
    if (btnCancel) btnCancel.addEventListener('click', function() { addForm.style.display = 'none'; });
    if (btnSave) btnSave.addEventListener('click', function() {
        var label = (inputLabel.value || '').trim();
        var tz = (inputTz.value || '').trim();
        if (!label || !tz) return;
        var arr = getOrte(); arr.push({ label: label, timezone: tz }); setOrte(arr);
        inputLabel.value = ''; inputTz.value = ''; addForm.style.display = 'none';
        render(); weltuhrTick();
    });
    render();
    if (document.getElementById('panelWeltuhr').classList.contains('active')) weltuhrTick();
}

var stoppuhrStartTime = 0, stoppuhrElapsed = 0, stoppuhrRunning = false, stoppuhrTimer = null;
function initStoppuhr() {
    var anzeige = document.getElementById('stoppuhrAnzeige');
    var btnStart = document.getElementById('stoppuhrStart');
    var btnStop = document.getElementById('stoppuhrStop');
    var btnReset = document.getElementById('stoppuhrReset');
    function update() {
        var ms = stoppuhrElapsed + (stoppuhrRunning ? Date.now() - stoppuhrStartTime : 0);
        var h = Math.floor(ms / 3600000), m = Math.floor((ms % 3600000) / 60000), s = Math.floor((ms % 60000) / 1000), z = Math.floor((ms % 1000) / 10);
        anzeige.textContent = (h < 10 ? '0' : '') + h + ':' + (m < 10 ? '0' : '') + m + ':' + (s < 10 ? '0' : '') + s + '.' + (z < 10 ? '0' : '') + z;
    }
    if (btnStart) btnStart.addEventListener('click', function() {
        if (!stoppuhrRunning) { stoppuhrRunning = true; stoppuhrStartTime = Date.now(); btnStart.textContent = 'Pause'; btnStop.disabled = false; stoppuhrTimer = setInterval(update, 50); }
        else { stoppuhrRunning = false; stoppuhrElapsed += Date.now() - stoppuhrStartTime; btnStart.textContent = 'Start'; clearInterval(stoppuhrTimer); }
    });
    if (btnStop) btnStop.addEventListener('click', function() {
        if (stoppuhrRunning) { stoppuhrRunning = false; stoppuhrElapsed += Date.now() - stoppuhrStartTime; btnStart.textContent = 'Start'; btnStop.disabled = true; clearInterval(stoppuhrTimer); }
    });
    if (btnReset) btnReset.addEventListener('click', function() {
        stoppuhrRunning = false; stoppuhrElapsed = 0; clearInterval(stoppuhrTimer); btnStart.textContent = 'Start'; btnStop.disabled = true; update();
    });
    if (btnStop) btnStop.disabled = true;
    update();
}

var timerInterval = null, timerRest = 0;
function initTimer() {
    var inpMin = document.getElementById('timerMin');
    var inpSek = document.getElementById('timerSek');
    var anzeige = document.getElementById('timerAnzeige');
    var btnStart = document.getElementById('timerStart');
    var btnStop = document.getElementById('timerStop');
    var setDiv = document.querySelector('.timer-set');
    function showSet(show) { if (setDiv) setDiv.style.display = show ? 'flex' : 'none'; if (anzeige) anzeige.style.display = show ? 'none' : 'block'; if (btnStop) btnStop.style.display = show ? 'none' : 'inline-flex'; }
    if (btnStart) btnStart.addEventListener('click', function() {
        if (timerInterval) return;
        var min = parseInt(inpMin.value, 10) || 0, sek = parseInt(inpSek.value, 10) || 0;
        timerRest = min * 60 + sek;
        if (timerRest <= 0) return;
        showSet(false);
        timerInterval = setInterval(function() {
            timerRest--;
            if (anzeige) anzeige.textContent = (Math.floor(timerRest / 60) < 10 ? '0' : '') + Math.floor(timerRest / 60) + ':' + (timerRest % 60 < 10 ? '0' : '') + (timerRest % 60);
            if (timerRest <= 0) { clearInterval(timerInterval); timerInterval = null; showSet(true); alert('Timer abgelaufen!'); }
        }, 1000);
    });
    if (btnStop) btnStop.addEventListener('click', function() {
        if (timerInterval) { clearInterval(timerInterval); timerInterval = null; showSet(true); }
    });
    showSet(true);
}

function loadWetterFromStorage() {
    var plz = (localStorage.getItem('wetter_plz') || '').trim();
    if (plz) document.getElementById('wetterPlz').value = plz;
}
function initWetter() {
    var inp = document.getElementById('wetterPlz');
    var btn = document.getElementById('wetterAktualisieren');
    var out = document.getElementById('wetterErgebnis');
    if (btn) btn.addEventListener('click', function() {
        var plz = (inp.value || '').trim();
        if (!plz) { out.innerHTML = '<p class="platzhalter-hint">Bitte PLZ eingeben.</p>'; return; }
        localStorage.setItem('wetter_plz', plz);
        out.innerHTML = '<p>Lade…</p>';
        fetch('api_wetter.php?plz=' + encodeURIComponent(plz)).then(function(r) { return r.json(); }).then(function(data) {
            if (!data.ok) { out.innerHTML = '<p class="settings-msg error">' + escapeHtml(data.error || 'Fehler') + '</p>'; return; }
            var h = '<div class="wetter-aktuell">' + (data.current ? (data.current.temp + ' °C, ' + (data.current.beschreibung || '')) : '–') + '</div>';
            if (data.daily && data.daily.length) {
                h += '<div class="wetter-vorhersage">';
                data.daily.slice(0, 5).forEach(function(d) {
                    h += '<div class="tag">' + escapeHtml(d.datum) + ': ' + (d.temp_max != null ? d.temp_max + '°' : '') + (d.temp_min != null ? ' / ' + d.temp_min + '°' : '') + (d.beschreibung ? ' – ' + d.beschreibung : '') + '</div>';
                });
                h += '</div>';
            }
            out.innerHTML = h;
        }).catch(function() { out.innerHTML = '<p class="settings-msg error">Netzwerkfehler.</p>'; });
    });
}

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function () {
        navigator.serviceWorker.register('/sw.js').catch(function () {});
    });
}

window.neuWecker = neuWecker;
window.openSettings = openSettings;
window.toggleTheme = toggleTheme;
window.editWecker = editWecker;
window.closeEdit = closeEdit;
window.toggleWecker = toggleWecker;
window.deleteWecker = deleteWecker;
window.saveSettings = saveSettings;
window.closeSettings = closeSettings;
</script>

</body>
</html>
