const { useState, useEffect, useCallback, useRef } = React;
const { createRoot } = ReactDOM;
const {
  Bus, Clock, MapPin, LogOut, Plus, Check, Unlock,
  ArrowLeft, ChevronUp, ChevronDown, Pencil, Trash2, Save, StickyNote,
  Building2, Phone, RefreshCw, CalendarDays, List, Sun, Moon, Clapperboard,
} = Icons;

const API = "storage.php";
const ITEMS_POLL_MS = 6000;   // "alle paar Sekunden" – Ablauf eines offenen Stops
const STOPS_POLL_MS = 15000;  // Liste aller Stops (neue Termine etc.)

// ---------- API-Helfer ----------
function headers(withEdit) {
  const h = { "Content-Type": "application/json", "X-View-Pin": window.pinStorage.getView() };
  if (withEdit) h["X-Edit-Pin"] = window.pinStorage.getEdit();
  return h;
}

async function apiGet(action, params = {}) {
  const qs = new URLSearchParams({ action, ...params }).toString();
  const r = await fetch(`${API}?${qs}`, { headers: headers(false) });
  if (!r.ok) throw new Error((await r.json().catch(() => ({}))).error || "Fehler beim Laden");
  return r.json();
}

async function apiPost(body, withEdit = false) {
  const r = await fetch(API, { method: "POST", headers: headers(withEdit), body: JSON.stringify(body) });
  if (!r.ok) throw new Error((await r.json().catch(() => ({}))).error || "Fehler beim Speichern");
  return r.json();
}

async function login(pin) {
  const r = await fetch(API, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ action: "login", pin }) });
  return r.json();
}

// ---------- Datum-Helfer ----------
const WEEKDAYS = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"];
const MONTHS = ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"];

function parseDate(dateStr) {
  const [y, m, d] = dateStr.split("-").map(Number);
  return new Date(y, m - 1, d);
}
function dateBadge(dateStr) {
  const d = parseDate(dateStr);
  return { day: String(d.getDate()).padStart(2, "0"), month: MONTHS[d.getMonth()] };
}
function headerDate(dateStr) {
  const d = parseDate(dateStr);
  return `${WEEKDAYS[d.getDay()]}, ${String(d.getDate()).padStart(2, "0")}. ${MONTHS[d.getMonth()]} ${d.getFullYear()}`;
}
function todayISO() {
  const d = new Date();
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
}

// Einträge ohne Startzeit werden ans Ende sortiert; bei gleicher Zeit bleibt
// die bisherige Reihenfolge erhalten (stabile Sortierung) – so wirkt sich
// ein manuelles Verschieben per Pfeil bei Zeitgleichheit weiterhin aus.
function sortByTime(items) {
  return [...items].sort((a, b) => {
    const at = a.startTime || "99:99";
    const bt = b.startTime || "99:99";
    return at.localeCompare(bt);
  });
}

// ---------- URL-Deeplink (?date=YYYY-MM-DD) ----------
function getUrlDate() {
  return new URLSearchParams(window.location.search).get("date") || "";
}
function setUrlDate(date) {
  const url = new URL(window.location.href);
  if (date) url.searchParams.set("date", date);
  else url.searchParams.delete("date");
  window.history.replaceState({}, "", url.toString());
}

// ---------- Theme ----------
function getStoredTheme() { return localStorage.getItem("hope-ablauf-theme") || "dark"; }
function setStoredTheme(t) { localStorage.setItem("hope-ablauf-theme", t); }

// ---------- PIN-Screen (einziger Ort, an dem der Bearbeitungsmodus vergeben wird) ----------
function PinScreen({ onSuccess }) {
  const [pin, setPin] = useState("");
  const [error, setError] = useState("");
  const [busy, setBusy] = useState(false);

  const submit = async () => {
    if (!pin) return;
    setBusy(true);
    setError("");
    try {
      const res = await login(pin);
      if (res.view) {
        window.pinStorage.setView(pin);
        if (res.edit) window.pinStorage.setEdit(pin);
        onSuccess(!!res.edit);
      } else {
        setError("Falscher PIN.");
      }
    } catch {
      setError("Verbindung fehlgeschlagen.");
    } finally {
      setBusy(false);
    }
  };

  return (
    <div className="pin-screen">
      <div className="pin-mark"><Bus size={30} /></div>
      <h1 className="pin-title">hope Ablauf</h1>
      <p className="pin-sub">Tagesablauf der Tournee 2027 — bitte PIN eingeben</p>
      <input
        className="pin-input"
        type="password"
        inputMode="numeric"
        placeholder="••••"
        value={pin}
        onChange={(e) => setPin(e.target.value)}
        onKeyDown={(e) => e.key === "Enter" && submit()}
        autoFocus
      />
      {error && <p className="pin-error">{error}</p>}
      <button className="pin-submit" onClick={submit} disabled={busy}>{busy ? "Prüfe…" : "Los geht's"}</button>
      <p className="pin-cancel" style={{ marginTop: 14 }}>Der Bearbeiten-PIN schaltet direkt beim Login den Bearbeitungsmodus frei — danach nur noch über Abmelden &amp; neu einloggen wechselbar.</p>
    </div>
  );
}

