/* ============================================================
   BAN YARO — Giftköder-Alarm (Sprint 2)
   Seiten-Modul: Leaflet-Karte + Meldungsliste + Melden-Formular.
   ============================================================ */

window.Page_poison = (() => {

  // ----------------------------------------------------------
  // MODUL-STATE
  // ----------------------------------------------------------
  let _container     = null;
  let _appState      = null;
  let _map           = null;
  let _markers       = [];
  let _userMarker    = null;
  let _reports       = [];
  let _userPos       = null;

  const TYPEN = {
    unbekannt:  { label: 'Unbekannt',         icon: 'question', color: '#e67e22' },
    koeoder:    { label: 'Köder',              icon: 'fish',     color: '#e74c3c' },
    vergiftet:  { label: 'Vergiftetes Tier',   icon: 'skull',    color: '#8e44ad' },
    chemikalie: { label: 'Chemikalie',         icon: 'flask',    color: '#c0392b' },
    andere:     { label: 'Andere Gefahr',      icon: 'warning',  color: '#d35400' },
  };

  // ----------------------------------------------------------
  // INIT
  // ----------------------------------------------------------
  async function init(container, appState) {
    _container = container;
    _appState  = appState;
    await _render();
  }

  // ----------------------------------------------------------
  // REFRESH — Navigation zur bereits geladenen Seite
  // ----------------------------------------------------------
  async function refresh() {
    if (_userPos) await _loadReports();
  }

  // ----------------------------------------------------------
  // OPEN NEW — vom + Button
  // ----------------------------------------------------------
  function openNew() {
    _showReportForm();
  }

  // ----------------------------------------------------------
  // RENDER — Grundstruktur aufbauen
  // ----------------------------------------------------------
  async function _render() {
    _container.innerHTML = `
      <div style="display:flex;gap:var(--space-2);margin-bottom:var(--space-3);flex-wrap:wrap">
        <button class="btn btn-secondary" id="poison-btn-locate">${UI.icon('map-pin')} Mein Standort</button>
        <button class="btn btn-danger"    id="poison-btn-report">${UI.icon('warning-octagon')} Giftköder melden</button>
      </div>

      <div id="poison-map"
           style="height:280px;border-radius:var(--radius-md);overflow:hidden;
                  background:var(--c-surface-2)">
      </div>
      <div style="font-size:10px;color:var(--c-text-secondary);
                  text-align:right;margin-bottom:var(--space-4);
                  padding:2px var(--space-2) 0">
        © OpenStreetMap-Mitwirkende
      </div>

      <div style="display:flex;gap:var(--space-2);flex-wrap:wrap;margin-bottom:var(--space-3)">
        <a href="tel:110" class="btn btn-secondary" style="flex:1;text-align:center;text-decoration:none">
          ${UI.icon('phone')} <strong>110</strong> Polizei
        </a>
        <button class="btn btn-secondary" id="poison-btn-erstehilfe" style="flex:1">
          ${UI.icon('first-aid')} Erste Hilfe & Tiergift
        </button>
      </div>

      <p id="poison-info"
         style="font-size:var(--text-sm);color:var(--c-text-secondary);
                margin-bottom:var(--space-3)">
        Standort wird ermittelt…
      </p>

      <div id="poison-list"></div>
    `;

    document.getElementById('poison-btn-locate')
      ?.addEventListener('click', _locateUser);
    document.getElementById('poison-btn-report')
      ?.addEventListener('click', _showReportForm);
    document.getElementById('poison-btn-erstehilfe')
      ?.addEventListener('click', () => App.navigate('erste-hilfe', true, { tab: 'lebensgefahr' }));

    await UI.loadLeaflet();
    _initMap();
    // Leaflet muss nach CSS-Load die Container-Größe neu berechnen
    setTimeout(() => _map?.invalidateSize(), 100);
    await _locateAndLoad();
  }

  // ----------------------------------------------------------
  // KARTE INITIALISIEREN
  // ----------------------------------------------------------
  function _initMap() {
    const mapEl = document.getElementById('poison-map');
    if (!mapEl || !window.L || _map) return;

    _map = L.map('poison-map', { zoomControl: true, attributionControl: false })
            .setView([51.1657, 10.4515], 6); // Deutschland-Mitte

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      maxZoom: 19,
    }).addTo(_map);

  }

  // ----------------------------------------------------------
  // STANDORT ERMITTELN + LADEN
  // ----------------------------------------------------------
  async function _locateAndLoad() {
    try {
      _userPos = await API.getLocation({ timeout: 8000 });
      _showUserOnMap();
    } catch {
      _userPos = null;
    }
    await _loadReports();
  }

  async function _locateUser() {
    const btn = document.getElementById('poison-btn-locate');
    UI.setLoading(btn, true);
    try {
      _userPos = await API.getLocation({ timeout: 8000 });
      _showUserOnMap();
      if (_map) _map.setView([_userPos.lat, _userPos.lon], 13);
      await _loadReports();
    } catch {
      UI.toast.warning('Standort konnte nicht ermittelt werden.');
    }
    UI.setLoading(btn, false);
  }

  function _showUserOnMap() {
    if (!_map || !window.L || !_userPos) return;
    if (_userMarker) _map.removeLayer(_userMarker);
    _userMarker = L.circleMarker([_userPos.lat, _userPos.lon], {
      radius      : 9,
      fillColor   : '#3498db',
      color       : '#fff',
      weight      : 2,
      fillOpacity : 0.9,
    }).addTo(_map).bindPopup('<b>Du bist hier</b>');
    _map.setView([_userPos.lat, _userPos.lon], 13);
  }

  // ----------------------------------------------------------
  // MELDUNGEN LADEN
  // ----------------------------------------------------------
  async function _loadReports() {
    const infoEl = document.getElementById('poison-info');

    if (!_userPos) {
      _reports = [];
      _renderList();
      if (infoEl) infoEl.textContent =
        'Standort unbekannt — bitte Standort freigeben (📍 Mein Standort).';
      return;
    }

    try {
      _reports = await API.poison.listNearby(_userPos.lat, _userPos.lon, 10000);
      _renderMarkers();
      _renderList();
      _updateBadge(_reports.length);
      if (infoEl) {
        infoEl.textContent = _reports.length > 0
          ? `${_reports.length} aktive Meldung${_reports.length !== 1 ? 'en' : ''} im Umkreis von 10 km`
          : 'Keine aktiven Giftköder-Meldungen in deiner Nähe (10 km Radius).';
      }
    } catch {
      UI.toast.error('Meldungen konnten nicht geladen werden.');
    }
  }

  // ----------------------------------------------------------
  // KARTEN-MARKER
  // ----------------------------------------------------------
  function _renderMarkers() {
    if (!_map || !window.L) return;
    _markers.forEach(m => _map.removeLayer(m));
    _markers = [];

    _reports.forEach(r => {
      const typ  = TYPEN[r.typ] || TYPEN.unbekannt;

      const distStr = r.distanz_m < 1000
        ? `${r.distanz_m} m`
        : `${(r.distanz_m / 1000).toFixed(1)} km`;

      const marker = UI.leafletMarker({ lat: r.lat, lon: r.lon, color: typ.color, icon: UI.icon(typ.icon), size: 34 })
        .addTo(_map)
        .bindPopup(`
          <b>${UI.icon(typ.icon)} ${typ.label}</b><br>
          ${r.beschreibung ? UI.escape(r.beschreibung.slice(0, 80)) + '<br>' : ''}
          <small>📍 ${distStr} entfernt</small><br>
          <small>📅 ${_fmtDate(r.created_at)}</small>
          ${r.bestaetigt ? '<br><small><svg class="ph-icon" aria-hidden="true" style="color:var(--c-success)"><use href="/icons/phosphor.svg#check-circle"></use></svg> Bestätigt</small>' : ''}
        `);

      marker.on('click', () => _openDetail(r));
      _markers.push(marker);
    });
  }

  // ----------------------------------------------------------
  // LISTE
  // ----------------------------------------------------------
  function _renderList() {
    const listEl = document.getElementById('poison-list');
    if (!listEl) return;

    if (_reports.length === 0) {
      listEl.innerHTML = UI.emptyState({
        icon  : UI.icon('check-circle'),
        title : 'Alles sicher',
        text  : 'In deiner Nähe (10 km) gibt es aktuell keine Giftköder-Meldungen.',
        action: `<button class="btn btn-danger" id="poison-empty-report">⚠️ Trotzdem melden</button>`,
      });
      listEl.querySelector('#poison-empty-report')
        ?.addEventListener('click', _showReportForm);
      return;
    }

    listEl.innerHTML = _reports.map(r => _reportCard(r)).join('');
    listEl.querySelectorAll('[data-poison-id]').forEach(card => {
      card.addEventListener('click', () => {
        const r = _reports.find(x => x.id === parseInt(card.dataset.poisonId));
        if (r) _openDetail(r);
      });
    });
    listEl.querySelectorAll('.poison-note-btn').forEach(btn => {
      btn.addEventListener('click', e => {
        e.stopPropagation();
        const id = parseInt(btn.dataset.poisonNoteId);
        _openNoteModal('poison', id, 'Giftköder-Meldung ' + id, null);
      });
    });
  }

  function _reportCard(r) {
    const typ     = TYPEN[r.typ] || TYPEN.unbekannt;
    const distStr = r.distanz_m < 1000
      ? `${r.distanz_m} m`
      : `${(r.distanz_m / 1000).toFixed(1)} km`;

    return `
      <div class="card" data-poison-id="${r.id}"
           style="cursor:pointer;margin-bottom:var(--space-3);
                  border-left:4px solid ${typ.color}">
        <div style="display:flex;gap:var(--space-3);align-items:flex-start">
          <div style="width:40px;height:40px;flex-shrink:0;color:${typ.color};display:flex;align-items:center;justify-content:center">${UI.icon(typ.icon)}</div>
          <div style="flex:1;min-width:0">
            <div style="display:flex;align-items:center;gap:var(--space-2);
                        margin-bottom:var(--space-1);flex-wrap:wrap">
              <span class="badge"
                    style="background:${typ.color};color:#fff">${typ.label}</span>
              ${r.bestaetigt
                ? '<span class="badge badge-success"><svg class="ph-icon" aria-hidden="true" style="color:var(--c-success)"><use href="/icons/phosphor.svg#check-circle"></use></svg> Bestätigt</span>'
                : ''}
              <span style="margin-left:auto;color:var(--c-text-secondary);
                           font-size:var(--text-sm);white-space:nowrap">
                ${distStr}
              </span>
            </div>
            ${r.beschreibung
              ? `<p style="margin:0 0 var(--space-1);font-size:var(--text-sm);
                           color:var(--c-text)">
                   ${UI.escape(r.beschreibung.slice(0, 120))}${r.beschreibung.length > 120 ? '…' : ''}
                 </p>`
              : ''}
            <div style="font-size:var(--text-xs);color:var(--c-text-secondary)">
              Gemeldet ${_fmtDate(r.created_at)} ·
              läuft ab ${_fmtDate(r.expires_at)}
            </div>
          </div>
        </div>
        ${_appState.user ? `<div style="margin-top:var(--space-2);text-align:right">
          <button class="btn btn-ghost btn-xs poison-note-btn"
                  data-poison-note-id="${r.id}"
                  title="Notiz" onclick="event.stopPropagation()">
            <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#note-pencil"></use></svg> Notiz
          </button>
        </div>` : ''}
        ${r.foto_url
          ? `<img src="${r.foto_url}" alt="Foto"
                  loading="lazy"
                  style="width:100%;max-height:160px;object-fit:cover;
                         border-radius:var(--radius-sm);margin-top:var(--space-2)">`
          : ''}
      </div>
    `;
  }

  // ----------------------------------------------------------
  // DETAIL-MODAL
  // ----------------------------------------------------------
  function _openDetail(r) {
    const typ        = TYPEN[r.typ] || TYPEN.unbekannt;
    const isOwnEntry = _appState.user && _appState.user.id === r.user_id;
    const isAdmin    = _appState.user?.rolle === 'admin';

    const body = `
      ${r.foto_url
        ? `<img src="${r.foto_url}" alt="Foto"
                style="width:100%;border-radius:var(--radius-md);margin-bottom:var(--space-4)">`
        : ''}

      <div style="display:flex;gap:var(--space-2);flex-wrap:wrap;margin-bottom:var(--space-3)">
        <span class="badge" style="background:${typ.color};color:#fff">
          ${UI.icon(typ.icon)} ${typ.label}
        </span>
        ${r.bestaetigt ? '<span class="badge badge-success"><svg class="ph-icon" aria-hidden="true" style="color:var(--c-success)"><use href="/icons/phosphor.svg#check-circle"></use></svg> Bestätigt</span>' : ''}
      </div>

      ${r.beschreibung
        ? `<p style="white-space:pre-wrap;margin-bottom:var(--space-3)">${UI.escape(r.beschreibung)}</p>`
        : ''}

      <div style="font-size:var(--text-sm);color:var(--c-text-secondary);
                  margin-bottom:var(--space-4);line-height:1.8">
        <div>📍 ${r.lat.toFixed(5)}, ${r.lon.toFixed(5)}</div>
        <div>📅 Gemeldet: ${_fmtDate(r.created_at)}</div>
        <div>⏰ Läuft ab: ${_fmtDate(r.expires_at)}</div>
        ${r.melder_name ? `<div>👤 Gemeldet von: ${UI.escape(r.melder_name)}</div>` : ''}
      </div>

      <div style="display:flex;gap:var(--space-2);flex-wrap:wrap">
        ${!r.bestaetigt && _appState.user && !isOwnEntry
          ? `<button class="btn btn-secondary flex-1" id="detail-confirm"><svg class="ph-icon" aria-hidden="true" style="color:var(--c-success)"><use href="/icons/phosphor.svg#check-circle"></use></svg> Bestätigen</button>`
          : ''}
        <button class="btn btn-secondary flex-1" id="detail-show-map">🗺️ Auf Karte</button>
        ${isOwnEntry || isAdmin
          ? `<button class="btn btn-nature flex-1" id="detail-resolve">✔ Erledigt</button>`
          : ''}
      </div>
    `;

    UI.modal.open({ title: `${UI.icon(typ.icon)} Giftköder-Meldung`, body });

    document.getElementById('detail-confirm')?.addEventListener('click', async () => {
      try {
        const updated = await API.poison.confirm(r.id);
        const idx = _reports.findIndex(x => x.id === r.id);
        if (idx !== -1) _reports[idx] = { ..._reports[idx], ...updated };
        UI.toast.success('Meldung bestätigt. Danke!');
        UI.modal.close();
        _renderMarkers();
        _renderList();
      } catch (err) {
        UI.toast.error(err.message || 'Fehler beim Bestätigen.');
      }
    });

    document.getElementById('detail-show-map')?.addEventListener('click', () => {
      UI.modal.close();
      if (_map) {
        _map.setView([r.lat, r.lon], 16);
        document.getElementById('poison-map')
          ?.scrollIntoView({ behavior: 'smooth', block: 'start' });
        // Popup des Markers öffnen
        const marker = _markers[_reports.findIndex(x => x.id === r.id)];
        marker?.openPopup();
      }
    });

    document.getElementById('detail-resolve')?.addEventListener('click', () => {
      _showResolveDialog(r);
    });
  }

  // ----------------------------------------------------------
  // ERLEDIGT-DIALOG — mit Grundauswahl für KI-Analyse
  // ----------------------------------------------------------
  function _showResolveDialog(r) {
    UI.modal.open({
      title: '✔ Meldung als erledigt markieren',
      body: `
        <p style="color:var(--c-text-secondary);margin-bottom:var(--space-4)">
          Die Meldung wird inaktiv gesetzt. Die Daten bleiben für spätere
          Musteranalysen gespeichert.
        </p>
        <div class="form-group">
          <label class="form-label">Grund</label>
          <select class="form-control" id="resolve-grund">
            <option value="beseitigt">Gefahr wurde beseitigt</option>
            <option value="fehlerhaft">❌ Meldung war fehlerhaft</option>
            <option value="anderes">💬 Anderer Grund</option>
          </select>
        </div>
      `,
      footer: `
        <button class="btn btn-secondary" id="resolve-cancel">Abbrechen</button>
        <button class="btn btn-nature"    id="resolve-confirm">Erledigt markieren</button>
      `,
    });

    document.getElementById('resolve-cancel')
      ?.addEventListener('click', UI.modal.close);

    document.getElementById('resolve-confirm')
      ?.addEventListener('click', async () => {
        const grund = document.getElementById('resolve-grund')?.value || 'beseitigt';
        const btn   = document.getElementById('resolve-confirm');
        await UI.asyncButton(btn, async () => {
          await API.poison.resolve(r.id, { grund });
          _reports = _reports.filter(x => x.id !== r.id);
          _renderMarkers();
          _renderList();
          _updateBadge(_reports.length);
          App.checkNearbyAlerts();
          UI.modal.close();
          UI.toast.success('Meldung als erledigt markiert.');
        });
      });
  }

  // ----------------------------------------------------------
  // MELDE-FORMULAR
  // ----------------------------------------------------------
  function _showReportForm() {
    if (!_appState.user) {
      UI.toast.warning('Bitte zuerst anmelden, um eine Meldung abzuschicken.');
      App.navigate('settings');
      return;
    }

    const typOpts = Object.entries(TYPEN)
      .map(([val, { label }]) =>
        `<option value="${val}">${label}</option>`)
      .join('');

    const body = `
      <form id="poison-form" autocomplete="off">

        <div class="form-group">
          <label class="form-label">Art des Fundes</label>
          <select class="form-control" name="typ">${typOpts}</select>
        </div>

        <div class="form-group">
          <label class="form-label">Standort</label>
          <div id="poison-location-picker"></div>
        </div>

        <div class="form-group">
          <label class="form-label">
            Beschreibung
            <span style="color:var(--c-text-secondary)">(optional)</span>
          </label>
          <textarea class="form-control" name="beschreibung" rows="3"
                    placeholder="z. B. Wurstköder mit Nadeln, liegt beim Eingang Hundeparkplatz, linke Seite…"></textarea>
        </div>

        <div class="form-group">
          <label class="form-label">
            Foto
            <span style="color:var(--c-text-secondary)">(optional)</span>
          </label>
          <input class="form-control" type="file" name="photo"
                 accept="image/*" capture="environment">
          <img id="pf-photo-preview"
               style="display:none;width:100%;max-height:200px;object-fit:cover;
                      border-radius:var(--radius-md);margin-top:var(--space-2)">
        </div>

      </form>
    `;

    const footer = `
      <button type="button" class="btn btn-secondary flex-1" id="pf-cancel">Abbrechen</button>
      <button type="submit" form="poison-form" class="btn btn-danger">
        Absenden
      </button>
    `;

    UI.modal.open({ title: '⚠️ Giftköder melden', body, footer });

    // Location-Picker initialisieren + ggf. bekannten Standort vorausfüllen
    const _picker = UI.locationPicker({ containerId: 'poison-location-picker' });
    if (_userPos) {
      _picker.setValue(_userPos.lat, _userPos.lon, null);
    }

    // Foto-Vorschau
    const photoInput   = document.querySelector('#poison-form [name="photo"]');
    const photoPreview = document.getElementById('pf-photo-preview');
    if (photoInput && photoPreview) {
      UI.setupPhotoPreview(photoInput, photoPreview);
      photoInput.addEventListener('change', () => {
        photoPreview.style.display = photoInput.files[0] ? 'block' : 'none';
      });
    }

    document.getElementById('pf-cancel')
      ?.addEventListener('click', UI.modal.close);

    // Formular absenden
    document.getElementById('poison-form')?.addEventListener('submit', async e => {
      e.preventDefault();
      const submitBtn = document.querySelector('[form="poison-form"][type="submit"]') || e.target.querySelector('[type="submit"]');
      const fd        = UI.formData(e.target);
      const loc       = _picker.getValue();

      if (!loc.lat || !loc.lon) {
        UI.toast.warning('Bitte zuerst den GPS-Standort ermitteln (📍).');
        return;
      }

      await UI.asyncButton(submitBtn, async () => {
        const payload = {
          lat          : loc.lat,
          lon          : loc.lon,
          typ          : fd.typ,
          beschreibung : fd.beschreibung || null,
        };

        const created = await API.poison.report(payload);

        // Foto hochladen
        if (photoInput?.files[0]) {
          try {
            const formData = new FormData();
            formData.append('file', photoInput.files[0]);
            const media = await API.poison.uploadPhoto(created.id, formData);
            created.foto_url = media.foto_url;
          } catch {
            UI.toast.warning('Meldung erstellt — Foto konnte nicht hochgeladen werden.');
          }
        }

        // Distanz client-seitig berechnen (für sofortige Anzeige)
        // _userPos aktualisieren falls Picker neuen Standort geliefert hat
        if (loc.lat && loc.lon) _userPos = { lat: loc.lat, lon: loc.lon };
        created.distanz_m = _userPos
          ? Math.round(_haversine(_userPos.lat, _userPos.lon, created.lat, created.lon))
          : 0;

        _reports.unshift(created);
        _renderMarkers();
        _renderList();
        _updateBadge(_reports.length);
        App.checkNearbyAlerts();
        App.callModule('map', 'refresh');
        UI.toast.success('Giftköder gemeldet! Danke für die Warnung.');
        UI.modal.close();
      });
    });
  }

  // ----------------------------------------------------------
  // BADGE (Sidebar + Bottom-Nav)
  // ----------------------------------------------------------
  function _updateBadge(count) {
    const b1 = document.getElementById('poison-badge');
    const b2 = document.getElementById('poison-nav-badge');
    if (b1) { b1.textContent = count; b1.style.display = count > 0 ? '' : 'none'; }
    if (b2) { b2.textContent = count; b2.classList.toggle('hidden', count === 0); }
  }

  // ----------------------------------------------------------
  // HELPER
  // ----------------------------------------------------------

  // Haversine client-seitig (für frisch gemeldete Einträge)
  function _haversine(lat1, lon1, lat2, lon2) {
    const R  = 6_371_000;
    const p1 = lat1 * Math.PI / 180;
    const p2 = lat2 * Math.PI / 180;
    const dp = (lat2 - lat1) * Math.PI / 180;
    const dl = (lon2 - lon1) * Math.PI / 180;
    const a  = Math.sin(dp / 2) ** 2 + Math.cos(p1) * Math.cos(p2) * Math.sin(dl / 2) ** 2;
    return 2 * R * Math.asin(Math.sqrt(a));
  }

  // _fmtDate: bewusst lokal behalten — UI.time.format() liefert langen Monats-Namen
  // und behandelt kein SQLite-Leerzeichen-Format ("2026-04-12 00:00:00")
  function _fmtDate(isoStr) {
    if (!isoStr) return '';
    // SQLite speichert "2026-04-12T00:00:00" oder "2026-04-12 00:00:00"
    const d = new Date(isoStr.replace(' ', 'T'));
    return d.toLocaleDateString('de-DE', {
      day: '2-digit', month: '2-digit', year: 'numeric'
    });
  }

  // ----------------------------------------------------------
  // NOTIZ-MODAL
  // ----------------------------------------------------------
  async function _openNoteModal(parentType, parentId, parentLabel, locationName) {
    document.getElementById('by-note-modal')?.remove();

    const overlay = document.createElement('div');
    overlay.id = 'by-note-modal';
    overlay.style.cssText = 'position:fixed;inset:0;z-index:2000;background:rgba(0,0,0,.55);display:flex;align-items:flex-end;justify-content:center';

    overlay.innerHTML = `
      <div style="background:var(--c-surface);border-radius:var(--radius-xl) var(--radius-xl) 0 0;
                  width:100%;max-width:640px;max-height:90vh;display:flex;flex-direction:column;
                  padding-bottom:env(safe-area-inset-bottom,0px)">
        <div style="padding:var(--space-4) var(--space-5);border-bottom:1px solid var(--c-border);
                    display:flex;align-items:center;justify-content:space-between;flex-shrink:0">
          <div>
            <div style="font-weight:var(--weight-semibold);font-size:var(--text-base)"><svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#note-pencil"></use></svg> Notiz</div>
            <div style="font-size:var(--text-xs);color:var(--c-text-muted);margin-top:2px">${UI.escape(parentLabel)}</div>
          </div>
          <button id="by-note-close" style="background:none;border:none;cursor:pointer;font-size:1.4rem;color:var(--c-text-muted);padding:4px 8px" aria-label="Schließen">×</button>
        </div>
        <div style="padding:var(--space-4) var(--space-5);flex:1;overflow-y:auto">
          <form id="by-note-form">
            <textarea id="by-note-text" class="form-control" rows="5"
                      placeholder="Notiz eingeben…"
                      style="width:100%;resize:vertical"></textarea>
          </form>
        </div>
        <div style="padding:var(--space-3) var(--space-5);border-top:1px solid var(--c-border);
                    display:flex;gap:var(--space-2);flex-shrink:0">
          <button type="button" id="by-note-cancel" class="btn btn-secondary flex-1">Abbrechen</button>
          <button type="submit" form="by-note-form" id="by-note-save" class="btn btn-primary flex-1">Speichern</button>
        </div>
      </div>
    `;

    document.body.appendChild(overlay);

    const textarea  = document.getElementById('by-note-text');
    const saveBtn   = document.getElementById('by-note-save');
    const cancelBtn = document.getElementById('by-note-cancel');
    const closeBtn  = document.getElementById('by-note-close');

    let existingNoteId = null;

    try {
      const existing = await API.notes.get(parentType, String(parentId));
      if (existing?.id) {
        existingNoteId = existing.id;
        textarea.value = existing.text || '';
      }
    } catch (_) { /* keine Notiz vorhanden — ok */ }

    setTimeout(() => textarea.focus(), 100);

    const _close = () => overlay.remove();
    closeBtn.addEventListener('click', _close);
    cancelBtn.addEventListener('click', _close);
    overlay.addEventListener('click', e => { if (e.target === overlay) _close(); });

    document.getElementById('by-note-form').addEventListener('submit', async e => {
      e.preventDefault();
      const text = textarea.value.trim();
      UI.setLoading(saveBtn, true);
      try {
        const payload = { text, parent_label: parentLabel, location_name: locationName };
        if (existingNoteId) {
          await API.notes.update(existingNoteId, payload);
        } else {
          await API.notes.create(parentType, String(parentId), payload);
        }
        UI.toast.success('Notiz gespeichert.');
        _close();
      } catch (err) {
        UI.toast.error(err.message || 'Fehler beim Speichern.');
        UI.setLoading(saveBtn, false);
      }
    });
  }

  // ----------------------------------------------------------
  // PUBLIC
  // ----------------------------------------------------------
  return { init, refresh, openNew, openDetail: _openDetail };

})();
