/* ============================================================
   BAN YARO — Notizblock
   Seiten-Modul: Alle Notizen mit Filter, Suche, Sortierung und KI-Analyse.
   ============================================================ */

window.Page_notes = (() => {

  let _container = null;
  let _appState  = null;
  let _notes     = [];

  // Aktueller Filter-/Such-Zustand
  let _filterType = '';       // '' = alle
  let _sortMode   = 'newest'; // newest | type | location
  let _searchQ    = '';
  let _searchTimer = null;

  // KI-Panel
  let _kiOpen        = false;
  let _kiLoading     = false;
  let _kiSuggestions = null;
  let _kiError       = null;

  // ----------------------------------------------------------
  // Rubrik-Konfiguration
  // ----------------------------------------------------------
  const RUBRIKEN = [
    { type: '',               label: 'Alle',         color: 'var(--c-text-muted)',  icon: 'note' },
    { type: 'health',         label: 'Gesundheit',   color: '#e74c3c',              icon: 'heart' },
    { type: 'diary',          label: 'Tagebuch',     color: '#C4843A',              icon: 'book-open' },
    { type: 'training_session', label: 'Training',   color: '#27ae60',              icon: 'target' },
    { type: 'route',          label: 'Routen',       color: '#2980b9',              icon: 'path' },
    { type: 'event',          label: 'Events',       color: '#8e44ad',              icon: 'calendar' },
    { type: 'walk',           label: 'Gassi-Treffen',color: '#f39c12',              icon: 'paw-print' },
    { type: 'sitting',        label: 'Sitting',      color: '#16a085',              icon: 'house-line' },
    { type: 'erste_hilfe',    label: 'Erste Hilfe',  color: '#c0392b',              icon: 'first-aid' },
    { type: 'trainingsplan',  label: 'Trainingsplan',color: '#059669',              icon: 'clipboard-text' },
    { type: 'friends',        label: 'Freunde',      color: '#7c3aed',              icon: 'users' },
    { type: 'poison',         label: 'Giftköder',    color: '#dc2626',              icon: 'warning-octagon' },
    { type: 'lost',           label: 'Vermisste',    color: '#b45309',              icon: 'magnifying-glass' },
  ];

  function _rubrik(type) {
    return RUBRIKEN.find(r => r.type === type) || { type, label: type, color: 'var(--c-text-muted)', icon: 'note' };
  }

  // ----------------------------------------------------------
  // Hilfsfunktionen
  // ----------------------------------------------------------
  function _esc(s) {
    if (!s) return '';
    return String(s)
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;');
  }

  function _formatTime(isoStr) {
    if (!isoStr) return '';
    try {
      const d = new Date(isoStr.replace(' ', 'T') + (isoStr.includes('T') || isoStr.endsWith('Z') ? '' : 'Z'));
      return d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' });
    } catch (_) { return ''; }
  }

  function _dateGroup(isoStr) {
    if (!isoStr) return 'Älteres';
    try {
      const d   = new Date(isoStr.replace(' ', 'T') + (isoStr.includes('T') || isoStr.endsWith('Z') ? '' : 'Z'));
      const now = new Date();
      const diffDays = (now - d) / 86400000;
      if (diffDays < 1 && d.getDate() === now.getDate()) return 'Heute';
      if (diffDays < 7) return 'Diese Woche';
      return 'Älteres';
    } catch (_) { return 'Älteres'; }
  }

  function _truncate(str, max = 150) {
    if (!str) return '';
    return str.length > max ? str.slice(0, max) + '…' : str;
  }

  // ----------------------------------------------------------
  // Daten laden
  // ----------------------------------------------------------
  async function _load() {
    const params = {};
    if (_filterType) params.parent_type = _filterType;
    if (_sortMode !== 'newest') params.sort = _sortMode;
    if (_searchQ) params.q = _searchQ;
    return await API.notes.getAll(params);
  }

  // ----------------------------------------------------------
  // Filter/Sortierung anwenden (client-seitig falls API alles zurückgibt)
  // ----------------------------------------------------------
  function _applySort(list) {
    const copy = [...list];
    if (_sortMode === 'newest') {
      copy.sort((a, b) => new Date(b.updated_at || b.created_at) - new Date(a.updated_at || a.created_at));
    } else if (_sortMode === 'type') {
      copy.sort((a, b) => (a.parent_type || '').localeCompare(b.parent_type || '', 'de'));
    } else if (_sortMode === 'location') {
      copy.sort((a, b) => (a.location_name || '').localeCompare(b.location_name || '', 'de'));
    }
    return copy;
  }

  // ----------------------------------------------------------
  // Rendern
  // ----------------------------------------------------------
  function _render() {
    const kiEnabled = _appState?.user?.notes_ki_enabled !== 0;
    const sorted    = _applySort(_notes);

    // Gruppen aufbauen
    const groups = { 'Heute': [], 'Diese Woche': [], 'Älteres': [] };
    sorted.forEach(n => {
      const g = _dateGroup(n.updated_at || n.created_at);
      groups[g].push(n);
    });

    const groupHtml = Object.entries(groups)
      .filter(([, items]) => items.length > 0)
      .map(([label, items]) => `
        <div class="notes-group">
          <div class="notes-group-label">${_esc(label)}</div>
          ${items.map(_noteCard).join('')}
        </div>
      `).join('');

    _container.innerHTML = `
      <div class="notes-page">

        <!-- Header -->
        <div class="notes-header">
          <h2 class="notes-title">Notizblock</h2>
          <div style="display:flex;align-items:center;gap:var(--space-2)">
            <span class="notes-count">${_notes.length} Notiz${_notes.length !== 1 ? 'en' : ''}</span>
            <button id="notes-new-btn" class="btn btn-primary btn-sm" style="gap:4px">
              <svg class="ph-icon" aria-hidden="true" style="width:15px;height:15px"><use href="/icons/phosphor.svg#plus"></use></svg>
              ${_filterType && _filterType !== '' ? _rubrik(_filterType).label : 'Neue Notiz'}
            </button>
          </div>
        </div>

        <!-- Datenschutz-Hinweis (einmalig, wegklickbar) -->
        ${localStorage.getItem('by_notes_privacy_ack') ? '' : `
        <div id="notes-privacy-notice" style="font-size:var(--text-xs);color:var(--c-text-secondary);
                    background:var(--c-surface-2);border-radius:var(--radius-md);
                    padding:var(--space-3) var(--space-3);display:flex;align-items:center;
                    gap:var(--space-2);cursor:pointer;border:1px solid var(--c-border-light)"
             title="Klicken zum Schließen">
          <svg class="ph-icon" aria-hidden="true" style="width:16px;height:16px;flex-shrink:0;color:var(--c-primary)">
            <use href="/icons/phosphor.svg#lock-simple"></use></svg>
          <span>Alle Notizen sind privat — nur du kannst sie lesen.</span>
          <svg class="ph-icon" aria-hidden="true" style="width:12px;height:12px;margin-left:auto;flex-shrink:0;opacity:0.4">
            <use href="/icons/phosphor.svg#x"></use></svg>
        </div>`}

        <!-- KI-Panel -->
        ${kiEnabled ? _kiPanelHtml() : ''}

        <!-- Filter-Chips -->
        <div class="notes-filter-chips">
          ${RUBRIKEN.map(r => `
            <button class="notes-chip ${_filterType === r.type ? 'notes-chip--active' : ''}"
                    data-type="${_esc(r.type)}"
                    style="${_filterType === r.type ? `--chip-color:${r.color}` : ''}">
              ${_esc(r.label)}
            </button>
          `).join('')}
        </div>

        <!-- Suche + Sortierung -->
        <div class="notes-toolbar">
          <div class="notes-search-wrap">
            <svg class="ph-icon notes-search-icon" aria-hidden="true"><use href="/icons/phosphor.svg#magnifying-glass"></use></svg>
            <input id="notes-search" type="search" class="notes-search-input"
                   placeholder="Suche…" value="${_esc(_searchQ)}">
          </div>
          <div class="notes-sort-btns">
            <button class="notes-sort-btn ${_sortMode === 'newest' ? 'notes-sort-btn--active' : ''}"
                    data-sort="newest">Neueste</button>
            <button class="notes-sort-btn ${_sortMode === 'type' ? 'notes-sort-btn--active' : ''}"
                    data-sort="type">Rubrik</button>
            <button class="notes-sort-btn ${_sortMode === 'location' ? 'notes-sort-btn--active' : ''}"
                    data-sort="location">Ort</button>
          </div>
        </div>

        <!-- Liste -->
        <div class="notes-list">
          ${sorted.length === 0
            ? UI.emptyState({ icon: 'note', title: 'Keine Notizen', text: 'Füge Notizen zu Trainingseinheiten oder anderen Einträgen hinzu.' })
            : groupHtml
          }
        </div>

      </div>

      <style>
        .notes-page { padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-3); }

        .notes-header { display: flex; align-items: center; justify-content: space-between; }
        .notes-title  { font-size: var(--text-lg); font-weight: var(--weight-bold); color: var(--c-text); margin: 0; }
        .notes-count  { font-size: var(--text-xs); color: var(--c-text-muted); }

        /* KI-Panel */
        .notes-ki-panel { background: var(--c-surface-2); border: 1.5px solid var(--c-border); border-radius: var(--radius-lg); overflow: hidden; }
        .notes-ki-header { display: flex; align-items: center; justify-content: space-between; padding: var(--space-3) var(--space-4); cursor: pointer; gap: var(--space-2); }
        .notes-ki-header-left { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--c-text); }
        .notes-ki-chevron { transition: transform .2s; color: var(--c-text-muted); }
        .notes-ki-chevron--open { transform: rotate(180deg); }
        .notes-ki-body { padding: var(--space-3) var(--space-4) var(--space-4); border-top: 1px solid var(--c-border); }
        .notes-ki-btn { padding: var(--space-2) var(--space-4); border-radius: var(--radius-md); border: none; background: var(--c-primary); color: #fff; font-size: var(--text-sm); font-weight: var(--weight-semibold); cursor: pointer; }
        .notes-ki-btn:disabled { opacity: .6; cursor: default; }
        .notes-ki-suggestions { margin-top: var(--space-3); font-size: var(--text-sm); color: var(--c-text); line-height: 1.6; }
        .notes-ki-suggestions ul { margin: var(--space-2) 0 0; padding-left: var(--space-4); }
        .notes-ki-suggestions li { margin-bottom: var(--space-1); }
        .notes-ki-error { margin-top: var(--space-2); font-size: var(--text-sm); color: var(--c-danger); }

        /* Filter-Chips */
        .notes-filter-chips { display: flex; gap: var(--space-2); overflow-x: auto; padding-bottom: 2px; scrollbar-width: none; }
        .notes-filter-chips::-webkit-scrollbar { display: none; }
        @media (min-width: 1024px) {
          .notes-filter-chips { flex-wrap: wrap; overflow-x: visible; }
        }
        .notes-chip { flex-shrink: 0; font-size: var(--text-xs); font-weight: var(--weight-semibold); padding: 4px var(--space-3); border-radius: 999px; border: 1.5px solid var(--c-border); background: var(--c-surface-2); color: var(--c-text-secondary); cursor: pointer; white-space: nowrap; transition: background .15s, color .15s, border-color .15s; }
        .notes-chip--active { background: var(--chip-color, var(--c-primary)); color: #fff; border-color: var(--chip-color, var(--c-primary)); }

        /* Toolbar */
        .notes-toolbar { display: flex; gap: var(--space-2); align-items: center; }
        .notes-search-wrap { position: relative; flex: 1; }
        .notes-search-icon { position: absolute; left: var(--space-3); top: 50%; transform: translateY(-50%); color: var(--c-text-muted); width: 16px; height: 16px; pointer-events: none; }
        .notes-search-input { width: 100%; padding: var(--space-2) var(--space-3) var(--space-2) calc(var(--space-3) + 1.3rem); border: 1.5px solid var(--c-border); border-radius: var(--radius-md); font-size: var(--text-sm); background: var(--c-surface); color: var(--c-text); outline: none; box-sizing: border-box; }
        .notes-search-input:focus { border-color: var(--c-primary); }
        .notes-sort-btns { display: flex; border: 1.5px solid var(--c-border); border-radius: var(--radius-md); overflow: hidden; flex-shrink: 0; }
        .notes-sort-btn { padding: var(--space-2) var(--space-3); font-size: var(--text-xs); font-weight: var(--weight-semibold); border: none; background: var(--c-surface-2); color: var(--c-text-secondary); cursor: pointer; transition: background .15s, color .15s; border-right: 1px solid var(--c-border); }
        .notes-sort-btn:last-child { border-right: none; }
        .notes-sort-btn--active { background: var(--c-primary); color: #fff; }

        /* Gruppen */
        .notes-group { display: flex; flex-direction: column; gap: var(--space-2); }
        .notes-group-label { font-size: var(--text-xs); font-weight: var(--weight-semibold); color: var(--c-text-muted); text-transform: uppercase; letter-spacing: .05em; padding: var(--space-1) 0; }

        /* Karten */
        .notes-card { background: var(--c-surface); border: 1px solid var(--c-border); border-radius: var(--radius-lg); padding: var(--space-3) var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
        .notes-card-top { display: flex; align-items: flex-start; gap: var(--space-2); }
        .notes-rubrik-chip { display: inline-flex; align-items: center; gap: 4px; font-size: var(--text-xs); font-weight: var(--weight-semibold); padding: 2px var(--space-2); border-radius: 999px; flex-shrink: 0; }
        .notes-parent-label { font-size: var(--text-xs); color: var(--c-text-secondary); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; align-self: center; }
        .notes-card-meta { display: flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); color: var(--c-text-muted); }
        .notes-card-actions { display: flex; gap: var(--space-2); margin-left: auto; flex-shrink: 0; }
        .notes-card-text { font-size: var(--text-sm); color: var(--c-text); line-height: 1.55; white-space: pre-wrap; margin: 0; }
        .notes-micro-badges { display: flex; flex-wrap: wrap; gap: var(--space-1); }
        .notes-micro-badge { font-size: var(--text-xs); padding: 2px 6px; border-radius: var(--radius-sm); background: var(--c-surface-2); color: var(--c-text-secondary); }
        .notes-action-btn { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: var(--radius-md); border: 1px solid var(--c-border); background: var(--c-surface-2); color: var(--c-text-muted); cursor: pointer; font-size: 1rem; transition: background .15s, color .15s; }
        .notes-action-btn:hover { background: var(--c-surface); color: var(--c-text); }
        .notes-action-btn--danger:hover { background: #fef2f2; color: var(--c-danger); border-color: var(--c-danger); }

        .notes-list { display: flex; flex-direction: column; gap: var(--space-4); }
        @keyframes spin { to { transform: rotate(360deg); } }
      </style>
    `;

    _bindEvents();
  }

  // ----------------------------------------------------------
  // KI-Panel HTML
  // ----------------------------------------------------------
  function _kiPanelHtml() {
    return `
      <div class="notes-ki-panel" id="notes-ki-panel">
        <div class="notes-ki-header" id="notes-ki-toggle">
          <div class="notes-ki-header-left">
            <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#robot"></use></svg>
            Muster-Analyse
          </div>
          <svg class="ph-icon notes-ki-chevron ${_kiOpen ? 'notes-ki-chevron--open' : ''}" id="notes-ki-chevron" aria-hidden="true"><use href="/icons/phosphor.svg#caret-down"></use></svg>
        </div>
        ${_kiOpen ? `
          <div class="notes-ki-body" id="notes-ki-body">
            <button class="notes-ki-btn" id="notes-ki-analyse-btn" ${_kiLoading ? 'disabled' : ''}>
              ${_kiLoading ? '<svg class="ph-icon" aria-hidden="true" style="animation:spin 1s linear infinite"><use href="/icons/phosphor.svg#spinner-gap"></use></svg> Analysiere…' : 'Analysieren'}
            </button>
            ${_kiError ? `<div class="notes-ki-error"><svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#warning-circle"></use></svg> ${_esc(_kiError)}</div>` : ''}
            ${_kiSuggestions ? `
              <div class="notes-ki-suggestions">
                <ul>
                  ${_kiSuggestions.map(s => `<li>${_esc(s)}</li>`).join('')}
                </ul>
              </div>
            ` : ''}
          </div>
        ` : ''}
      </div>
    `;
  }

  // ----------------------------------------------------------
  // Notiz-Karte HTML
  // ----------------------------------------------------------
  function _noteCard(note) {
    const rb   = _rubrik(note.parent_type);
    const meta = note.meta_json || {};

    const microBadges = [];
    if (meta.erfolgsquote) microBadges.push('🐾'.repeat(meta.erfolgsquote));
    if (meta.umgebung)    microBadges.push({ zuhause: '🏠 Zuhause', natur: '🌿 Natur', stadt: '🌆 Stadt' }[meta.umgebung] || meta.umgebung);
    if (meta.hund_stimmung) microBadges.push({ super: '😊 Super', ok: '😐 Ok', mude: '😔 Müde' }[meta.hund_stimmung] || meta.hund_stimmung);

    const hasLocation = !!note.location_name;

    return `
      <div class="notes-card" data-id="${note.id}">
        <!-- Top-Zeile: Rubrik-Chip + parent_label + Zeit + Buttons -->
        <div class="notes-card-top">
          <span class="notes-rubrik-chip"
                style="background:${rb.color}22;color:${rb.color}">
            <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#${rb.icon}"></use></svg>
            ${_esc(rb.label)}
          </span>
          ${note.parent_label
            ? `<span class="notes-parent-label" title="${_esc(note.parent_label)}">${_esc(note.parent_label)}</span>`
            : ''
          }
          <div class="notes-card-actions">
            <button class="notes-action-btn notes-edit-btn" data-id="${note.id}" title="Bearbeiten">
              <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#pencil"></use></svg>
            </button>
            <button class="notes-action-btn notes-action-btn--danger notes-delete-btn" data-id="${note.id}" title="Löschen">
              <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#trash"></use></svg>
            </button>
          </div>
        </div>

        <!-- Notiztext -->
        <p class="notes-card-text">${_esc(_truncate(note.text))}</p>

        <!-- Micro-Badges -->
        ${microBadges.length ? `
          <div class="notes-micro-badges">
            ${microBadges.map(b => `<span class="notes-micro-badge">${_esc(b)}</span>`).join('')}
          </div>
        ` : ''}

        <!-- Meta: Zeit + Ort -->
        <div class="notes-card-meta">
          <svg class="ph-icon" aria-hidden="true" style="width:12px;height:12px"><use href="/icons/phosphor.svg#clock"></use></svg>
          ${_esc(_formatTime(note.updated_at || note.created_at))}
          ${hasLocation ? `<svg class="ph-icon" aria-hidden="true" style="width:12px;height:12px"><use href="/icons/phosphor.svg#map-pin"></use></svg> ${_esc(note.location_name)}` : ''}
        </div>
      </div>
    `;
  }

  // ----------------------------------------------------------
  // Event-Binding
  // ----------------------------------------------------------
  function _bindEvents() {

    // Datenschutz-Hinweis wegklicken
    _container.querySelector('#notes-privacy-notice')?.addEventListener('click', () => {
      localStorage.setItem('by_notes_privacy_ack', '1');
      _container.querySelector('#notes-privacy-notice')?.remove();
    });

    // Neue Notiz
    _container.querySelector('#notes-new-btn')?.addEventListener('click', () => {
      _openCreateModal(_filterType || '');
    });

    // Filter-Chips
    _container.querySelectorAll('.notes-chip').forEach(btn => {
      btn.addEventListener('click', () => {
        _filterType = btn.dataset.type;
        _reload();
      });
    });

    // Sortierung
    _container.querySelectorAll('.notes-sort-btn').forEach(btn => {
      btn.addEventListener('click', () => {
        _sortMode = btn.dataset.sort;
        _render(); // nur neu rendern, keine API-Last
      });
    });

    // Suche (debounced)
    const searchInput = _container.querySelector('#notes-search');
    if (searchInput) {
      searchInput.addEventListener('input', () => {
        clearTimeout(_searchTimer);
        _searchTimer = setTimeout(() => {
          _searchQ = searchInput.value.trim();
          _reload();
        }, 300);
      });
    }

    // KI-Toggle
    const kiToggle = _container.querySelector('#notes-ki-toggle');
    if (kiToggle) {
      kiToggle.addEventListener('click', () => {
        _kiOpen = !_kiOpen;
        _render();
      });
    }

    // KI-Analyse-Button
    const kiBtn = _container.querySelector('#notes-ki-analyse-btn');
    if (kiBtn) {
      kiBtn.addEventListener('click', async () => {
        _kiLoading     = true;
        _kiError       = null;
        _kiSuggestions = null;
        _render();
        try {
          const res = await API.notes.analyse();
          if (res && Array.isArray(res.suggestions)) {
            _kiSuggestions = res.suggestions;
          } else if (res && res.text) {
            _kiSuggestions = res.text.split('\n').filter(Boolean);
          } else {
            _kiSuggestions = ['Keine Vorschläge verfügbar.'];
          }
        } catch (err) {
          _kiError = err?.message || 'KI-Analyse nicht verfügbar.';
        } finally {
          _kiLoading = false;
          _render();
        }
      });
    }

    // Edit-Buttons
    _container.querySelectorAll('.notes-edit-btn').forEach(btn => {
      btn.addEventListener('click', e => {
        e.stopPropagation();
        const note = _notes.find(n => n.id === parseInt(btn.dataset.id, 10));
        if (note) _openEditModal(note);
      });
    });

    // Delete-Buttons
    _container.querySelectorAll('.notes-delete-btn').forEach(btn => {
      btn.addEventListener('click', async e => {
        e.stopPropagation();
        const noteId = parseInt(btn.dataset.id, 10);
        if (!window.confirm('Notiz wirklich löschen?')) return;
        try {
          await API.notes.delete(noteId);
          _notes = _notes.filter(n => n.id !== noteId);
          _render();
          UI.toast.success('Notiz gelöscht.');
        } catch (_) {
          UI.toast.error('Löschen fehlgeschlagen.');
        }
      });
    });
  }

  // ----------------------------------------------------------
  // Laden + Re-Render
  // ----------------------------------------------------------
  async function _reload() {
    _container.querySelector('.notes-list')?.classList.add('loading');
    try {
      _notes = await _load();
    } catch (_) {
      _notes = [];
    }
    _render();
  }

  // ----------------------------------------------------------
  // Create-Modal — neue Notiz mit vorausgewählter Kategorie
  // ----------------------------------------------------------
  function _openCreateModal(preselectedType = '') {
    const ERSTELL_RUBRIKEN = RUBRIKEN.filter(r => r.type !== ''); // ohne "Alle"
    let _selType = preselectedType || ERSTELL_RUBRIKEN[0].type;

    const modalId = 'notes-create-modal';
    document.getElementById(modalId)?.remove();

    const overlay = document.createElement('div');
    overlay.id = modalId;
    overlay.style.cssText = `position:fixed;inset:0;z-index:9999;display:flex;align-items:flex-end;justify-content:center;background:rgba(0,0,0,0.45)`;

    const _buildContent = () => {
      const rb = _rubrik(_selType);
      return `
        <div style="background:var(--c-surface);border-radius:var(--radius-lg) var(--radius-lg) 0 0;
                    width:100%;max-width:480px;max-height:90vh;overflow-y:auto;
                    padding:var(--space-5) var(--space-4) var(--space-6);box-shadow:0 -4px 24px rgba(0,0,0,0.15)">
          <div style="width:40px;height:4px;background:var(--c-border);border-radius:2px;margin:0 auto var(--space-4)"></div>
          <h3 style="font-size:var(--text-base);font-weight:700;margin:0 0 var(--space-4)">Neue Notiz</h3>

          <!-- Kategorie-Auswahl -->
          <div style="margin-bottom:var(--space-4)">
            <label style="display:block;font-size:var(--text-sm);font-weight:600;color:var(--c-text);margin-bottom:var(--space-2)">Kategorie</label>
            <div style="display:flex;flex-wrap:wrap;gap:var(--space-2)">
              ${ERSTELL_RUBRIKEN.map(r => `
                <button class="nc-cat" data-type="${r.type}"
                        style="font-size:var(--text-xs);font-weight:600;padding:4px var(--space-3);
                               border-radius:999px;border:1.5px solid ${_selType===r.type ? r.color : 'var(--c-border)'};
                               background:${_selType===r.type ? r.color+'22' : 'var(--c-surface-2)'};
                               color:${_selType===r.type ? r.color : 'var(--c-text-secondary)'};cursor:pointer">
                  ${_esc(r.label)}
                </button>`).join('')}
            </div>
          </div>

          <!-- Text -->
          <div style="margin-bottom:var(--space-4)">
            <label style="display:block;font-size:var(--text-sm);font-weight:600;color:var(--c-text);margin-bottom:var(--space-2)">Notiz</label>
            <textarea id="nc-text" rows="5" placeholder="Was möchtest du festhalten…"
                      style="width:100%;padding:var(--space-3);border:1.5px solid var(--c-border);
                             border-radius:var(--radius-md);font-size:var(--text-sm);
                             font-family:var(--font-sans);background:var(--c-surface);
                             color:var(--c-text);resize:vertical;outline:none;line-height:1.5;
                             box-sizing:border-box"></textarea>
          </div>

          <div style="display:flex;gap:var(--space-3)">
            <button id="nc-cancel" class="btn btn-ghost" style="flex:1">Abbrechen</button>
            <button id="nc-save" class="btn btn-primary" style="flex:1">Speichern</button>
          </div>
        </div>`;
    };

    overlay.innerHTML = _buildContent();
    document.body.appendChild(overlay);

    const _rebind = () => {
      overlay.querySelectorAll('.nc-cat').forEach(btn => {
        btn.addEventListener('click', () => {
          _selType = btn.dataset.type;
          overlay.innerHTML = _buildContent();
          _rebind();
          overlay.querySelector('#nc-text')?.focus();
        });
      });

      overlay.querySelector('#nc-cancel')?.addEventListener('click', () => overlay.remove());
      overlay.addEventListener('click', e => { if (e.target === overlay) overlay.remove(); });

      overlay.querySelector('#nc-save')?.addEventListener('click', async () => {
        const text = overlay.querySelector('#nc-text')?.value?.trim();
        if (!text) { UI.toast.warning('Bitte einen Text eingeben.'); return; }
        const btn = overlay.querySelector('#nc-save');
        await UI.asyncButton(btn, async () => {
          const rb = _rubrik(_selType);
          await API.notes.create(_selType, 'standalone', {
            text,
            parent_label: rb.label,
          });
          overlay.remove();
          _filterType = _selType;
          await _reload();
          UI.toast.success('Notiz gespeichert.');
        });
      });

      setTimeout(() => overlay.querySelector('#nc-text')?.focus(), 100);
    };

    _rebind();
  }

  // ----------------------------------------------------------
  // Edit-Modal (Bottom-Sheet Stil)
  // ----------------------------------------------------------
  function _openEditModal(note) {
    const meta = note.meta_json || {};
    const rb   = _rubrik(note.parent_type);

    const modalId = 'notes-edit-modal';
    document.getElementById(modalId)?.remove();

    const overlay = document.createElement('div');
    overlay.id = modalId;
    overlay.style.cssText = `
      position:fixed;inset:0;z-index:9999;
      display:flex;align-items:flex-end;justify-content:center;
      background:rgba(0,0,0,0.45);
    `;

    overlay.innerHTML = `
      <div style="background:var(--c-surface);border-radius:var(--radius-lg) var(--radius-lg) 0 0;
                  width:100%;max-width:480px;max-height:85vh;overflow-y:auto;
                  padding:var(--space-5) var(--space-4) var(--space-6);box-shadow:0 -4px 24px rgba(0,0,0,0.15)">

        <!-- Griff -->
        <div style="width:40px;height:4px;background:var(--c-border);border-radius:2px;margin:0 auto var(--space-4)"></div>

        <!-- Kopfzeile -->
        <div style="display:flex;align-items:center;gap:var(--space-2);margin-bottom:var(--space-4)">
          <span style="display:inline-flex;align-items:center;gap:4px;font-size:var(--text-xs);
                       font-weight:var(--weight-semibold);padding:2px var(--space-2);border-radius:999px;
                       background:${rb.color}22;color:${rb.color}">
            <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#${rb.icon}"></use></svg> ${_esc(rb.label)}
          </span>
          <h3 style="font-size:var(--text-base);font-weight:var(--weight-semibold);color:var(--c-text);margin:0">
            Notiz bearbeiten
          </h3>
        </div>

        <div style="display:flex;flex-direction:column;gap:var(--space-4)">

          <!-- Freitext -->
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:var(--weight-semibold);
                          color:var(--c-text);margin-bottom:var(--space-2)">Text</label>
            <textarea id="notes-edit-text" rows="5"
                      style="width:100%;padding:var(--space-3);border:1.5px solid var(--c-border);
                             border-radius:var(--radius-md);font-size:var(--text-sm);
                             font-family:var(--font-sans);background:var(--c-surface);
                             color:var(--c-text);resize:vertical;outline:none;line-height:1.5;
                             box-sizing:border-box">${_esc(note.text)}</textarea>
          </div>

          ${note.parent_type === 'training_session' ? `
          <!-- Bewertung -->
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:var(--weight-semibold);
                          color:var(--c-text);margin-bottom:var(--space-2)">Bewertung</label>
            <div style="display:flex;gap:var(--space-2)">
              ${[1,2,3,4,5].map(n => `
                <button type="button" class="notes-pfote" data-val="${n}"
                        style="font-size:1.3rem;border:1.5px solid var(--c-border);border-radius:var(--radius-md);
                               padding:3px 9px;cursor:pointer;
                               background:${(meta.erfolgsquote||0)===n?'var(--c-primary-subtle)':'var(--c-surface-2)'};
                               border-color:${(meta.erfolgsquote||0)===n?'var(--c-primary)':'var(--c-border)'}">🐾</button>
              `).join('')}
            </div>
          </div>

          <!-- Umgebung -->
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:var(--weight-semibold);
                          color:var(--c-text);margin-bottom:var(--space-2)">Umgebung</label>
            <div style="display:flex;gap:var(--space-2)">
              ${[['🏠','zuhause'],['🌿','natur'],['🌆','stadt']].map(([emoji,val]) => `
                <button type="button" class="notes-umgebung" data-val="${val}"
                        style="font-size:1.2rem;border:1.5px solid var(--c-border);border-radius:var(--radius-md);
                               padding:3px 10px;cursor:pointer;
                               background:${meta.umgebung===val?'var(--c-primary-subtle)':'var(--c-surface-2)'};
                               border-color:${meta.umgebung===val?'var(--c-primary)':'var(--c-border)'}">${emoji}</button>
              `).join('')}
            </div>
          </div>

          <!-- Stimmung -->
          <div>
            <label style="display:block;font-size:var(--text-sm);font-weight:var(--weight-semibold);
                          color:var(--c-text);margin-bottom:var(--space-2)">Stimmung des Hundes</label>
            <div style="display:flex;gap:var(--space-2)">
              ${[['😊','super'],['😐','ok'],['😔','mude']].map(([emoji,val]) => `
                <button type="button" class="notes-stimmung" data-val="${val}"
                        style="font-size:1.2rem;border:1.5px solid var(--c-border);border-radius:var(--radius-md);
                               padding:3px 10px;cursor:pointer;
                               background:${meta.hund_stimmung===val?'var(--c-primary-subtle)':'var(--c-surface-2)'};
                               border-color:${meta.hund_stimmung===val?'var(--c-primary)':'var(--c-border)'}">${emoji}</button>
              `).join('')}
            </div>
          </div>
          ` : ''}

        </div>

        <!-- Buttons -->
        <div style="display:flex;gap:var(--space-3);margin-top:var(--space-5)">
          <button id="notes-edit-delete" type="button"
                  style="padding:var(--space-3) var(--space-4);border-radius:var(--radius-md);
                         border:1.5px solid var(--c-danger);background:none;
                         color:var(--c-danger);font-size:var(--text-sm);cursor:pointer">
            Löschen
          </button>
          <button id="notes-edit-cancel" type="button"
                  style="flex:1;padding:var(--space-3);border-radius:var(--radius-md);
                         border:1.5px solid var(--c-border);background:none;
                         color:var(--c-text-secondary);font-size:var(--text-sm);cursor:pointer">
            Abbrechen
          </button>
          <button id="notes-edit-save" type="button"
                  style="flex:2;padding:var(--space-3);border-radius:var(--radius-md);
                         border:none;background:var(--c-primary);
                         color:#fff;font-size:var(--text-sm);font-weight:var(--weight-semibold);cursor:pointer">
            Speichern
          </button>
        </div>
      </div>
    `;

    document.body.appendChild(overlay);

    let selErfolgsquote = meta.erfolgsquote || null;
    let selUmgebung     = meta.umgebung || null;
    let selStimmung     = meta.hund_stimmung || null;

    function _toggleBtn(group, val, getter, setter) {
      overlay.querySelectorAll(`.notes-${group}`).forEach(b => {
        const match = (group === 'pfote')
          ? parseInt(b.dataset.val, 10) === val
          : b.dataset.val === val;
        b.style.background  = match ? 'var(--c-primary-subtle)' : 'var(--c-surface-2)';
        b.style.borderColor = match ? 'var(--c-primary)'        : 'var(--c-border)';
      });
    }

    overlay.querySelectorAll('.notes-pfote').forEach(btn => {
      btn.addEventListener('click', () => {
        const v = parseInt(btn.dataset.val, 10);
        selErfolgsquote = selErfolgsquote === v ? null : v;
        _toggleBtn('pfote', selErfolgsquote, null, null);
      });
    });

    overlay.querySelectorAll('.notes-umgebung').forEach(btn => {
      btn.addEventListener('click', () => {
        selUmgebung = selUmgebung === btn.dataset.val ? null : btn.dataset.val;
        _toggleBtn('umgebung', selUmgebung, null, null);
      });
    });

    overlay.querySelectorAll('.notes-stimmung').forEach(btn => {
      btn.addEventListener('click', () => {
        selStimmung = selStimmung === btn.dataset.val ? null : btn.dataset.val;
        _toggleBtn('stimmung', selStimmung, null, null);
      });
    });

    function _close() { overlay.remove(); }
    overlay.addEventListener('click', e => { if (e.target === overlay) _close(); });
    overlay.querySelector('#notes-edit-cancel').addEventListener('click', _close);

    // Speichern
    overlay.querySelector('#notes-edit-save').addEventListener('click', async () => {
      const text = overlay.querySelector('#notes-edit-text').value.trim();
      if (!text) { UI.toast.warning('Notiz darf nicht leer sein.'); return; }

      const saveBtn = overlay.querySelector('#notes-edit-save');
      saveBtn.disabled = true;
      saveBtn.textContent = 'Speichern…';

      const metaObj = {};
      if (selErfolgsquote) metaObj.erfolgsquote = selErfolgsquote;
      if (selUmgebung)     metaObj.umgebung      = selUmgebung;
      if (selStimmung)     metaObj.hund_stimmung = selStimmung;

      try {
        const updated = await API.notes.update(note.id, {
          text,
          meta_json: Object.keys(metaObj).length > 0 ? metaObj : null,
        });
        const idx = _notes.findIndex(n => n.id === note.id);
        if (idx >= 0) _notes[idx] = updated;
        _render();
        _close();
        UI.toast.success('Notiz aktualisiert.');
      } catch (_) {
        saveBtn.disabled = false;
        saveBtn.textContent = 'Speichern';
        UI.toast.error('Speichern fehlgeschlagen.');
      }
    });

    // Löschen
    overlay.querySelector('#notes-edit-delete').addEventListener('click', async () => {
      if (!window.confirm('Notiz wirklich löschen?')) return;
      try {
        await API.notes.delete(note.id);
        _notes = _notes.filter(n => n.id !== note.id);
        _render();
        _close();
        UI.toast.success('Notiz gelöscht.');
      } catch (_) {
        UI.toast.error('Löschen fehlgeschlagen.');
      }
    });
  }

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

    // Zustand zurücksetzen
    _filterType    = '';
    _sortMode      = 'newest';
    _searchQ       = '';
    _kiOpen        = false;
    _kiLoading     = false;
    _kiSuggestions = null;
    _kiError       = null;
    _notes         = [];

    _container.innerHTML = UI.skeleton(3);

    try {
      _notes = await _load();
    } catch (_) {
      _notes = [];
    }

    _render();
  }

  async function refresh() {
    if (!_container) return;
    _container.innerHTML = UI.skeleton(3);
    try {
      _notes = await _load();
    } catch (_) {
      _notes = [];
    }
    _render();
  }

  return { init, refresh };

})();