// ---------- Topbar ----------
function Topbar({ title, sub, onBack, isEditor, theme, onToggleTheme, onLogout }) {
  return (
    <div className="topbar">
      <div className="brand">
        {onBack ? (
          <button className="icon-btn" onClick={onBack}><ArrowLeft size={18} /></button>
        ) : (
          <div className="brand-mark"><Bus size={17} /></div>
        )}
        <div className="brand-text">
          <span className="brand-name">{title}</span>
          {sub && <span className="brand-sub">{sub}</span>}
        </div>
      </div>
      <div className="topbar-actions">
        {isEditor && <span className="editor-badge">Bearbeiten</span>}
        <button className="icon-btn" onClick={onToggleTheme} title="Hell/Dunkel">
          {theme === "dark" ? <Sun size={16} /> : <Moon size={16} />}
        </button>
        <button className="icon-btn" onClick={onLogout} title="Abmelden"><LogOut size={16} /></button>
      </div>
    </div>
  );
}

// ---------- Stop-Liste ----------
function StopList({ stops, onSelect }) {
  if (!stops.length) return <p className="empty-hint">Noch keine Tourstopps vorhanden.</p>;
  return (
    <div className="stop-list">
      {stops.map((s) => {
        const b = dateBadge(s.date);
        const isToday = s.date === todayISO();
        return (
          <button key={s.id} className="stop-card" onClick={() => onSelect(s.id)}>
            <div className="stop-date-badge" style={isToday ? { borderColor: "var(--accent)" } : undefined}>
              <div className="d">{b.day}</div><div className="m">{b.month}</div>
            </div>
            <div className="stop-card-body">
              <div className="stop-card-city">{s.city}</div>
              <div className="stop-card-arena">{s.arena || (s.venue && s.venue.name) || ""}</div>
            </div>
            <ChevronUp className="chev" size={18} style={{ transform: "rotate(90deg)" }} />
          </button>
        );
      })}
    </div>
  );
}

// ---------- Schedule-Item-Sheet ----------
function ItemSheet({ initial, onClose, onSave }) {
  const [title, setTitle] = useState(initial?.title || "");
  const [startTime, setStartTime] = useState(initial?.startTime || "");
  const [endTime, setEndTime] = useState(initial?.endTime || "");
  const [iconType, setIconType] = useState(initial?.iconType || "clock");
  const [note, setNote] = useState(initial?.note || "");
  const [tags, setTags] = useState(initial?.tags || "");

  const save = () => {
    if (!title.trim()) return;
    onSave({ ...initial, title: title.trim(), startTime, endTime, iconType, note, tags });
    onClose();
  };

  return (
    <div className="sheet-backdrop" onClick={onClose}>
      <div className="sheet" onClick={(e) => e.stopPropagation()}>
        <h3 className="sheet-title">{initial?.id ? "Eintrag bearbeiten" : "Neuer Eintrag"}</h3>
        <div className="field">
          <label>Titel</label>
          <input type="text" value={title} onChange={(e) => setTitle(e.target.value)} autoFocus />
        </div>
        <div className="field-row">
          <div className="field">
            <label>Startzeit</label>
            <input type="time" value={startTime} onChange={(e) => setStartTime(e.target.value)} />
          </div>
          <div className="field">
            <label>Endzeit (optional)</label>
            <input type="time" value={endTime} onChange={(e) => setEndTime(e.target.value)} />
          </div>
        </div>
        <div className="field">
          <label>Art</label>
          <div className="icon-toggle">
            <button className={"icon-toggle-btn" + (iconType === "clock" ? " is-active" : "")} onClick={() => setIconType("clock")}>
              <Clock size={15} /> Termin
            </button>
            <button className={"icon-toggle-btn" + (iconType === "bus" ? " is-active" : "")} onClick={() => setIconType("bus")}>
              <Bus size={15} /> Bus / Shuttle
            </button>
          </div>
        </div>
        <div className="field">
          <label>Notiz (optional)</label>
          <textarea value={note} onChange={(e) => setNote(e.target.value)} />
        </div>
        <div className="field">
          <label>Namen / Gruppe (optional)</label>
          <input type="text" placeholder="z. B. Kai, Marieke oder MOTUS (6)" value={tags} onChange={(e) => setTags(e.target.value)} />
        </div>
        <div className="sheet-actions">
          <button className="btn ghost" onClick={onClose}>Abbrechen</button>
          <button className="btn primary" onClick={save}><Check size={15} /> Speichern</button>
        </div>
      </div>
    </div>
  );
}

