/* ============================================================
   BAN YARO — Trainingspläne
   Seiten-Modul: Welpe, Junior, Erwachsener Hund
   Alle Inhalte hardcoded, Checkboxen via localStorage
   ============================================================ */

window.Page_trainingsplaene = (() => {

  let _container = null;
  let _appState  = null;
  let _activePlan = 'welpe'; // welpe | junior | erwachsen
  let _activeAdultTab = 'grundkurs'; // grundkurs | aufbaukurs

  // ----------------------------------------------------------
  // API HELPERS
  // ----------------------------------------------------------
  function _dogId() {
    return _appState?.activeDog?.id || null;
  }

  async function _apiGet(url) {
    const r = await fetch(url, {credentials: 'include'});
    return r.ok ? r.json() : null;
  }

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

  function _icon(name) {
    return `<svg class="ph-icon" aria-hidden="true" style="width:1em;height:1em;vertical-align:-0.15em"><use href="/icons/phosphor.svg#${name}"></use></svg>`;
  }

  function _lsKey(planId, goalIdx) {
    return `tp_${planId}_${goalIdx}`;
  }

  function _saveGoal(key, checked) {
    localStorage.setItem(key, checked ? 'true' : 'false');
  }

  function _loadGoal(key) {
    return localStorage.getItem(key) === 'true';
  }

  // ----------------------------------------------------------
  // RENDER HELPERS
  // ----------------------------------------------------------

  function _renderTable(headers, rows) {
    const ths = headers.map(h => `<th style="padding:6px 10px;background:var(--c-surface-2);font-weight:var(--weight-semibold);font-size:var(--text-sm);white-space:nowrap">${_esc(h)}</th>`).join('');
    const trs = rows.map(row => {
      const tds = row.map((cell, i) => `<td style="padding:6px 10px;font-size:var(--text-sm);color:var(--c-text);border-top:1px solid var(--c-border);${i === 0 ? 'white-space:nowrap;font-weight:var(--weight-semibold)' : ''}">${_esc(cell)}</td>`).join('');
      return `<tr>${tds}</tr>`;
    }).join('');
    return `
      <div style="overflow-x:auto;margin:var(--space-3) 0">
        <table style="width:100%;border-collapse:collapse;min-width:400px">
          <thead><tr>${ths}</tr></thead>
          <tbody>${trs}</tbody>
        </table>
      </div>`;
  }

  function _renderGoals(planId, goals) {
    const total = goals.length;
    let doneCount = 0;
    const items = goals.map((goal, idx) => {
      const key = _lsKey(planId, idx);
      const checked = _loadGoal(key);
      if (checked) doneCount++;
      return `
        <label style="display:flex;align-items:flex-start;gap:var(--space-2);cursor:pointer;padding:var(--space-1) 0" class="tp-goal-label">
          <input type="checkbox" data-lskey="${_esc(key)}" ${checked ? 'checked' : ''}
                 style="margin-top:2px;flex-shrink:0;accent-color:var(--c-primary);width:16px;height:16px">
          <span style="font-size:var(--text-sm);color:var(--c-text);line-height:1.5">${_esc(goal)}</span>
        </label>`;
    }).join('');

    const progress = total > 0 ? Math.round((doneCount / total) * 100) : 0;
    return `
      <div class="tp-goals" data-plan="${_esc(planId)}" data-total="${total}">
        <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--space-2)">
          <span style="font-size:var(--text-sm);font-weight:var(--weight-semibold);color:var(--c-text-secondary)">
            ${_icon('check-circle')} Lernziele
          </span>
          <span class="tp-progress-label" style="font-size:var(--text-xs);color:var(--c-text-secondary)">
            ${doneCount} von ${total} erreicht
          </span>
        </div>
        <div style="background:var(--c-surface-2);border-radius:4px;height:6px;overflow:hidden;margin-bottom:var(--space-3)">
          <div class="tp-progress-bar" style="width:${progress}%;height:6px;background:var(--c-primary);border-radius:4px;transition:width 0.3s"></div>
        </div>
        ${items}
      </div>`;
  }

  function _renderAccordionPhase(id, title, content) {
    return `
      <div class="tp-acc" id="tp-acc-${_esc(id)}">
        <button class="tp-acc-head" data-acc="${_esc(id)}"
                style="width:100%;display:flex;justify-content:space-between;align-items:center;padding:var(--space-3) var(--space-4);background:none;border:none;border-top:1px solid var(--c-border);cursor:pointer;text-align:left">
          <span style="font-weight:var(--weight-semibold);color:var(--c-text)">${title}</span>
          <span class="tp-acc-arrow">${_icon('caret-down')}</span>
        </button>
        <div class="tp-acc-body" id="tp-acc-body-${_esc(id)}" hidden
             style="padding:var(--space-3) var(--space-4) var(--space-4)">
          ${content}
        </div>
      </div>`;
  }

  function _renderHintBox(text) {
    return `
      <div style="background:var(--c-surface-2);border-left:3px solid var(--c-primary);border-radius:var(--radius-sm);padding:var(--space-3) var(--space-4);margin:var(--space-3) 0;font-size:var(--text-sm);color:var(--c-text);line-height:1.6">
        ${_icon('info')} ${_esc(text)}
      </div>`;
  }

  // ----------------------------------------------------------
  // PLAN SELECTOR
  // ----------------------------------------------------------
  function _renderPlanSelector() {
    const plans = [
      { id: 'welpe',    label: 'Welpe',           icon: 'dog', sub: '0–6 Monate' },
      { id: 'junior',   label: 'Junior',           icon: 'dog', sub: '6–18 Monate' },
      { id: 'erwachsen',label: 'Erwachsener Hund', icon: 'dog', sub: 'Grund- & Aufbaukurs' },
    ];
    const btns = plans.map(p => `
      <button class="by-tab${_activePlan === p.id ? ' active' : ''}" data-plan="${p.id}"
              style="flex:1;min-width:90px;display:flex;flex-direction:column;align-items:center;
                     justify-content:center;gap:2px;white-space:normal;text-align:center;line-height:1.2">
        <svg class="ph-icon" aria-hidden="true" style="width:22px;height:22px"><use href="/icons/phosphor.svg#${p.icon}"></use></svg>
        <span style="font-size:var(--text-sm);font-weight:600">${p.label}</span>
        <span style="font-size:var(--text-xs);opacity:0.8">${_esc(p.sub)}</span>
      </button>`).join('');
    return `<div style="display:flex;gap:var(--space-2);margin-bottom:var(--space-4);flex-wrap:wrap">${btns}</div>`;
  }

  // ----------------------------------------------------------
  // WELPENPLAN
  // ----------------------------------------------------------
  function _renderWelpe() {
    const intro = `
      <p style="color:var(--c-text);line-height:1.6;margin-bottom:var(--space-2)">
        <strong>Voraussetzungen:</strong> Welpe ist eingezogen, Grundvertrauen wird aufgebaut.<br>
        <strong>Ziel am Ende:</strong> Sitz, Platz, Hier, Warte, Leine ohne Ziehen, Alleine bleiben bis 1 Stunde, keine Begrüßungssprünge.
      </p>
      ${_renderHintBox('Welpen sind schnell überfordert. Lieber 3×5 Minuten täglich als einmal 20 Minuten. Sozialisation (Menschen, Geräusche, Orte) hat in dieser Phase genauso Priorität wie Training.')}`;

    const w12 = `
      <p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin-bottom:var(--space-2)"><strong>Fokus:</strong> Name, erste Bindung, Stubenreinheit, keine Übungen erzwingen.</p>
      ${_renderTable(
        ['Tag', 'Einheit 1', 'Einheit 2', 'Einheit 3'],
        [['Mo–So', 'Name lernen', 'Markerwort einführen', 'Freies Erkunden + Beobachten']]
      )}
      <ul style="font-size:var(--text-sm);color:var(--c-text);line-height:1.6;padding-left:var(--space-4);margin:var(--space-2) 0">
        <li><strong>Name lernen:</strong> Namen sagen → Hund schaut → sofort Markerwort + Leckerli. 10–15× täglich.</li>
        <li><strong>Markerwort einführen:</strong> Markerwort sagen → sofort Leckerli (10× wiederholen). Ab jetzt: Markerwort immer vor dem Leckerli.</li>
        <li><strong>Stubenreinheit:</strong> Alle 1–2 Stunden raus, nach Schlafen/Fressen/Spielen. Kein Schimpfen bei Unfällen.</li>
      </ul>`;

    const w34 = `
      <p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin-bottom:var(--space-2)"><strong>Fokus:</strong> Sitz, Warte (Futter), Nicht springen.</p>
      ${_renderTable(
        ['Tag', 'Einheit 1', 'Einheit 2', 'Einheit 3'],
        [
          ['Mo', 'Sitz einführen', 'Sitz wiederholen', 'Warte vor Futter'],
          ['Di', 'Sitz mit Handsignal', 'Nicht springen üben', 'Sitz aus verschiedenen Positionen'],
          ['Mi', 'Warte vor Futter', 'Sitz 5×', 'Freispiel + Name'],
          ['Do', 'Sitz festigen', 'Warte 5×', 'Nicht springen'],
          ['Fr', 'Sitz + Warte kombiniert', 'Freispiel', 'Leckerli-Suche im Gras'],
          ['Sa', 'Wiederholung Woche', 'Spaziergang mit Leine (ohne Ziel)', 'Entspannen auf Decke'],
          ['So', 'Ruhiger Tag', 'Kurze Sitz-Einheit', 'Sozialisation (Geräusche, Menschen)'],
        ]
      )}
      ${_renderGoals('welpe_w34', [
        'Sitz auf Handsignal (ohne Wort)',
        'Sitz auf Wort "Sitz"',
        'Wartet vor der Futterschüssel bis "Okay"',
        'Springt nicht mehr bei Begrüßung (in Übung)',
      ])}`;

    const w56 = `
      <p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin-bottom:var(--space-2)"><strong>Fokus:</strong> Platz, Leinengewöhnung, Hier auf kurze Distanz.</p>
      ${_renderTable(
        ['Tag', 'Einheit 1', 'Einheit 2', 'Einheit 3'],
        [
          ['Mo', 'Platz einführen', 'Sitz wiederholen', 'Leine anlegen + Leckerli'],
          ['Di', 'Platz üben', 'Hier (2 Meter, innen)', 'Leine: erste Schritte'],
          ['Mi', 'Platz festigen', 'Sitz + Platz abwechselnd', 'Hier aus anderem Zimmer'],
          ['Do', 'Leine im Garten', 'Hier mit Freude', 'Platz 5×'],
          ['Fr', 'Sitz + Platz + Hier kombiniert', 'Spaziergang kurz', 'Nasenarbeit (Leckerli unter Becher)'],
          ['Sa', 'Wiederholungstag', 'Sozialisation (Markt, Park)', 'Freispiel'],
          ['So', 'Ruhiger Tag', 'Kurze Einheit nach Wahl', 'Entspannen'],
        ]
      )}
      ${_renderGoals('welpe_w56', [
        'Platz auf Handsignal',
        'Platz auf Wort "Platz"',
        'Kommt auf "Hier" aus 3 Metern',
        'Läuft 5 Schritte an lockerer Leine',
      ])}`;

    const w78 = `
      <p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin-bottom:var(--space-2)"><strong>Fokus:</strong> Bleib (Dauer), Alleine bleiben aufbauen, Fuß vorbereiten.</p>
      ${_renderTable(
        ['Tag', 'Einheit 1', 'Einheit 2', 'Einheit 3'],
        [
          ['Mo', 'Bleib einführen (5 Sek)', 'Alleine bleiben (30 Sek)', 'Sitz + Platz Wiederholung'],
          ['Di', 'Bleib (10 Sek)', 'Alleine bleiben (1 Min)', 'Fuß: erste Schritte'],
          ['Mi', 'Bleib mit 1 Schritt Distanz', 'Hier aus Garten', 'Nasenarbeit'],
          ['Do', 'Bleib (20 Sek)', 'Alleine bleiben (2 Min)', 'Leine üben'],
          ['Fr', 'Sitz + Bleib + Hier kombiniert', 'Fuß 10 Schritte', 'Freispiel'],
          ['Sa', 'Ausflug (neue Umgebung)', 'Kurze Übungen unterwegs', 'Sozialisation'],
          ['So', 'Ruhiger Tag', 'Wiederholung nach Wahl', 'Entspannen'],
        ]
      )}
      ${_renderGoals('welpe_w78', [
        'Bleibt 30 Sekunden im Sitz',
        'Bleibt alleine bis 5 Minuten ohne Stress',
        'Kommt zuverlässig auf "Hier" (innen + Garten)',
        'Fuß: 10 Schritte an lockerer Leine',
      ])}`;

    const w912 = `
      <p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin-bottom:var(--space-2)"><strong>Fokus:</strong> Alle Kommandos in Alltagssituationen, erste leichte Ablenkungen.</p>
      ${_renderTable(
        ['Woche', 'Schwerpunkt'],
        [
          ['9', 'Alle Kommandos im Garten mit leichter Ablenkung'],
          ['10', 'Sitz + Bleib auf der Straße, Fuß auf kurzen Spaziergängen'],
          ['11', 'Hier mit Schleppleine im Park, Alleine bleiben bis 30 Min'],
          ['12', 'Wiederholung + erste Tricks (Pfote, Dreh)'],
        ]
      )}
      ${_renderGoals('welpe_w912', [
        'Alle Grundkommandos auf Wort und Handsignal',
        'Bleibt alleine bis 1 Stunde ohne Stress',
        'Kommt zuverlässig auf "Hier" im Garten',
        'Läuft entspannt an der Leine in ruhiger Umgebung',
        'Erster Trick gelernt (Pfote oder Dreh)',
      ])}`;

    return `
      ${intro}
      <div class="card" style="padding:0;overflow:hidden">
        ${_renderAccordionPhase('welpe-w12', 'Woche 1–2: Ankommen &amp; Vertrauen', w12)}
        ${_renderAccordionPhase('welpe-w34', 'Woche 3–4: Erste Kommandos', w34)}
        ${_renderAccordionPhase('welpe-w56', 'Woche 5–6: Platz &amp; erste Leine', w56)}
        ${_renderAccordionPhase('welpe-w78', 'Woche 7–8: Bleib &amp; Alleine bleiben', w78)}
        ${_renderAccordionPhase('welpe-w912', 'Woche 9–12: Festigung &amp; Alltagsintegration', w912)}
      </div>`;
  }

  // ----------------------------------------------------------
  // JUNIORPLAN
  // ----------------------------------------------------------
  function _renderJunior() {
    const intro = `
      <p style="color:var(--c-text);line-height:1.6;margin-bottom:var(--space-2)">
        <strong>Voraussetzungen:</strong> Grundkommandos bekannt, aber pubertätsbedingt unzuverlässig.<br>
        <strong>Ziel am Ende:</strong> Alle Grundkommandos auch bei Ablenkung, zuverlässiger Rückruf, Leinenführigkeit in der Stadt.
      </p>
      ${_renderHintBox('Die Pubertät (ca. 6–12 Monate) ist normal. Der Hund "vergisst" scheinbar alles — er testet Grenzen und Reize sind überwältigend. Konsequenz und Geduld, kein Rückschritt im Denken.')}`;

    const m1 = `
      <p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin-bottom:var(--space-2)"><strong>Fokus:</strong> Alle bekannten Kommandos mit höherer Ablenkung neu festigen.</p>
      ${_renderTable(
        ['Tag', 'Einheit 1 (5 Min)', 'Einheit 2 (5–10 Min)'],
        [
          ['Mo', 'Sitz + Platz mit Ablenkung (Ball auf dem Boden)', 'Leine üben in neuer Umgebung'],
          ['Di', 'Hier mit Schleppleine im Park', 'Bleib mit Distanz (3–5 Meter)'],
          ['Mi', 'Fuß auf belebtem Gehweg', 'Nasenarbeit / Trick'],
          ['Do', 'Aus + Warte kombiniert', 'Alleine bleiben (bis 2 Stunden)'],
          ['Fr', 'Alle Kommandos — kurze Runde', 'Freispiel'],
          ['Sa', 'Ausflug + Training in neuer Umgebung', 'Sozialisation'],
          ['So', 'Ruhiger Tag — leichte Einheit', 'Entspannen'],
        ]
      )}
      ${_renderGoals('junior_m1', [
        'Sitz + Platz trotz Ball/anderen Hunden in der Nähe',
        'Bleibt 1 Minute mit 5 Metern Distanz',
        'Kommt auf "Hier" im Park (mit Schleppleine)',
        'Fuß auf 50 Meter in ruhiger Straße',
      ])}`;

    const m2 = `
      <p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin-bottom:var(--space-2)"><strong>Fokus:</strong> Zuverlässiger Rückruf — das wichtigste Kommando in dieser Phase.</p>
      <ol style="font-size:var(--text-sm);color:var(--c-text);line-height:1.7;padding-left:var(--space-5);margin:var(--space-2) 0">
        <li><strong>Rückruf mit Schleppleine (10 Meter):</strong> Hund beschäftigt sich → "Hier!" → leichtes Anziehen wenn nötig → große Belohnung beim Ankommen</li>
        <li><strong>Versteckspiel:</strong> Im Wald/Park verstecken → "Hier!" rufen → Hund sucht und findet → größte Belohnung</li>
        <li><strong>Rückruf aus der Gruppe:</strong> Hund spielt mit anderen Hunden → "Hier!" → kommt er: Jackpot (5 Leckerlis + Streicheln)</li>
        <li><strong>Notfallrückruf einführen:</strong> Anderes Wort (z.B. "Rapid!") nur für echte Notfälle — immer mit höchster Belohnung</li>
      </ol>
      ${_renderGoals('junior_m2', [
        'Kommt auf "Hier" aus 20 Metern mit Schleppleine',
        'Kommt aus Spielsituation mit anderen Hunden zurück',
        'Notfallrückruf eingeführt',
      ])}`;

    const m3 = `
      <p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin-bottom:var(--space-2)"><strong>Fokus:</strong> Ruhiges Gehen auch bei Fahrrädern, anderen Hunden, Kinderwagen.</p>
      <ol style="font-size:var(--text-sm);color:var(--c-text);line-height:1.7;padding-left:var(--space-5);margin:var(--space-2) 0">
        <li>Ruhige Straße → belohnen alle 10 Schritte bei locker hängender Leine</li>
        <li>Fahrrad kommt entgegen → Sitz → warten → Fahrrad vorbei → weitergehen + Leckerli</li>
        <li>Anderer Hund in Sichtweite → Fokus auf dich (Augenkontakt trainieren) → Leckerli</li>
        <li>Belebte Fußgängerzone: erst beobachten lassen, dann durch</li>
      </ol>
      <p style="font-size:var(--text-sm);color:var(--c-text);margin:var(--space-2) 0"><strong>Augenkontakt:</strong> "Schau" sagen → Hund schaut in deine Augen → sofort Markerwort + Leckerli. In Ablenkungssituationen: "Schau" → fokussiert → dann erst weitergehen.</p>
      ${_renderGoals('junior_m3', [
        'Läuft 500 Meter an lockerer Leine in der Stadt',
        'Bleibt bei Ablenkung (Fahrrad, Jogger) fokussiert',
        'Augenkontakt auf Kommando "Schau"',
      ])}`;

    const m46 = `
      <p style="font-size:var(--text-sm);color:var(--c-text-secondary);margin-bottom:var(--space-2)"><strong>Fokus:</strong> Festigung aller Kommandos, erste Aufbauübungen, Tricks für mentale Auslastung.</p>
      ${_renderTable(
        ['Monat', 'Schwerpunkt'],
        [
          ['4', 'Bleib auf Distanz (10 Meter), Freifolge (ohne Leine in sicherer Umgebung)'],
          ['5', 'Platz auf Distanz, Hier vom Freilauf, Trick-Erweiterung (Decke, Suchspiel)'],
          ['6', 'Alle Kommandos zuverlässig, erstes Hundesport-Schnuppern optional'],
        ]
      )}
      ${_renderGoals('junior_m46', [
        'Alle Grundkommandos bei mittlerer Ablenkung',
        'Freifolge auf kurze Distanz (eingezäuntes Gelände)',
        '2–3 Tricks beherrscht',
        'Rückruf vom Freilauf (Schleppleine)',
      ])}`;

    return `
      ${intro}
      <div class="card" style="padding:0;overflow:hidden">
        ${_renderAccordionPhase('junior-m1', 'Monat 1: Grundkommandos neu aufbauen', m1)}
        ${_renderAccordionPhase('junior-m2', 'Monat 2: Rückruf vertiefen', m2)}
        ${_renderAccordionPhase('junior-m3', 'Monat 3: Leinenführigkeit in der Stadt', m3)}
        ${_renderAccordionPhase('junior-m46', 'Monat 4–6: Aufbau &amp; Tricks', m46)}
      </div>`;
  }

  // ----------------------------------------------------------
  // ERWACHSENER HUND
  // ----------------------------------------------------------
  function _renderErwachsenTabs() {
    return `
      <div class="by-tabs" style="margin-bottom:var(--space-4)">
        <button class="by-tab${_activeAdultTab === 'grundkurs'  ? ' active' : ''}" data-tab="grundkurs">Grundkurs</button>
        <button class="by-tab${_activeAdultTab === 'aufbaukurs' ? ' active' : ''}" data-tab="aufbaukurs">Aufbaukurs</button>
        <button class="by-tab${_activeAdultTab === 'uebersicht' ? ' active' : ''}" data-tab="uebersicht">Übersicht</button>
      </div>`;
  }

  function _renderGrundkurs() {
    const intro = `
      <p style="color:var(--c-text);line-height:1.6;margin-bottom:var(--space-2)">
        <strong>Voraussetzungen:</strong> Keine oder wenige Vorkenntnisse.<br>
        <strong>Ziel:</strong> Alle Grundkommandos in 8 Wochen.
      </p>
      ${_renderHintBox('Erwachsene Hunde lernen genauso gut wie Welpen — oft sogar konzentrierter. Alte Gewohnheiten brauchen länger zum Überschreiben, aber mit konsequentem Training klappt es.')}`;

    const gw12 = `
      ${_renderTable(
        ['Tag', 'Einheit 1', 'Einheit 2'],
        [
          ['Mo', 'Markerwort einführen', 'Sitz einführen'],
          ['Di', 'Sitz festigen', 'Warte vor Futter'],
          ['Mi', 'Sitz aus Bewegung', 'Markerwort in Alltagssituationen'],
          ['Do', 'Sitz + Warte kombiniert', 'Leine: erste Einschätzung'],
          ['Fr', 'Wiederholung', 'Freispiel'],
          ['Sa/So', 'Alltagsintegration', 'Kurze Einheit'],
        ]
      )}`;

    const gw34 = `
      ${_renderTable(
        ['Tag', 'Einheit 1', 'Einheit 2'],
        [
          ['Mo', 'Platz einführen', 'Hier (Wohnung, 3 Meter)'],
          ['Di', 'Platz festigen', 'Leinenführigkeit einschätzen + üben'],
          ['Mi', 'Sitz + Platz abwechselnd', 'Hier aus anderem Zimmer'],
          ['Do', 'Hier im Garten', 'Fuß vorbereiten'],
          ['Fr', 'Leine 10 Minuten üben', 'Platz + Hier kombiniert'],
          ['Sa/So', 'Spaziergang mit Training', 'Nasenarbeit'],
        ]
      )}`;

    const gw56 = `
      ${_renderTable(
        ['Tag', 'Einheit 1', 'Einheit 2'],
        [
          ['Mo', 'Bleib einführen (10 Sek)', 'Fuß einführen'],
          ['Di', 'Bleib (30 Sek, 1 Schritt)', 'Aus einführen'],
          ['Mi', 'Fuß 20 Schritte', 'Bleib mit Distanz'],
          ['Do', 'Aus mit Spielzeug', 'Fuß in der Straße'],
          ['Fr', 'Alle Kommandos kombiniert', 'Trick nach Wahl'],
          ['Sa/So', 'Ausflug mit Training', 'Sozialisation'],
        ]
      )}`;

    const gw78 = `
      <p style="font-size:var(--text-sm);color:var(--c-text);line-height:1.6;margin-bottom:var(--space-2)">Alle Kommandos in Alltagssituationen:</p>
      <ul style="font-size:var(--text-sm);color:var(--c-text);line-height:1.7;padding-left:var(--space-4);margin:0 0 var(--space-3)">
        <li>Sitz vor dem Überqueren der Straße</li>
        <li>Platz wenn Besuch kommt</li>
        <li>Warte vor der Haustür</li>
        <li>Hier beim Freilauf im Garten</li>
        <li>Fuß auf dem Bürgersteig</li>
        <li>Aus bei gefundenem Gegenstand</li>
      </ul>
      ${_renderGoals('erwachsen_gk', [
        'Sitz, Platz, Bleib (30 Sek), Hier, Fuß, Aus, Warte',
        'Alle Kommandos im Alltag einsetzbar',
        'Leine ohne starkes Ziehen',
      ])}`;

    return `
      ${intro}
      <div class="card" style="padding:0;overflow:hidden">
        ${_renderAccordionPhase('gk-w12', 'Woche 1–2: Markerwort + Sitz + Warte', gw12)}
        ${_renderAccordionPhase('gk-w34', 'Woche 3–4: Platz + Hier + Leine', gw34)}
        ${_renderAccordionPhase('gk-w56', 'Woche 5–6: Bleib + Fuß + Aus', gw56)}
        ${_renderAccordionPhase('gk-w78', 'Woche 7–8: Festigung + Alltagsintegration', gw78)}
      </div>`;
  }

  function _renderAufbaukurs() {
    const intro = `
      <p style="color:var(--c-text);line-height:1.6;margin-bottom:var(--space-2)">
        <strong>Voraussetzungen:</strong> Grundkurs abgeschlossen oder Kommandos bekannt.<br>
        <strong>Dauer:</strong> 8 Wochen &nbsp;|&nbsp; <strong>Ziel:</strong> Kommandos bei Ablenkung, Distanzkommandos, Tricks, mentale Auslastung.
      </p>`;

    const aw12 = `
      <p style="font-size:var(--text-sm);color:var(--c-text);margin-bottom:var(--space-2)">Alle bekannten Kommandos werden mit steigender Ablenkung trainiert. Immer bei der niedrigsten Stufe anfangen die noch klappt.</p>
      ${_renderTable(
        ['Ablenkungsstufe', 'Beispiele'],
        [
          ['Stufe 1', 'Leckerli auf dem Boden, Ball in Sichtweite'],
          ['Stufe 2', 'Anderer Mensch im Raum, Geräusche'],
          ['Stufe 3', 'Anderer Hund in Sichtweite'],
          ['Stufe 4', 'Belebter Park, Straße'],
          ['Stufe 5', 'Freilauf, Spielsituation unterbrechen'],
        ]
      )}`;

    const aw34 = `
      <ul style="font-size:var(--text-sm);color:var(--c-text);line-height:1.7;padding-left:var(--space-4);margin:0 0 var(--space-3)">
        <li>Sitz aus 5 Metern → 10 Metern</li>
        <li>Platz aus 5 Metern → 10 Metern</li>
        <li>Bleib mit 10 Metern Distanz</li>
        <li>Hier vom Freilauf (mit Schleppleine absichern)</li>
      </ul>
      <p style="font-size:var(--text-sm);color:var(--c-text);line-height:1.6"><strong>Übung "Fernbedienung":</strong> Hund steht 5 Meter entfernt → "Sitz" → kurz warten → "Platz" → kurz warten → "Sitz" → "Hier". Wirkt beeindruckend, festigt Kommandos enorm.</p>`;

    const aw56 = `
      ${_renderTable(
        ['Woche', 'Trick', 'Nasenarbeit'],
        [
          ['5', 'Pfote + Dreh', 'Leckerli unter 3 Bechern suchen'],
          ['6', 'Decke/Matte', 'Leckerli im Gras suchen, Gegenstand apportieren'],
        ]
      )}`;

    const aw78 = `
      <ul style="font-size:var(--text-sm);color:var(--c-text);line-height:1.7;padding-left:var(--space-4);margin:0 0 var(--space-3)">
        <li>Schwächstes Kommando intensiv üben</li>
        <li>Neue Umgebungen aufsuchen (anderer Wald, andere Stadt)</li>
        <li>Hundesport ausprobieren: Agility, Mantrailing, Obedience, Trickdogging</li>
      </ul>
      ${_renderGoals('erwachsen_ak', [
        'Alle Kommandos bei Stufe 3–4 Ablenkung',
        'Sitz + Platz auf 10 Meter Distanz',
        'Hier vom Freilauf (Schleppleine)',
        '3–4 Tricks',
        'Nasenarbeit als regelmäßige Beschäftigung',
      ])}`;

    return `
      ${intro}
      <div class="card" style="padding:0;overflow:hidden">
        ${_renderAccordionPhase('ak-w12', 'Woche 1–2: Ablenkungstraining', aw12)}
        ${_renderAccordionPhase('ak-w34', 'Woche 3–4: Distanzkommandos', aw34)}
        ${_renderAccordionPhase('ak-w56', 'Woche 5–6: Tricks &amp; Nasenarbeit', aw56)}
        ${_renderAccordionPhase('ak-w78', 'Woche 7–8: Freie Gestaltung', aw78)}
      </div>`;
  }

  function _renderUebersicht() {
    return `
      <h3 style="font-size:var(--text-base);font-weight:var(--weight-semibold);margin-bottom:var(--space-3);color:var(--c-text)">
        ${_icon('clipboard-text')} Welcher Plan für welchen Hund?
      </h3>
      ${_renderTable(
        ['Situation', 'Empfohlener Plan'],
        [
          ['Neuer Welpe (8–16 Wochen)', 'Welpenplan Woche 1–4'],
          ['Welpe 4–6 Monate', 'Welpenplan Woche 5–12'],
          ['Junghund 6–12 Monate (Pubertät)', 'Juniorplan Monat 1–3'],
          ['Junghund 12–18 Monate', 'Juniorplan Monat 4–6'],
          ['Erwachsener Hund ohne Training', 'Grundkurs Erwachsener'],
          ['Erwachsener Hund mit Grundwissen', 'Aufbaukurs Erwachsener'],
          ['Neu eingezogener Hund (unbekannte Vorgeschichte)', 'Grundkurs Erwachsener, Tempo anpassen'],
        ]
      )}`;
  }

  function _renderErwachsen() {
    const intro = `
      <p style="color:var(--c-text);line-height:1.6;margin-bottom:var(--space-3)">
        Wähle deinen Kurs oder sieh dir die Schnellübersicht an.
      </p>`;

    let content = '';
    if (_activeAdultTab === 'grundkurs') {
      content = _renderGrundkurs();
    } else if (_activeAdultTab === 'aufbaukurs') {
      content = _renderAufbaukurs();
    } else {
      content = `<div class="card">${_renderUebersicht()}</div>`;
    }

    return `${intro}${_renderErwachsenTabs()}${content}`;
  }

  // ----------------------------------------------------------
  // BIND EVENTS
  // ----------------------------------------------------------
  function _bindEvents() {
    // Notiz-Button
    const dogId = _dogId();
    _container.querySelector('#tp-note-btn')?.addEventListener('click', e => {
      e.stopPropagation();
      const planLabel = _activePlan === 'welpe' ? 'Welpe 0–6 Monate'
                      : _activePlan === 'junior' ? 'Junior 6–18 Monate'
                      : `Erwachsener Hund – ${_activeAdultTab}`;
      _openNoteModal('trainingsplan', dogId, planLabel, null);
    });

    // Plan selector
    _container.querySelectorAll('[data-plan]').forEach(btn => {
      btn.addEventListener('click', () => {
        _activePlan = btn.dataset.plan;
        _render();
      });
    });

    // Adult sub-tabs
    _container.querySelectorAll('[data-tab]').forEach(btn => {
      btn.addEventListener('click', () => {
        _activeAdultTab = btn.dataset.tab;
        _render();
      });
    });

    // Accordion
    _container.querySelectorAll('.tp-acc-head').forEach(btn => {
      btn.addEventListener('click', () => {
        const id   = btn.dataset.acc;
        const body = document.getElementById(`tp-acc-body-${id}`);
        const arrow = btn.querySelector('.tp-acc-arrow');
        if (!body) return;
        const isOpen = !body.hidden;
        body.hidden = isOpen;
        arrow.innerHTML = isOpen ? _icon('caret-down') : _icon('caret-up');
      });
    });

    // Checkboxes
    _container.querySelectorAll('input[data-lskey]').forEach(cb => {
      cb.addEventListener('change', () => {
        const key = cb.dataset.lskey;
        _saveGoal(key, cb.checked);
        _updateProgress(cb);
      });
    });
  }

  function _updateProgress(cb) {
    const goalsEl = cb.closest('.tp-goals');
    if (!goalsEl) return;
    const total = parseInt(goalsEl.dataset.total, 10) || 0;
    const done  = goalsEl.querySelectorAll('input[type=checkbox]:checked').length;
    const label = goalsEl.querySelector('.tp-progress-label');
    const bar   = goalsEl.querySelector('.tp-progress-bar');
    if (label) label.textContent = `${done} von ${total} erreicht`;
    if (bar)   bar.style.width   = total > 0 ? `${Math.round((done / total) * 100)}%` : '0%';
  }

  // ----------------------------------------------------------
  // MAIN RENDER
  // ----------------------------------------------------------
  function _render() {
    let planContent = '';
    if (_activePlan === 'welpe')     planContent = _renderWelpe();
    else if (_activePlan === 'junior') planContent = _renderJunior();
    else                               planContent = _renderErwachsen();

    const dogId = _dogId();
    const planLabel = _activePlan === 'welpe' ? 'Welpe 0–6 Monate'
                    : _activePlan === 'junior' ? 'Junior 6–18 Monate'
                    : `Erwachsener Hund – ${_activeAdultTab}`;

    _container.innerHTML = `
      <div style="padding-bottom:var(--space-8)">
        <div style="display:flex;align-items:center;justify-content:space-between;margin:var(--space-4) 0 var(--space-4)">
          <h2 style="font-size:var(--text-lg);font-weight:700;margin:0">
            ${_icon('clipboard-text')} Trainingspläne
          </h2>
          ${dogId ? `<button class="btn btn-ghost btn-xs" id="tp-note-btn" title="Notiz zum Plan">
            <svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#note-pencil"></use></svg> Notiz
          </button>` : ''}
        </div>
        ${_renderPlanSelector()}
        ${planContent}
        <!-- Trainingskalender -->
        <div id="tp-calendar-section" style="margin-top:var(--space-6)">
          <h3 style="font-size:var(--text-base);font-weight:var(--weight-semibold);
                     color:var(--c-text);margin:0 0 var(--space-3)">
            ${_icon('calendar')} Trainingskalender
          </h3>
          <div id="tp-calendar-wrap" style="display:flex;flex-direction:column;gap:var(--space-4)">
            <div style="color:var(--c-text-secondary);font-size:var(--text-sm);text-align:center;padding:var(--space-4)">
              Lade Kalender…
            </div>
          </div>
        </div>
      </div>`;

    _bindEvents();
    _loadCalendar();
  }

  // ----------------------------------------------------------
  // TRAININGSKALENDER
  // ----------------------------------------------------------
  async function _loadCalendar() {
    const dogId = _dogId();
    const wrap  = _container.querySelector('#tp-calendar-wrap');
    if (!wrap) return;

    if (!dogId) {
      wrap.innerHTML = `<p style="font-size:var(--text-sm);color:var(--c-text-secondary);text-align:center;padding:var(--space-3)">Kein Hund ausgewählt.</p>`;
      return;
    }

    const now      = new Date();
    const thisYear = now.getFullYear();
    const thisMon  = now.getMonth() + 1; // 1-based

    // Letzter Monat
    const prevDate = new Date(now.getFullYear(), now.getMonth() - 1, 1);
    const prevYear = prevDate.getFullYear();
    const prevMon  = prevDate.getMonth() + 1;

    const [dataCurr, dataPrev] = await Promise.all([
      _apiGet(`/api/training/calendar?dog_id=${dogId}&year=${thisYear}&month=${thisMon}`),
      _apiGet(`/api/training/calendar?dog_id=${dogId}&year=${prevYear}&month=${prevMon}`),
    ]);

    wrap.innerHTML = `
      <div style="display:flex;flex-wrap:wrap;gap:var(--space-4)">
        ${_renderCalendarMonth(prevYear, prevMon, dataPrev?.days || {})}
        ${_renderCalendarMonth(thisYear, thisMon, dataCurr?.days || {})}
      </div>
      <!-- Legende -->
      <div style="display:flex;gap:var(--space-4);flex-wrap:wrap;margin-top:var(--space-2);
                  font-size:var(--text-xs);color:var(--c-text-secondary);align-items:center">
        <span style="display:flex;align-items:center;gap:5px">
          <span style="width:14px;height:14px;border-radius:3px;border:1.5px solid var(--c-border);display:inline-block"></span>
          kein Training
        </span>
        <span style="display:flex;align-items:center;gap:5px">
          <span style="width:14px;height:14px;border-radius:3px;background:var(--c-primary-subtle);border:1.5px solid var(--c-primary);display:inline-block"></span>
          Training
        </span>
        <span style="display:flex;align-items:center;gap:5px">
          <span style="width:14px;height:14px;border-radius:3px;background:var(--c-primary);display:inline-block"></span>
          Top-Training
        </span>
      </div>
    `;
  }

  function _renderCalendarMonth(year, month, days) {
    const MONTHS = ['Januar','Februar','März','April','Mai','Juni',
                    'Juli','August','September','Oktober','November','Dezember'];
    const WDAYS  = ['Mo','Di','Mi','Do','Fr','Sa','So'];

    const firstDay = new Date(year, month - 1, 1);
    // Monday = 0 offset: getDay() returns 0=Sun, so we shift
    let startOffset = firstDay.getDay(); // 0=Sun
    startOffset = startOffset === 0 ? 6 : startOffset - 1; // Mon=0 … Sun=6

    const daysInMonth = new Date(year, month, 0).getDate();

    // Header Wochentage
    const wdayHeader = WDAYS.map(d =>
      `<div style="text-align:center;font-size:10px;font-weight:var(--weight-semibold);
                   color:var(--c-text-secondary);padding-bottom:4px">${d}</div>`
    ).join('');

    // Leere Slots am Anfang
    let cells = '';
    for (let i = 0; i < startOffset; i++) {
      cells += `<div></div>`;
    }

    const today = new Date();
    const todayStr = `${today.getFullYear()}-${String(today.getMonth()+1).padStart(2,'0')}-${String(today.getDate()).padStart(2,'0')}`;

    for (let d = 1; d <= daysInMonth; d++) {
      const dateStr = `${year}-${String(month).padStart(2,'0')}-${String(d).padStart(2,'0')}`;
      const dayData = days[dateStr];
      const isToday = dateStr === todayStr;

      let bg      = 'transparent';
      let border  = '1.5px solid var(--c-border)';
      let color   = 'var(--c-text-secondary)';
      let title   = '';

      if (dayData) {
        if (dayData.top) {
          bg     = 'var(--c-primary)';
          border = '1.5px solid var(--c-primary)';
          color  = '#fff';
          title  = `Top-Training! ${dayData.count} Einheit${dayData.count !== 1 ? 'en' : ''}`;
        } else {
          bg     = 'var(--c-primary-subtle)';
          border = '1.5px solid var(--c-primary)';
          color  = 'var(--c-primary)';
          title  = `${dayData.count} Einheit${dayData.count !== 1 ? 'en' : ''}`;
        }
      }

      const todayRing = isToday ? 'box-shadow:0 0 0 2px var(--c-primary);' : '';

      cells += `
        <div title="${title}"
             style="aspect-ratio:1;border-radius:4px;background:${bg};border:${border};
                    display:flex;align-items:center;justify-content:center;
                    font-size:10px;font-weight:${dayData ? 'var(--weight-semibold)' : '400'};
                    color:${color};${todayRing}cursor:default">
          ${d}
        </div>
      `;
    }

    return `
      <div style="flex:1;min-width:220px">
        <div style="font-size:var(--text-sm);font-weight:var(--weight-semibold);
                    color:var(--c-text);margin-bottom:var(--space-2)">
          ${_esc(MONTHS[month - 1])} ${year}
        </div>
        <div style="display:grid;grid-template-columns:repeat(7,1fr);gap:3px">
          ${wdayHeader}
          ${cells}
        </div>
      </div>
    `;
  }

  // ----------------------------------------------------------
  // NOTIZ-MODAL
  // ----------------------------------------------------------
  async function _openNoteModal(parentType, parentId, parentLabel, locationName) {
    // Vorhandenes Modal entfernen falls noch offen
    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">${_esc(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 API
  // ----------------------------------------------------------
  async function init(container, appState) {
    _container = container;
    _appState  = appState;
    _render();
  }

  function refresh() {}
  function onDogChange() {}

  return { init, refresh, onDogChange };

})();
