/**
 * Coach-Modus: eine Position nach der anderen mit Assistentenhinweisen, Zeitnahme und optionaler Nachbereitung.
 */
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { Link, useNavigate, useParams } from 'react-router-dom'
import api from '../utils/api'
import ExerciseFullContent from '../components/ExerciseFullContent'
import {
  flattenPlanTimeline,
  itemStableKey,
  sectionsToPutPayload,
  summarizeTimelineEntry,
} from '../utils/trainingPlanUtils'

function storageStepKey(unitId) {
  return `sj_coach_step_${unitId}`
}

function storageDeltasKey(unitId) {
  return `sj_coach_deltas_${unitId}`
}

function storageDebriefKey(unitId) {
  return `sj_coach_debrief_${unitId}`
}

function formatClock(totalSec) {
  const m = Math.floor(totalSec / 60)
  const s = totalSec % 60
  return `${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`
}

function mergeDelta(setDeltas, itemKey, patch) {
  setDeltas((prev) => ({ ...prev, [itemKey]: { ...prev[itemKey], ...patch } }))
}

function CoachControlsBand({
  step,
  timelineLength,
  onPrev,
  onNext,
  onDone,
  clockStr,
  runStartAt,
  pausedAccumMs,
  onTimerStart,
  onTimerPause,
  onTimerReset,
  onApplyActual,
  roundedMinForApply,
  isLastCoachStep,
  showJumpToTimerOwner,
  showJumpToTimerOwnerRow = true,
  onJumpToTimerOwner,
  timerOwnerLabelIndex,
}) {
  const disPrev = step <= 0
  const disNext = step >= timelineLength - 1
  const alive = runStartAt != null || pausedAccumMs > 0
  const canApplyForOwner = roundedMinForApply != null && roundedMinForApply >= 1
  const istLabelMin = roundedMinForApply == null ? '—' : String(roundedMinForApply)
  const doneLabel =
    timelineLength <= 1
      ? 'Nachbereitung öffnen'
      : isLastCoachStep
        ? 'Nachbereitung & Ist-Zeit'
        : 'Abgeschlossen & weiter'

  return (
    <div className="training-coach-stepbar" style={{ marginBottom: '10px' }}>
      {showJumpToTimerOwner && showJumpToTimerOwnerRow && (
        <div style={{ textAlign: 'center', marginBottom: '8px' }}>
          <button
            type="button"
            className="btn btn-secondary"
            style={{ fontSize: '0.82rem', fontWeight: 600, padding: '8px 12px', lineHeight: 1.3 }}
            onClick={onJumpToTimerOwner}
          >
            ← Zur laufenden Übung ({timerOwnerLabelIndex + 1}/{timelineLength})
          </button>
        </div>
      )}
      <div
        style={{
          display: 'grid',
          gridTemplateColumns: 'minmax(92px,1fr) minmax(0,2fr) minmax(92px,1fr)',
          gap: '8px',
          alignItems: 'stretch',
        }}
      >
        <button
          type="button"
          className="btn btn-secondary"
          style={{ minHeight: '46px', fontWeight: 700, padding: '6px 8px' }}
          disabled={disPrev}
          onClick={onPrev}
        >
          ← zurück
        </button>
        <div style={{ display: 'flex', flexDirection: 'column', gap: '6px', justifyContent: 'center' }}>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: '6px', justifyContent: 'center', alignItems: 'center' }}>
            {runStartAt == null ? (
              <button
                type="button"
                className="btn btn-primary"
                style={{ minHeight: '44px', flex: '1 1 auto', fontWeight: 700 }}
                onClick={onTimerStart}
              >
                ▶ Start{alive ? ` · ${clockStr}` : ''}
              </button>
            ) : (
              <button type="button" className="btn btn-secondary" style={{ minHeight: '44px', flex: '1 1 auto', fontWeight: 700 }} onClick={onTimerPause}>
                Pause · {clockStr}
              </button>
            )}
            <button type="button" className="btn btn-secondary" style={{ minHeight: '44px', flex: '0 1 auto', fontWeight: 600 }} disabled={!canApplyForOwner} onClick={onApplyActual}>
              Ist ({istLabelMin}&nbsp;Min)
            </button>
            {alive && (
              <button
                type="button"
                className="btn btn-secondary"
                title="Zeit löschen"
                style={{ minHeight: '44px', flex: '0 0 auto', padding: '0 10px' }}
                onClick={onTimerReset}
              >
                ↺
              </button>
            )}
          </div>
          <button
            type="button"
            className="btn btn-primary"
            style={{ width: '100%', minHeight: '44px', fontWeight: 700, lineHeight: 1.2, padding: '6px 10px', whiteSpace: 'normal', textAlign: 'center' }}
            onClick={onDone}
          >
            {doneLabel}
          </button>
        </div>
        <button
          type="button"
          className="btn btn-secondary"
          style={{ minHeight: '46px', fontWeight: 700, padding: '6px 8px' }}
          disabled={disNext}
          onClick={onNext}
        >
          weiter →
        </button>
      </div>
    </div>
  )
}