// ---------- Notiz-Sheet ----------
function NotesSheet({ initial, onClose, onSave }) {
  const [text, setText] = useState(initial || "");
  return (
    <div className="sheet-backdrop" onClick={onClose}>
      <div className="sheet" onClick={(e) => e.stopPropagation()}>
        <h3 className="sheet-title">Day Notes</h3>
        <div className="field">
          <textarea style={{ minHeight: 120 }} value={text} onChange={(e) => setText(e.target.value)} autoFocus />
        </div>
        <div className="sheet-actions">
          <button className="btn ghost" onClick={onClose}>Abbrechen</button>
          <button className="btn primary" onClick={() => { onSave(text); onClose(); }}><Save size={15} /> Speichern</button>
        </div>
      </div>
    </div>
  );
}

// ---------- Venue/Hotel-Sheet ----------
function PlaceSheet({ kind, initial, onClose, onSave }) {
  const [name, setName] = useState(initial?.name || "");
  const [street, setStreet] = useState(initial?.street || "");
  const [zip, setZip] = useState(initial?.zip || "");
  const [city, setCity] = useState(initial?.city || "");
  const [phone, setPhone] = useState(initial?.phone || "");
  const [web, setWeb] = useState(initial?.web || "");

  const save = () => {
    const data = { name, street, zip, city, phone };
    if (kind === "venue") data.web = web;
    onSave(data);
    onClose();
  };

  return (
    <div className="sheet-backdrop" onClick={onClose}>
      <div className="sheet" onClick={(e) => e.stopPropagation()}>
        <h3 className="sheet-title">{kind === "venue" ? "Venue bearbeiten" : "Hotel bearbeiten"}</h3>
        <div className="field"><label>Name</label><input type="text" value={name} onChange={(e) => setName(e.target.value)} autoFocus /></div>
        <div className="field"><label>Straße</label><input type="text" value={street} onChange={(e) => setStreet(e.target.value)} /></div>
        <div className="field-row">
          <div className="field"><label>PLZ</label><input type="text" value={zip} onChange={(e) => setZip(e.target.value)} /></div>
          <div className="field"><label>Stadt</label><input type="text" value={city} onChange={(e) => setCity(e.target.value)} /></div>
        </div>
        <div className="field"><label>Telefon</label><input type="text" value={phone} onChange={(e) => setPhone(e.target.value)} /></div>
        {kind === "venue" && <div className="field"><label>Website</label><input type="text" value={web} onChange={(e) => setWeb(e.target.value)} /></div>}
        <div className="sheet-actions">
          <button className="btn ghost" onClick={onClose}>Abbrechen</button>
          <button className="btn primary" onClick={save}><Save size={15} /> Speichern</button>
        </div>
      </div>
    </div>
  );
}

// ---------- Stop-Detail (Inhalt, ohne eigene Topbar) ----------
function StopDetail({ stop, items: rawItems, isEditor, onSaveItems, onSaveStop }) {
  const [sheet, setSheet] = useState(null);
  const items = sortByTime(rawItems);

  const move = (idx, dir) => {
    const next = [...items];
    const j = idx + dir;
    if (j < 0 || j >= next.length) return;
    [next[idx], next[j]] = [next[j], next[idx]];
    onSaveItems(next);
  };

  const removeItem = (idx) => {
    if (!confirm("Diesen Eintrag wirklich löschen?")) return;
    onSaveItems(items.filter((_, i) => i !== idx));
  };

  const saveItem = (item) => {
    let next;
    if (item.id) next = items.map((it) => (it.id === item.id ? item : it));
    else next = [...items, item];
    onSaveItems(sortByTime(next));
  };

  const formatTime = (it) => (!it.startTime ? "" : it.endTime ? `${it.startTime} – ${it.endTime}` : it.startTime);

  return (
    <>
      <div className="stop-header">
        <h2 className="stop-header-title">{(stop.venue && stop.venue.name) || stop.arena || stop.city}</h2>
        <p className="stop-header-sub">{headerDate(stop.date)}</p>
      </div>

      <div className="section">
        <div className="section-card">
          <div className="section-head">
            <span><StickyNote size={16} style={{ verticalAlign: "-3px", marginRight: 6 }} />Day Notes</span>
            {isEditor && <button className="icon-btn" onClick={() => setSheet({ type: "notes" })}><Pencil size={14} /></button>}
          </div>
          <div className="day-notes-body">{stop.dayNotes || (isEditor ? "Noch keine Notiz — antippen zum Hinzufügen." : "Keine Notizen für diesen Tag.")}</div>
        </div>
      </div>

      <div className="section">
        <div className="section-card">
          <div className="section-head">
            <span>Ablauf</span>
            {isEditor && (
              <div className="section-head-actions">
                <button className="icon-btn" onClick={() => setSheet({ type: "item" })}><Plus size={16} /></button>
              </div>
            )}
          </div>
          <div className="sched-list">
            {items.length === 0 && <div className="loading-hint">Noch keine Einträge.</div>}
            {items.map((it, idx) => (
              <div className="sched-row" key={it.id ?? idx}>
                <div className={"sched-icon" + (it.iconType === "bus" ? " is-bus" : "")}>
                  {it.iconType === "bus" ? <Bus size={15} /> : <Clock size={15} />}
                </div>
                <div className="sched-body">
                  {formatTime(it) && <div className="sched-time">{formatTime(it)}</div>}
                  <div className="sched-title">{it.title}</div>
                  {it.note && <div className="sched-note">{it.note}</div>}
                  {it.tags && <div className="sched-tags">{it.tags}</div>}
                  {isEditor && (
                    <div className="sched-edit-row2">
                      <button className="icon-btn" onClick={() => setSheet({ type: "item", data: it })}><Pencil size={13} /></button>
                      <button className="icon-btn" onClick={() => removeItem(idx)}><Trash2 size={13} /></button>
                    </div>
                  )}
                </div>
                {isEditor && (
                  <div className="sched-edit-controls">
                    <button className="icon-btn" onClick={() => move(idx, -1)} disabled={idx === 0}><ChevronUp size={14} /></button>
                    <button className="icon-btn" onClick={() => move(idx, 1)} disabled={idx === items.length - 1}><ChevronDown size={14} /></button>
                  </div>
                )}
              </div>
            ))}
          </div>
        </div>
      </div>

      <div className="section">
        <div className="section-card">
          <div className="section-head">
            <span><Building2 size={16} style={{ verticalAlign: "-3px", marginRight: 6 }} />Venue</span>
            {isEditor && <button className="icon-btn" onClick={() => setSheet({ type: "venue" })}><Pencil size={14} /></button>}
          </div>
          {stop.venue && stop.venue.name ? (
            <>
              <div className="info-row">
                <MapPin size={16} />
                <div>
                  <div className="info-row-title">{stop.venue.name}</div>
                  <div className="info-row-sub">{stop.venue.street}, {stop.venue.zip} {stop.venue.city}</div>
                </div>
              </div>
              {stop.venue.phone && <div className="info-row"><Phone size={16} /><div className="info-row-sub">{stop.venue.phone}</div></div>}
              {stop.venue.web && <div className="info-row"><a href={stop.venue.web} target="_blank" rel="noreferrer">{stop.venue.web}</a></div>}
            </>
          ) : <div className="day-notes-body">Keine Venue-Daten hinterlegt.</div>}
        </div>
      </div>

      <div className="section" style={{ paddingBottom: 20 }}>
        <div className="section-card">
          <div className="section-head">
            <span><Building2 size={16} style={{ verticalAlign: "-3px", marginRight: 6 }} />Hotel</span>
            {isEditor && <button className="icon-btn" onClick={() => setSheet({ type: "hotel" })}><Pencil size={14} /></button>}
          </div>
          {stop.hotel && stop.hotel.name ? (
            <>
              <div className="info-row">
                <MapPin size={16} />
                <div>
                  <div className="info-row-title">{stop.hotel.name}</div>
                  <div className="info-row-sub">{stop.hotel.street}, {stop.hotel.zip} {stop.hotel.city}</div>
                </div>
              </div>
              {stop.hotel.phone && <div className="info-row"><Phone size={16} /><div className="info-row-sub">{stop.hotel.phone}</div></div>}
            </>
          ) : <div className="day-notes-body">Keine Hotel-Daten hinterlegt.</div>}
        </div>
      </div>

      {sheet?.type === "item" && <ItemSheet initial={sheet.data} onClose={() => setSheet(null)} onSave={saveItem} />}
      {sheet?.type === "notes" && <NotesSheet initial={stop.dayNotes} onClose={() => setSheet(null)} onSave={(text) => onSaveStop({ dayNotes: text })} />}
      {sheet?.type === "venue" && <PlaceSheet kind="venue" initial={stop.venue} onClose={() => setSheet(null)} onSave={(venue) => onSaveStop({ venue })} />}
      {sheet?.type === "hotel" && <PlaceSheet kind="hotel" initial={stop.hotel} onClose={() => setSheet(null)} onSave={(hotel) => onSaveStop({ hotel })} />}
    </>
  );
}