export default function TrainingCoachPage() {
  const { unitId } = useParams()
  const navigate = useNavigate()
  const idNum = unitId ? parseInt(unitId, 10) : NaN

  const [unit, setUnit] = useState(null)
  const [loadError, setLoadError] = useState(null)
  const [loading, setLoading] = useState(true)

  const [outlineOpen, setOutlineOpen] = useState(false)
  const [catalogExercise, setCatalogExercise] = useState(null)
  const [catalogLoading, setCatalogLoading] = useState(false)
  const [catalogError, setCatalogError] = useState(null)
  const [debriefOpen, setDebriefOpen] = useState(false)
  const [coachDebriefPhase, setCoachDebriefPhase] = useState(false)

  const [step, setStep] = useState(0)
  const [deltas, setDeltas] = useState({})

  const [runStartAt, setRunStartAt] = useState(null)
  const [pausedAccumMs, setPausedAccumMs] = useState(0)
  const [timerOwningStep, setTimerOwningStep] = useState(null)
  const [, setPulse] = useState(0)

  const [trainerAppend, setTrainerAppend] = useState('')
  const [saveMarkDone, setSaveMarkDone] = useState(true)
  const [saving, setSaving] = useState(false)
  const [saveOk, setSaveOk] = useState(null)

  const reloadUnit = useCallback(async () => {
    const u = await api.getTrainingUnit(idNum)
    setUnit(u)
  }, [idNum])

  useEffect(() => {
    if (!unitId || Number.isNaN(idNum)) {
      setLoadError('Ungültige Trainingseinheit')
      setLoading(false)
      return
    }
    let cancelled = false
    ;(async () => {
      setLoading(true)
      setLoadError(null)
      try {
        await reloadUnit()
        if (cancelled) return
        try {
          const s = parseInt(sessionStorage.getItem(storageStepKey(idNum)), 10)
          if (!Number.isNaN(s) && s >= 0) setStep(s)
        } catch {
          /* ignore */
        }
        try {
          const raw = sessionStorage.getItem(storageDeltasKey(idNum))
          if (raw) {
            const o = JSON.parse(raw)
            if (o && typeof o === 'object') setDeltas(o)
          }
        } catch {
          /* ignore */
        }
        try {
          if (sessionStorage.getItem(storageDebriefKey(idNum)) === '1') setCoachDebriefPhase(true)
        } catch {
          /* ignore */
        }
      } catch (e) {
        if (!cancelled) setLoadError(e.message || 'Laden fehlgeschlagen')
      } finally {
        if (!cancelled) setLoading(false)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [unitId, idNum, reloadUnit])

  useEffect(() => {
    sessionStorage.setItem(storageStepKey(idNum), String(step))
  }, [idNum, step])

  useEffect(() => {
    try {
      sessionStorage.setItem(storageDeltasKey(idNum), JSON.stringify(deltas))
    } catch {
      /* quota */
    }
  }, [idNum, deltas])

  useEffect(() => {
    try {
      sessionStorage.setItem(storageDebriefKey(idNum), coachDebriefPhase ? '1' : '0')
    } catch {
      /* quota */
    }
  }, [idNum, coachDebriefPhase])

  useEffect(() => {
    if (runStartAt == null) return undefined
    const iv = setInterval(() => setPulse((p) => p + 1), 380)
    return () => clearInterval(iv)
  }, [runStartAt])

  const timeline = useMemo(() => flattenPlanTimeline(unit), [unit])

  const clampStep = (s, len = timeline.length) =>
    Math.max(0, Math.min(s, Math.max(len - 1, 0)))

  useEffect(() => {
    if (!unit) return
    if (timeline.length === 0) {
      setStep(0)
      return
    }
    if (coachDebriefPhase) return
    setStep((prev) => clampStep(prev, timeline.length))
  }, [unit, timeline.length, coachDebriefPhase])

  useEffect(() => {
    if (!coachDebriefPhase || !unit || timeline.length === 0) return
    setStep(timeline.length - 1)
  }, [coachDebriefPhase, unit, timeline.length])

  const elapsedMs =
    pausedAccumMs + (runStartAt != null ? Date.now() - runStartAt : 0)

  const tickDisplaySec = Math.max(0, Math.floor(elapsedMs / 1000))

  const currentEntry = timeline[step]
  const nextEntry = timeline[step + 1] || null
  const next2Entry = timeline[step + 2] || null

  const clockStr = formatClock(tickDisplaySec)
  const roundedMinApply = elapsedMs <= 650 ? null : Math.max(1, Math.round(elapsedMs / 60000))
  const showJumpToTimerOwner =
    timerOwningStep != null &&
    step !== timerOwningStep &&
    (runStartAt != null || pausedAccumMs > 0)
  const isLastCoachStep = timeline.length > 0 && step >= timeline.length - 1

  const timerStart = () => {
    setRunStartAt(Date.now())
    setTimerOwningStep(step)
  }

  const timerPause = () => {
    if (runStartAt != null) {
      setPausedAccumMs((a) => a + (Date.now() - runStartAt))
      setRunStartAt(null)
    }
  }

  const timerReset = () => {
    setRunStartAt(null)
    setPausedAccumMs(0)
    setTimerOwningStep(null)
  }

  const applySuggestedDuration = () => {
    const idx = timerOwningStep != null ? timerOwningStep : step
    const ent = timeline[idx]
    const item = ent?.item
    if (!item || item.item_type !== 'exercise') return
    if (elapsedMs <= 650) return
    const min = Math.max(1, Math.round(elapsedMs / 60000))
    const key = itemStableKey(item, ent.secOrder, ent.ii)
    mergeDelta(setDeltas, key, { actual_duration_min: min })
    timerPause()
  }

  const goPrev = () => setStep((s) => clampStep(s - 1))
  const goNext = () => setStep((s) => clampStep(s + 1))

  const markCurrentDoneAdvance = () => {
    const ownerIdx = timerOwningStep != null ? timerOwningStep : step
    const ent = timeline[ownerIdx]
    const item = ent?.item
    if (item?.item_type === 'exercise' && elapsedMs > 650) {
      const key = itemStableKey(item, ent.secOrder, ent.ii)
      const min = Math.max(1, Math.round(elapsedMs / 60000))
      mergeDelta(setDeltas, key, { actual_duration_min: min })
    }
    timerReset()

    const lastIdx = timeline.length - 1
    if (step >= lastIdx && lastIdx >= 0) {
      setCoachDebriefPhase(true)
      try {
        sessionStorage.setItem(storageDebriefKey(idNum), '1')
      } catch {
        /* ignore */
      }
      return
    }
    setStep((s) => clampStep(s + 1, timeline.length))
  }

  const durationOverridesForApi = useMemo(() => {
    const out = {}
    for (let i = 0; i < timeline.length; i++) {
      const ent = timeline[i]
      const { item } = ent
      if (item.item_type !== 'exercise' || item.id == null) continue
      const k = itemStableKey(item, ent.secOrder, ent.ii)
      const dv = deltas[k]?.actual_duration_min
      if (dv !== undefined && dv !== '' && dv !== null && !Number.isNaN(Number(dv))) {
        out[String(item.id)] = { actual_duration_min: Number(dv) }
      }
    }
    return out
  }, [timeline, deltas])

  useEffect(() => {
    const item = currentEntry?.item
    if (!item || item.item_type === 'note') {
      setCatalogExercise(null)
      setCatalogError(null)
      setCatalogLoading(false)
      return
    }
    const eid = item.exercise_id
    if (!eid) {
      setCatalogExercise(null)
      setCatalogError(null)
      setCatalogLoading(false)
      return
    }
    let cancelled = false
    setCatalogLoading(true)
    setCatalogError(null)
    setCatalogExercise(null)
    api.getExercise(eid)
      .then((ex) => {
        if (!cancelled) {
          setCatalogExercise(ex)
          setCatalogLoading(false)
        }
      })
      .catch((err) => {
        if (!cancelled) {
          setCatalogError(err.message || String(err))
          setCatalogExercise(null)
          setCatalogLoading(false)
        }
      })
    return () => {
      cancelled = true
    }
  }, [step, currentEntry?.item?.exercise_id, currentEntry?.item?.exercise_variant_id, currentEntry?.item?.item_type])

  const handleSaveDebrief = async () => {
    setSaveOk(null)
    setSaving(true)
    try {
      const sectionsPayload = sectionsToPutPayload(unit, durationOverridesForApi)
      const tn = trainerAppend.trim()
      const payload = {
        sections: sectionsPayload,
        ...(saveMarkDone ? { status: 'completed' } : {}),
      }
      if (tn) {
        payload.trainer_notes = [unit.trainer_notes || '', `--- (${new Date().toLocaleString('de-DE')}) ---`, tn]
          .filter(Boolean)
          .join('\n')
          .trim()
      }
      await api.updateTrainingUnit(idNum, payload)
      await reloadUnit()
      setTrainerAppend('')
      try {
        sessionStorage.removeItem(storageDeltasKey(idNum))
        sessionStorage.removeItem(storageDebriefKey(idNum))
      } catch {
        /* ignore */
      }
      setDeltas({})
      setCoachDebriefPhase(false)
      setSaveOk('Gespeichert.')
      setDebriefOpen(false)
    } catch (e) {
      setSaveOk(`Fehler: ${e.message || e}`)
    } finally {
      setSaving(false)
    }
  }

  if (loading) {
    return (
      <div style={{ padding: '2rem', textAlign: 'center' }}>
        <div className="spinner" />
        <p>Coach laden…</p>
      </div>
    )
  }

  if (loadError || !unit) {
    return (
      <div className="card" style={{ margin: '1rem', padding: '1.5rem' }}>
        <p style={{ marginBottom: '1rem' }}>{loadError || 'Nicht gefunden.'}</p>
        <button type="button" className="btn btn-secondary" onClick={() => navigate('/planning')}>
          Zur Planung
        </button>
      </div>
    )
  }

  return (
    <div className="training-coach-page training-coach-layout">
      <nav
        className="no-print training-coach-meta-nav"
        style={{
          flexShrink: 0,
          display: 'flex',
          flexWrap: 'wrap',
          gap: '8px',
          alignItems: 'center',
          marginBottom: '8px',
          paddingBottom: '4px'
        }}
      >
        <button type="button" className="btn btn-secondary" onClick={() => navigate(`/planning/run/${unitId}`)}>
          Zur Planansicht
        </button>
        <button type="button" className="btn btn-secondary" onClick={() => navigate('/planning')}>
          Planung
        </button>
        <button
          type="button"
          className="btn btn-primary"
          onClick={() => setOutlineOpen((o) => !o)}
          style={{ marginLeft: 'auto' }}
        >
          {outlineOpen ? 'Rahmen schließen' : 'Trainingsrahmen'}
        </button>
      </nav>

      <header
        className="card training-coach-hero training-coach-hero--compact"
        style={{
          flexShrink: 0,
          padding: '12px 14px',
          marginBottom: '8px',
          background: 'var(--surface)',
          borderRadius: '12px',
          borderLeft: `4px solid var(--accent)`
        }}
      >
        <div style={{ fontSize: '0.7rem', color: 'var(--text3)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>
          Coach ·{' '}
          {coachDebriefPhase ? 'Nachbereitung · abschließend speichern' : `Schritt ${(step || 0) + 1} / ${Math.max(timeline.length, 1)}`}
        </div>
        <h1 style={{ fontSize: '1.1rem', margin: '4px 0 0', lineHeight: 1.28 }}>
          {unit.planned_date}
          {unit.planned_time_start && ` · ${String(unit.planned_time_start).slice(0, 5)}`}
          {unit.planned_focus ? ` · ${unit.planned_focus}` : ''}
        </h1>
      </header>

      {outlineOpen && (
        <div className="card training-coach-outline" style={{ flexShrink: 0, marginBottom: '8px', padding: '10px 12px', maxHeight: 'min(28vh, 260px)', display: 'flex', flexDirection: 'column', minHeight: 0 }}>
          <div style={{ fontSize: '0.75rem', color: 'var(--text3)', marginBottom: '6px', flexShrink: 0 }}>Ablauf · Antippen zum Springen</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: '6px', overflowY: 'auto', minHeight: 0 }}>
            {timeline.map((ent, ix) => {
              const lbl = summarizeTimelineEntry(ent)
              const secTitle = ent.sec.title || `Abschnitt ${ent.si + 1}`
              const active = coachDebriefPhase ? ix === timeline.length - 1 : ix === step
              return (
                <button
                  key={`${itemStableKey(ent.item, ent.secOrder, ent.ii)}-${ix}`}
                  type="button"
                  className={`btn ${active ? 'btn-primary' : 'btn-secondary'}`}
                  style={{
                    textAlign: 'left',
                    justifyContent: 'flex-start',
                    opacity: active ? 1 : 0.92,
                    fontWeight: active ? 700 : 500
                  }}
                  onClick={() => {
                    setCoachDebriefPhase(false)
                    setStep(ix)
                  }}
                >
                  <span style={{ opacity: 0.75 }}>{secTitle.substring(0, 14)} › </span>
                  <span>{lbl}</span>
                </button>
              )
            })}
          </div>
        </div>
      )}

      {timeline.length === 0 ? (
        <p className="card" style={{ padding: '1rem', flexShrink: 0 }}>
          Dieser Plan ist leer. <Link to="/planning">Unter Planung ergänzen</Link>.
        </p>
      ) : coachDebriefPhase ? (
        <div className="training-coach-scroll" style={{ flex: 1, minHeight: 0 }}>
          <div className="card" style={{ padding: '14px', marginBottom: '12px', borderRadius: '12px', borderLeft: `4px solid var(--accent)` }}>
            <div style={{ fontSize: '0.88rem', fontWeight: 700, marginBottom: '8px', color: 'var(--accent-dark)' }}>
              Nachbereitung
            </div>
            <p style={{ fontSize: '0.82rem', color: 'var(--text2)', margin: '0 0 14px', lineHeight: 1.5 }}>
              <strong>Ist‑Minuten</strong> prüfen, Trainer‑Ergänzung anlegen und Einheit sichern (zeigt bestehende Notizen weiter unten an).
            </p>
            <div style={{ display: 'flex', flexDirection: 'column', gap: '10px', marginBottom: '12px' }}>
              {timeline
                .filter((e) => e.item.item_type === 'exercise')
                .map((ent) => {
                  const k = itemStableKey(ent.item, ent.secOrder, ent.ii)
                  const val = deltas[k]?.actual_duration_min ?? ent.item.actual_duration_min ?? ''
                  return (
                    <label key={`db-${k}`} style={{ display: 'grid', gridTemplateColumns: '1fr 88px', gap: '10px', alignItems: 'center', fontSize: '0.88rem' }}>
                      <span style={{ wordBreak: 'break-word' }}>{summarizeTimelineEntry(ent)}</span>
                      <input
                        type="number"
                        min="0"
                        className="form-input"
                        style={{ margin: 0 }}
                        value={val === '' || val == null ? '' : String(val)}
                        placeholder="Min"
                        onChange={(e) => {
                          const raw = e.target.value
                          if (raw === '') mergeDelta(setDeltas, k, { actual_duration_min: null })
                          else mergeDelta(setDeltas, k, { actual_duration_min: parseInt(raw, 10) })
                        }}
                      />
                    </label>
                  )
                })}
            </div>
            <label style={{ display: 'block', marginBottom: '10px', fontSize: '0.88rem', color: 'var(--text2)' }}>
              Ergänzung Trainer (wird angehängt · mit Zeitstempel)
              <textarea className="form-input" rows={3} value={trainerAppend} onChange={(e) => setTrainerAppend(e.target.value)} style={{ marginTop: '6px' }} />
            </label>
            <label style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '12px', fontSize: '0.88rem' }}>
              <input type="checkbox" checked={saveMarkDone} onChange={(e) => setSaveMarkDone(e.target.checked)} />
              Einheit als <strong>durchgeführt</strong> markieren
            </label>
            {saveOk && (
              <p
                style={{
                  fontSize: '0.88rem',
                  marginBottom: '8px',
                  color: saveOk.startsWith('Fehler') ? 'var(--danger)' : 'var(--accent-dark)'
                }}
              >
                {saveOk}
              </p>
            )}
            <div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
              <button type="button" className="btn btn-primary" style={{ width: '100%', minHeight: '48px' }} disabled={saving} onClick={handleSaveDebrief}>
                {saving ? 'Speichert…' : 'Speichern'}
              </button>
              <button
                type="button"
                className="btn btn-secondary"
                style={{ width: '100%', minHeight: '44px' }}
                onClick={() => {
                  setCoachDebriefPhase(false)
                  if (timeline.length > 0) setStep(Math.max(0, timeline.length - 1))
                }}
              >
                Zurück zur letzten Übungsposition
              </button>
            </div>
          </div>
          {unit.trainer_notes ? (
            <div className="card" style={{ marginBottom: '12px', padding: '12px 14px', borderLeft: `4px solid var(--accent)` }}>
              <div style={{ fontSize: '0.7rem', fontWeight: 700, color: 'var(--text3)', textTransform: 'uppercase' }}>Einheit · Trainernotizen</div>
              <p style={{ fontSize: '0.88rem', marginTop: '6px', whiteSpace: 'pre-wrap', color: 'var(--text2)' }}>{unit.trainer_notes}</p>
            </div>
          ) : null}
        </div>
      ) : (
        <>
          <div
            className="training-coach-assist training-coach-assist--compact"
            style={{
              flexShrink: 0,
              marginBottom: '8px',
              padding: '12px 14px',
              background: 'var(--accent-light)',
              borderRadius: '12px'
            }}
          >
            <div style={{ fontSize: '0.72rem', fontWeight: 700, color: 'var(--accent-dark)', marginBottom: '6px' }}>
              Als Nächstes
            </div>
            {nextEntry ? (
              <>
                <p style={{ margin: '0', fontSize: '0.9rem', color: 'var(--text1)', lineHeight: 1.4 }}>
                  <strong>Nächste:</strong> {summarizeTimelineEntry(nextEntry)}
                </p>
                {next2Entry && (
                  <p style={{ margin: '6px 0 0', fontSize: '0.82rem', color: 'var(--text2)' }}>
                    <strong>Daraufhin:</strong> {summarizeTimelineEntry(next2Entry)}
                  </p>
                )}
              </>
            ) : (
              <p style={{ margin: 0, fontSize: '0.88rem', color: 'var(--text2)' }}>
                Letzter Punkt — „Nachbereitung &amp; Ist-Zeit“ öffnet die Abschlussseite zum Speichern.
              </p>
            )}
          </div>

          <CoachControlsBand
            step={step}
            timelineLength={timeline.length}
            onPrev={goPrev}
            onNext={goNext}
            onDone={markCurrentDoneAdvance}
            clockStr={clockStr}
            runStartAt={runStartAt}
            pausedAccumMs={pausedAccumMs}
            onTimerStart={timerStart}
            onTimerPause={timerPause}
            onTimerReset={timerReset}
            onApplyActual={applySuggestedDuration}
            roundedMinForApply={roundedMinApply}
            isLastCoachStep={isLastCoachStep}
            showJumpToTimerOwner={showJumpToTimerOwner}
            showJumpToTimerOwnerRow
            onJumpToTimerOwner={() => setStep(timerOwningStep ?? step)}
            timerOwnerLabelIndex={timerOwningStep ?? 0}
          />

          <div className="training-coach-scroll">
            {currentEntry?.item?.item_type === 'note' ? (
              <div className="card" style={{ padding: '16px 14px' }}>
                <div style={{ fontSize: '0.74rem', color: 'var(--text3)', marginBottom: '8px' }}>
                  {currentEntry.sec.title || 'Abschnitt'} · Coach-Notiz · Teil {step + 1}
                </div>
                <div style={{ fontSize: '0.78rem', color: 'var(--text3)', marginBottom: '6px' }}>Coach-Notiz</div>
                <p style={{ fontSize: '1.05rem', lineHeight: 1.52, whiteSpace: 'pre-wrap', margin: 0 }}>{currentEntry.item.note_body || ''}</p>
              </div>
            ) : (
              <>
                <div className="card training-coach-plan-strip" style={{ padding: '12px 14px', marginBottom: '12px', borderRadius: '12px', borderLeft: `3px solid var(--accent)` }}>
                  <div style={{ fontSize: '0.74rem', color: 'var(--text3)', marginBottom: '6px' }}>
                    In diesem Training · {currentEntry?.sec.title || 'Abschnitt'} · Teil {step + 1}
                  </div>
                  {currentEntry?.item && (
                    <>
                      <p style={{ margin: '0 0 6px', fontSize: '0.95rem', fontWeight: 700 }}>
                        {currentEntry.item.exercise_title ||
                          (currentEntry.item.exercise_id ? `Übung #${currentEntry.item.exercise_id}` : 'Übung')}
                        {currentEntry.item.exercise_variant_name ? (
                          <span style={{ fontWeight: 600, color: 'var(--text2)' }}> ({currentEntry.item.exercise_variant_name})</span>
                        ) : null}
                      </p>
                      <p style={{ fontSize: '0.83rem', color: 'var(--text3)', marginBottom: '8px' }}>
                        geplant <strong>{currentEntry.item.planned_duration_min ?? '—'}</strong> Min · Ist (Plan):{' '}
                        <strong>
                          {durationOverridesForApi[String(currentEntry.item.id)] != null
                            ? durationOverridesForApi[String(currentEntry.item.id)].actual_duration_min
                            : currentEntry.item.actual_duration_min ?? '—'}{' '}
                          Min
                        </strong>{' '}
                        {durationOverridesForApi[String(currentEntry.item.id)] != null ? '(Entwurf)' : ''}
                      </p>
                      {currentEntry.item.exercise_focus_area ? (
                        <p style={{ fontSize: '0.82rem', color: 'var(--text2)', marginBottom: '10px' }}>{currentEntry.item.exercise_focus_area}</p>
                      ) : null}
                      {currentEntry.item.notes ? (
                        <div style={{ marginBottom: '10px', padding: '10px', background: 'var(--surface2)', borderRadius: '8px' }}>
                          <div style={{ fontSize: '0.72rem', textTransform: 'uppercase', color: 'var(--text3)' }}>Zu dieser Platzierung</div>
                          <p style={{ marginTop: '4px', whiteSpace: 'pre-wrap', fontSize: '0.93rem' }}>{currentEntry.item.notes}</p>
                        </div>
                      ) : null}
                      {currentEntry.item.modifications ? (
                        <div style={{ padding: '10px', borderRadius: '8px', border: `1px solid var(--accent)` }}>
                          <div style={{ fontSize: '0.72rem', textTransform: 'uppercase', color: 'var(--accent-dark)' }}>Anpassung</div>
                          <p style={{ marginTop: '4px', whiteSpace: 'pre-wrap', fontSize: '0.93rem' }}>{currentEntry.item.modifications}</p>
                        </div>
                      ) : null}
                    </>
                  )}
                  <hr style={{ border: 'none', borderTop: '1px solid var(--border)', margin: '14px 0 12px' }} />
                  <div style={{ fontSize: '0.72rem', textTransform: 'uppercase', letterSpacing: '0.04em', color: 'var(--text3)', marginBottom: '6px' }}>
                    Übung aus dem Katalog (vollständig)
                  </div>
                  <ExerciseFullContent
                    loading={catalogLoading}
                    error={catalogError}
                    exercise={catalogExercise}
                    exerciseId={currentEntry?.item?.exercise_id ?? null}
                    variantId={currentEntry?.item?.exercise_variant_id ?? null}
                  />
                </div>
              </>
            )}

            {unit.trainer_notes ? (
              <div className="card" style={{ marginBottom: '12px', padding: '12px 14px', borderLeft: `4px solid var(--accent)` }}>
                <div style={{ fontSize: '0.7rem', fontWeight: 700, color: 'var(--text3)', textTransform: 'uppercase' }}>Einheit · Trainernotizen</div>
                <p style={{ fontSize: '0.88rem', marginTop: '6px', whiteSpace: 'pre-wrap', color: 'var(--text2)' }}>{unit.trainer_notes}</p>
              </div>
            ) : null}

            <div className="card training-coach-debrief" style={{ padding: '14px', marginBottom: '8px', borderRadius: '10px' }}>
              <button
                type="button"
                className="btn btn-secondary"
                style={{ width: '100%', textAlign: 'left', justifyContent: 'space-between', display: 'flex', alignItems: 'center' }}
                onClick={() => setDebriefOpen(!debriefOpen)}
              >
                <span style={{ fontWeight: 700 }}>Nachbereitung &amp; speichern</span>
                <span>{debriefOpen ? '▼' : '▶'}</span>
              </button>
              {debriefOpen && (
                <>
                  <p style={{ fontSize: '0.82rem', color: 'var(--text2)', margin: '14px 0 10px', lineHeight: 1.5 }}>
                    <strong>Ist‑Minuten</strong> anpassen und Einheit speichern (inkl. Trainer-Ergänzung).
                  </p>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: '10px', marginBottom: '12px' }}>
                    {timeline
                      .filter((e) => e.item.item_type === 'exercise')
                      .map((ent) => {
                        const k = itemStableKey(ent.item, ent.secOrder, ent.ii)
                        const val = deltas[k]?.actual_duration_min ?? ent.item.actual_duration_min ?? ''
                        return (
                          <label key={k} style={{ display: 'grid', gridTemplateColumns: '1fr 88px', gap: '10px', alignItems: 'center', fontSize: '0.88rem' }}>
                            <span style={{ wordBreak: 'break-word' }}>{summarizeTimelineEntry(ent)}</span>
                            <input
                              type="number"
                              min="0"
                              className="form-input"
                              style={{ margin: 0 }}
                              value={val === '' || val == null ? '' : String(val)}
                              placeholder="Min"
                              onChange={(e) => {
                                const raw = e.target.value
                                if (raw === '') mergeDelta(setDeltas, k, { actual_duration_min: null })
                                else mergeDelta(setDeltas, k, { actual_duration_min: parseInt(raw, 10) })
                              }}
                            />
                          </label>
                        )
                      })}
                  </div>
                  <label style={{ display: 'block', marginBottom: '10px', fontSize: '0.88rem', color: 'var(--text2)' }}>
                    Ergänzung Trainer (wird angehängt · mit Zeitstempel)
                    <textarea className="form-input" rows={3} value={trainerAppend} onChange={(e) => setTrainerAppend(e.target.value)} style={{ marginTop: '6px' }} />
                  </label>
                  <label style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '12px', fontSize: '0.88rem' }}>
                    <input type="checkbox" checked={saveMarkDone} onChange={(e) => setSaveMarkDone(e.target.checked)} />
                    Einheit als <strong>durchgeführt</strong> markieren
                  </label>
                  {saveOk && (
                    <p
                      style={{
                        fontSize: '0.88rem',
                        marginBottom: '8px',
                        color: saveOk.startsWith('Fehler') ? 'var(--danger)' : 'var(--accent-dark)'
                      }}
                    >
                      {saveOk}
                    </p>
                  )}
                  <button type="button" className="btn btn-primary" style={{ width: '100%', minHeight: '48px' }} disabled={saving} onClick={handleSaveDebrief}>
                    {saving ? 'Speichert…' : 'Speichern'}
                  </button>
                </>
              )}
            </div>
          </div>

          <CoachControlsBand
            step={step}
            timelineLength={timeline.length}
            onPrev={goPrev}
            onNext={goNext}
            onDone={markCurrentDoneAdvance}
            clockStr={clockStr}
            runStartAt={runStartAt}
            pausedAccumMs={pausedAccumMs}
            onTimerStart={timerStart}
            onTimerPause={timerPause}
            onTimerReset={timerReset}
            onApplyActual={applySuggestedDuration}
            roundedMinForApply={roundedMinApply}
            isLastCoachStep={isLastCoachStep}
            showJumpToTimerOwner={showJumpToTimerOwner}
            showJumpToTimerOwnerRow={false}
            onJumpToTimerOwner={() => setStep(timerOwningStep ?? step)}
            timerOwnerLabelIndex={timerOwningStep ?? 0}
          />
        </>
      )}
    </div>
  )
}