// ---------- Regieplan (statisch, keine Datenbank – ändert sich nicht) ----------
const SHOW_PROGRAM = {
  title: "Programmablauf VIVA",
  halves: [
    {
      label: "1. Hälfte",
      items: [
        { text: "Trailer" },
        { text: "President" },
        { divider: true },
        { text: "Intro Movie & Live Cam Intro", artist: "Rosemie" },
        { text: "Opening", artist: "All Artists" },
        { text: "Local Show Group" },
        { text: "Slack Wire", artist: "Alexey Glavatskyi" },
        { text: "Bon Bon Step", artist: "Rosemie" },
        { text: "BMX", artist: "Tim Höfel" },
        { text: "Beams", artist: "Showteam & Turnerinnen" },
        { text: "Song 1", artist: "Rosemie" },
        { text: "Swinging Trapez", artist: "Avital & Jochen" },
        { text: "Hand to Hand", artist: "Duo in Motion" },
        { text: "Parallel Bars", artist: "Lukas Dauser" },
        { text: "Umarmen", artist: "Rosemie" },
        { text: "Parcours Pole", artist: "Chinese National Acrobatic Troupe" },
        { text: "Outro First Half" },
      ],
    },
    {
      label: "2. Hälfte",
      items: [
        { text: "Intro Second Half" },
        { text: "X-Boards", artist: "Motus" },
        { text: "Rap", artist: "Rosemie" },
        { text: "Quickchange", artist: "Duo in Motion" },
        { text: "Pommel Horse & Breakdance", artist: "Andy Toba, Michi & Showteam" },
        { text: "Aerial Pole", artist: "Duo Soulmates" },
        { text: "Jump Rope", artist: "Haribow" },
        { text: "Cyr Wheel", artist: "Alexey Glavatskyi" },
        { text: "Alphorn", artist: "Rosemie" },
        { text: "Rhythmic Gymnastics", artist: "Anastasiia Tsibulska" },
        { text: "Aerial Rope", artist: "Two on the Rope" },
        { text: "High Bar", artist: "Lukas Dauser, Andy Toba & Showteam" },
        { text: "Song 1", artist: "Rosemie" },
        { text: "Bicycles", artist: "Chinese National Acrobatic Troupe" },
        { text: "Grand Finale", artist: "All Artists" },
        { text: "Encore", artist: "All Artists" },
        { text: "Trailer 2027 & After Movie" },
      ],
    },
  ],
};

function RegieplanView() {
  let counter = 0;
  return (
    <>
      <div className="stop-header">
        <h2 className="stop-header-title">{SHOW_PROGRAM.title}</h2>
        <p className="stop-header-sub">Regieplan / Ablaufplan der Show</p>
      </div>
      {SHOW_PROGRAM.halves.map((half) => (
        <div className="section" key={half.label}>
          <div className="regie-half-label">{half.label}</div>
          <div className="section-card">
            <div className="regie-list">
              {half.items.map((it, idx) =>
                it.divider ? (
                  <div className="regie-divider" key={idx}>• • •</div>
                ) : (
                  <div className="regie-row" key={idx}>
                    <div className="regie-num">{String(++counter).padStart(2, "0")}</div>
                    <div className="regie-body">
                      <div className="regie-title">{it.text}</div>
                      {it.artist && <div className="regie-artist">{it.artist}</div>}
                    </div>
                  </div>
                )
              )}
            </div>
          </div>
        </div>
      ))}
      <p className="hint" style={{ paddingBottom: 10 }}>Dieser Ablauf ist fest hinterlegt und ändert sich nicht automatisch mit den Tourstopps.</p>
    </>
  );
}

// ---------- Bottom-Nav ----------
function BottomNav({ tab, onChange }) {
  return (
    <div className="bottom-nav">
      <button className={"bottom-nav-btn" + (tab === "today" ? " is-active" : "")} onClick={() => onChange("today")}>
        <CalendarDays size={20} />
        Tagesübersicht
      </button>
      <button className={"bottom-nav-btn" + (tab === "tourplan" ? " is-active" : "")} onClick={() => onChange("tourplan")}>
        <List size={20} />
        Tourplan
      </button>
      <button className={"bottom-nav-btn" + (tab === "regieplan" ? " is-active" : "")} onClick={() => onChange("regieplan")}>
        <Clapperboard size={20} />
        Regieplan
      </button>
    </div>
  );
}

// ---------- App ----------
function App() {
  const [loggedIn, setLoggedIn] = useState(!!window.pinStorage.getView());
  const [isEditor, setIsEditor] = useState(!!window.pinStorage.getEdit());
  const [theme, setTheme] = useState(getStoredTheme());
  const [tab, setTab] = useState("today");
  const [stops, setStops] = useState([]);
  const [tourplanStopId, setTourplanStopId] = useState(null);
  const [itemsByStop, setItemsByStop] = useState({});
  const [loading, setLoading] = useState(false);

  const loadStops = useCallback(async () => {
    try {
      const data = await apiGet("stops");
      setStops(data);
    } catch (e) {
      if (String(e.message).includes("PIN")) { window.pinStorage.clearAll(); setLoggedIn(false); }
    }
  }, []);

  const loadItems = useCallback(async (stopId) => {
    if (!stopId) return;
    try {
      const data = await apiGet("schedule", { stopId });
      setItemsByStop((prev) => ({ ...prev, [stopId]: data }));
    } catch { /* stiller Fehlschlag bei Zwischen-Polls */ }
  }, []);

  // "overrideDate" ersetzt für die Tagesübersicht das echte Kalenderdatum,
  // wenn ein Deeplink (?date=...) verwendet wurde.
  const [overrideDate, setOverrideDate] = useState(() => getUrlDate() || null);

  const effectiveTodayDate = overrideDate || todayISO();
  const todayStop = stops.find((s) => s.date === effectiveTodayDate);
  const tourplanStop = stops.find((s) => s.id === tourplanStopId);
  const displayedStop = tab === "today" ? todayStop : tourplanStop;

  // Initiales Laden nach Login
  useEffect(() => {
    if (!loggedIn) return;
    setLoading(true);
    loadStops().finally(() => setLoading(false));
  }, [loggedIn, loadStops]);

  // Deeplink beim ersten Laden sicherstellen: Tagesübersicht-Tab aktivieren
  useEffect(() => {
    if (overrideDate) setTab("today");
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  // Stops regelmäßig aktualisieren (neue Tourstopps, geänderte Adressen etc.)
  useEffect(() => {
    if (!loggedIn) return;
    const t = setInterval(loadStops, STOPS_POLL_MS);
    return () => clearInterval(t);
  }, [loggedIn, loadStops]);

  // Ablauf des aktuell angezeigten Stops regelmäßig aktualisieren
  useEffect(() => {
    if (!displayedStop) return;
    loadItems(displayedStop.id);
    const t = setInterval(() => loadItems(displayedStop.id), ITEMS_POLL_MS);
    return () => clearInterval(t);
  }, [displayedStop?.id, loadItems]);

  // Beim Zurückkehren in den Tab sofort aktualisieren
  useEffect(() => {
    const onVis = () => {
      if (document.visibilityState === "visible") {
        loadStops();
        if (displayedStop) loadItems(displayedStop.id);
      }
    };
    document.addEventListener("visibilitychange", onVis);
    return () => document.removeEventListener("visibilitychange", onVis);
  }, [loadStops, loadItems, displayedStop]);

  // Theme anwenden
  useEffect(() => { setStoredTheme(theme); }, [theme]);

  const items = displayedStop ? (itemsByStop[displayedStop.id] || []) : [];

  const saveItems = async (next) => {
    if (!displayedStop) return;
    setItemsByStop((prev) => ({ ...prev, [displayedStop.id]: next }));
    await apiPost({ action: "save_schedule", stopId: displayedStop.id, items: next }, true);
    loadItems(displayedStop.id);
  };

  const saveStopFields = async (patch) => {
    if (!displayedStop) return;
    const merged = { ...displayedStop, ...patch };
    setStops((prev) => prev.map((s) => (s.id === displayedStop.id ? merged : s)));
    await apiPost({ action: "save_stop", stopId: displayedStop.id, dayNotes: merged.dayNotes, venue: merged.venue, hotel: merged.hotel }, true);
    loadStops();
  };

  const openTourplanStop = (id) => setTourplanStopId(id);
  const closeTourplanStop = () => setTourplanStopId(null);

  const resetToRealToday = () => {
    setOverrideDate(null);
    setUrlDate("");
  };

  const logout = () => {
    window.pinStorage.clearAll();
    setLoggedIn(false); setIsEditor(false); setTourplanStopId(null); setTab("today");
    setOverrideDate(null);
    setUrlDate("");
  };

  if (!loggedIn) {
    return (
      <div className={"app theme-" + theme}>
        <PinScreen onSuccess={(edit) => { setLoggedIn(true); setIsEditor(edit); }} />
      </div>
    );
  }

  let title, sub, onBack;
  if (tab === "today") {
    title = "Tagesübersicht";
    if (todayStop) {
      sub = overrideDate ? `${todayStop.city} · verlinktes Datum` : todayStop.city;
    } else {
      sub = overrideDate ? "Kein Tourstopp an diesem Datum" : "Heute kein Tourstopp";
    }
  } else if (tab === "regieplan") {
    title = "Regieplan";
    sub = "Programmablauf";
  } else if (tourplanStop) {
    title = tourplanStop.city;
    sub = null;
    onBack = closeTourplanStop;
  } else {
    title = "Tourplan";
    sub = "Alle Stopps";
  }

  return (
    <div className={"app theme-" + theme}>
      <Topbar
        title={title}
        sub={sub}
        onBack={onBack}
        isEditor={isEditor}
        theme={theme}
        onToggleTheme={() => setTheme((t) => (t === "dark" ? "light" : "dark"))}
        onLogout={logout}
      />

      {tab === "today" && (
        <>
          {overrideDate && (
            <div className="section" style={{ paddingTop: 10 }}>
              <button className="btn ghost" style={{ width: "100%" }} onClick={resetToRealToday}>
                Zum echten heutigen Datum zurück
              </button>
            </div>
          )}
          {todayStop ? (
            <StopDetail stop={todayStop} items={itemsByStop[todayStop.id] || []} isEditor={isEditor} onSaveItems={saveItems} onSaveStop={saveStopFields} />
          ) : (
            <p className="empty-hint">
              {overrideDate ? "Für dieses Datum ist kein Tourstopp hinterlegt." : "Für heute ist kein Tourstopp hinterlegt."}
              <br />Unter „Tourplan" siehst du alle kommenden Termine.
            </p>
          )}
        </>
      )}

      {tab === "tourplan" && (
        tourplanStop ? (
          <StopDetail stop={tourplanStop} items={itemsByStop[tourplanStop.id] || []} isEditor={isEditor} onSaveItems={saveItems} onSaveStop={saveStopFields} />
        ) : loading ? (
          <div className="loading-hint">Lade Tourstopps…</div>
        ) : (
          <StopList stops={stops} onSelect={openTourplanStop} />
        )
      )}

      {tab === "regieplan" && <RegieplanView />}

      <BottomNav tab={tab} onChange={(t) => { setTab(t); closeTourplanStop(); }} />
    </div>
  );
}

const __root = createRoot(document.getElementById("root"));
__root.render(<App />);
