import React, { useEffect, useState, useRef } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import api, { buildExerciseApiPayload } from '../utils/api'
import RichTextEditor from '../components/RichTextEditor'
import ExerciseProgressionGraphPanel from '../components/ExerciseProgressionGraphPanel'
import { SKILL_LEVEL_OPTIONS, normalizeSkillLevelSlug } from '../constants/skillLevels'

const INTENSITY_OPTIONS = [
  { value: '', label: '—' },
  { value: 'niedrig', label: 'niedrig' },
  { value: 'mittel', label: 'mittel' },
  { value: 'hoch', label: 'hoch' },
]

const VARIANT_DIFFICULTY = [
  { value: '', label: '—' },
  { value: 'easier', label: 'Einfacher' },
  { value: 'same', label: 'Gleich' },
  { value: 'harder', label: 'Schwerer' },
  { value: 'adapted', label: 'Angepasst' },
]

function emptyVariantDraft() {
  return {
    variant_name: '',
    description: '',
    execution_changes: '',
    duration_min: '',
    duration_max: '',
    equipment_lines: '',
    difficulty_adjustment: '',
    progression_level: 1,
    prerequisite_variant_id: '',
  }
}

function apiVariantToRow(v) {
  let lines = ''
  const eq = v.equipment_changes
  if (Array.isArray(eq)) {
    lines = eq.join('\n')
  } else if (typeof eq === 'string' && eq.trim()) {
    try {
      const p = JSON.parse(eq)
      lines = Array.isArray(p) ? p.join('\n') : eq
    } catch {
      lines = eq
    }
  }
  return {
    ...v,
    duration_min: v.duration_min ?? '',
    duration_max: v.duration_max ?? '',
    equipment_lines: lines,
    progression_level: v.progression_level ?? 1,
    prerequisite_variant_id: v.prerequisite_variant_id ?? '',
    difficulty_adjustment: v.difficulty_adjustment ?? '',
  }
}

function buildVariantPayloadFromRow(row) {
  const lines = (row.equipment_lines || '')
    .split(/[\n,]+/)
    .map((s) => s.trim())
    .filter(Boolean)
  const pl =
    row.progression_level === '' || row.progression_level == null
      ? 1
      : parseInt(row.progression_level, 10)
  const so =
    row.sequence_order === '' || row.sequence_order == null
      ? null
      : parseInt(row.sequence_order, 10)
  return {
    variant_name: (row.variant_name || '').trim(),
    description: (row.description || '').trim() || null,
    execution_changes: (row.execution_changes || '').trim() || null,
    duration_min: row.duration_min === '' || row.duration_min == null ? null : parseInt(row.duration_min, 10),
    duration_max: row.duration_max === '' || row.duration_max == null ? null : parseInt(row.duration_max, 10),
    equipment_changes: lines,
    difficulty_adjustment: row.difficulty_adjustment || null,
    progression_level: Number.isNaN(pl) ? 1 : pl,
    sequence_order: so !== null && Number.isNaN(so) ? null : so,
    prerequisite_variant_id:
      row.prerequisite_variant_id === '' || row.prerequisite_variant_id == null
        ? null
        : parseInt(row.prerequisite_variant_id, 10),
  }
}

/** Gemeinsame Felder für „Variante bearbeiten“ und „Neue Variante“. */
function ExerciseVariantFields({ row, onPatch, prerequisiteOthers, rteMinHeight = '110px' }) {
  return (
    <>
      <div className="form-row">
        <label className="form-label">Variantenname *</label>
        <input
          type="text"
          className="form-input"
          value={row.variant_name || ''}
          onChange={(e) => onPatch({ variant_name: e.target.value })}
          minLength={3}
        />
      </div>
      <div className="form-row">
        <label className="form-label">Kurzbeschreibung</label>
        <textarea
          className="form-input"
          rows={2}
          value={row.description || ''}
          onChange={(e) => onPatch({ description: e.target.value })}
        />
      </div>
      <div className="form-row">
        <label className="form-label">Abweichungen zur Durchführung</label>
        <RichTextEditor
          value={row.execution_changes || ''}
          onChange={(html) => onPatch({ execution_changes: html })}
          placeholder="Was unterscheidet diese Variante? (Listen über Symbolleiste)"
          minHeight={rteMinHeight}
        />
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' }}>
        <div className="form-row">
          <label className="form-label">Dauer Min</label>
          <input
            type="number"
            className="form-input"
            value={row.duration_min}
            onChange={(e) => onPatch({ duration_min: e.target.value })}
          />
        </div>
        <div className="form-row">
          <label className="form-label">Dauer Max</label>
          <input
            type="number"
            className="form-input"
            value={row.duration_max}
            onChange={(e) => onPatch({ duration_max: e.target.value })}
          />
        </div>
      </div>
      <div className="form-row">
        <label className="form-label">Materialänderungen (eine Zeile pro Eintrag)</label>
        <textarea
          className="form-input"
          rows={2}
          value={row.equipment_lines || ''}
          onChange={(e) => onPatch({ equipment_lines: e.target.value })}
          placeholder="+ Pratzen"
        />
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))', gap: '10px' }}>
        <div className="form-row">
          <label className="form-label">Schwere relativ</label>
          <select
            className="form-input"
            value={row.difficulty_adjustment || ''}
            onChange={(e) => onPatch({ difficulty_adjustment: e.target.value })}
          >
            {VARIANT_DIFFICULTY.map((o) => (
              <option key={o.label} value={o.value}>
                {o.label}
              </option>
            ))}
          </select>
        </div>
        <div className="form-row">
          <label className="form-label">Progressions-Stufe (1–10)</label>
          <input
            type="number"
            min={1}
            max={10}
            className="form-input"
            value={row.progression_level}
            onChange={(e) =>
              onPatch({
                progression_level: e.target.value === '' ? '' : parseInt(e.target.value, 10),
              })
            }
          />
        </div>
        <div className="form-row">
          <label className="form-label">Voraussetzungs-Variante</label>
          <select
            className="form-input"
            value={
              row.prerequisite_variant_id === '' || row.prerequisite_variant_id == null
                ? ''
                : String(row.prerequisite_variant_id)
            }
            onChange={(e) =>
              onPatch({
                prerequisite_variant_id: e.target.value === '' ? '' : parseInt(e.target.value, 10),
              })
            }
          >
            <option value="">— keine —</option>
            {prerequisiteOthers.map((o) => (
              <option key={o.id} value={o.id}>
                {o.variant_name || `Variante #${o.id}`}
              </option>
            ))}
          </select>
        </div>
      </div>
    </>
  )
}

function emptyForm() {
  return {
    title: '',
    summary: '',
    goal: '',
    execution: '',
    preparation: '',
    trainer_notes: '',
    equipmentLines: '',
    duration_min: '',
    duration_max: '',
    group_size_min: '',
    group_size_max: '',
    focus_areas_multi: [],
    training_styles_multi: [],
    training_types_multi: [],
    target_groups_multi: [],
    visibility: 'private',
    status: 'draft',
    skills: [],
  }
}

function detailToForm(exercise) {
  return {
    title: exercise.title || '',
    summary: exercise.summary || '',
    goal: exercise.goal || '',
    execution: exercise.execution || '',
    preparation: exercise.preparation || '',
    trainer_notes: exercise.trainer_notes || '',
    equipmentLines: (exercise.equipment || []).join('\n'),
    duration_min: exercise.duration_min ?? '',
    duration_max: exercise.duration_max ?? '',
    group_size_min: exercise.group_size_min ?? '',
    group_size_max: exercise.group_size_max ?? '',
    focus_areas_multi: (exercise.focus_areas || []).map((f) => ({
      focus_area_id: f.focus_area_id,
      is_primary: !!f.is_primary,
    })),
    training_styles_multi: (exercise.training_styles || []).map((t) => ({
      training_style_id: t.training_style_id,
      is_primary: !!t.is_primary,
    })),
    training_types_multi: (exercise.training_types || []).map((t) => ({
      training_type_id: t.training_type_id,
      is_primary: !!t.is_primary,
    })),
    target_groups_multi: (exercise.target_groups || []).map((g) => ({
      target_group_id: g.target_group_id,
      is_primary: !!g.is_primary,
    })),
    visibility: exercise.visibility || 'private',
    status: exercise.status || 'draft',
    skills:
      exercise.skills?.map((s) => ({
        skill_id: s.skill_id,
        is_primary: s.is_primary || false,
        intensity: s.intensity || '',
        required_level: normalizeSkillLevelSlug(s.required_level),
        target_level: normalizeSkillLevelSlug(s.target_level),
      })) || [],
  }
}

function MultiAssocBlock({ title, rows, setRows, options, idKey, emptyLabel }) {
  const setPrimary = (idx) => {
    setRows(rows.map((r, i) => ({ ...r, is_primary: i === idx })))
  }
  const updateRow = (idx, patch) => {
    const next = rows.map((r, i) => (i === idx ? { ...r, ...patch } : r))
    if (patch.is_primary === true) {
      next.forEach((r, i) => {
        if (i !== idx) r.is_primary = false
      })
    }
    setRows(next)
  }
  const addRow = () => setRows([...rows, { [idKey]: '', is_primary: rows.length === 0 }])
  const removeRow = (idx) => {
    const next = rows.filter((_, i) => i !== idx)
    if (next.length && !next.some((r) => r.is_primary)) next[0].is_primary = true
    setRows(next)
  }

  return (
    <div className="multi-assoc-block">
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: '8px' }}>
        <h3>{title}</h3>
        <button type="button" className="btn btn-secondary" style={{ fontSize: '12px', padding: '4px 10px' }} onClick={addRow}>
          + Eintrag
        </button>
      </div>
      {rows.length === 0 && (
        <p style={{ fontSize: '13px', color: 'var(--text2)', margin: 0 }}>{emptyLabel}</p>
      )}
      {rows.map((row, idx) => (
        <div key={idx} className="multi-assoc-row">
          <select
            className="form-input"
            value={row[idKey] || ''}
            onChange={(e) => updateRow(idx, { [idKey]: e.target.value ? parseInt(e.target.value, 10) : '' })}
          >
            <option value="">— wählen —</option>
            {options.map((o) => (
              <option key={o.id} value={o.id}>
                {o.icon ? `${o.icon} ` : ''}
                {o.name}
                {o.abbreviation ? ` (${o.abbreviation})` : ''}
              </option>
            ))}
          </select>
          <label style={{ display: 'flex', alignItems: 'center', gap: '4px', fontSize: '13px', whiteSpace: 'nowrap' }}>
            <input
              type="radio"
              name={`primary-${idKey}`}
              checked={!!row.is_primary}
              onChange={() => setPrimary(idx)}
            />
            primär
          </label>
          <button type="button" className="btn" style={{ fontSize: '12px', padding: '4px 8px' }} onClick={() => removeRow(idx)}>
            ✕
          </button>
        </div>
      ))}
    </div>
  )
}

function ExerciseFormPage() {
  const { id: routeId } = useParams()
  const navigate = useNavigate()
  const exerciseId = routeId && !Number.isNaN(parseInt(routeId, 10)) ? parseInt(routeId, 10) : null
  const isEdit = exerciseId != null

  const [formData, setFormData] = useState(emptyForm)
  const [skillsCatalog, setSkillsCatalog] = useState([])
  const [focusAreas, setFocusAreas] = useState([])
  const [styleDirections, setStyleDirections] = useState([])
  const [trainingTypes, setTrainingTypes] = useState([])
  const [targetGroups, setTargetGroups] = useState([])
  const [mediaList, setMediaList] = useState([])
  const [loading, setLoading] = useState(!!isEdit)
  const [saving, setSaving] = useState(false)
  const [skillPick, setSkillPick] = useState('')
  const [variants, setVariants] = useState([])
  const [variantDraft, setVariantDraft] = useState(() => emptyVariantDraft())
  const [variantSavingId, setVariantSavingId] = useState(null)
  const [variantBusy, setVariantBusy] = useState(false)
  const [variantEditSelection, setVariantEditSelection] = useState(null)
  const variantsDetailsRef = useRef(null)

  const [mediaFile, setMediaFile] = useState(null)
  const [mediaType, setMediaType] = useState('image')
  const [mediaTitle, setMediaTitle] = useState('')
  const [mediaContext, setMediaContext] = useState('ablauf')
  const [embedUrl, setEmbedUrl] = useState('')
  const [embedTitle, setEmbedTitle] = useState('')

  useEffect(() => {
    let cancelled = false
    const boot = async () => {
      try {
        const [skillsData, faData, sdData, ttData, tgData] = await Promise.all([
          api.listSkills(),
          api.listFocusAreas(),
          api.listTrainingStyles(),
          api.listTrainingTypes(),
          api.listTargetGroups(),
        ])
        if (cancelled) return
        setSkillsCatalog(skillsData)
        setFocusAreas(faData)
        setStyleDirections(sdData)
        setTrainingTypes(ttData)
        setTargetGroups(tgData)
      } catch (e) {
        if (!cancelled) {
          console.error(e)
          alert(
            'Kataloge (Fokus, Stile, Zielgruppen, Fähigkeiten) konnten nicht geladen werden: ' +
              (e.message || e),
          )
        }
      }
    }
    boot()
    return () => {
      cancelled = true
    }
  }, [])

  useEffect(() => {
    if (!isEdit) {
      setFormData(emptyForm())
      setMediaList([])
      setVariants([])
      setVariantDraft(emptyVariantDraft())
      setVariantEditSelection(null)
      setLoading(false)
      return
    }
    let cancelled = false
    const load = async () => {
      setLoading(true)
      try {
        const exercise = await api.getExercise(exerciseId)
        if (cancelled) return
        setFormData(detailToForm(exercise))
        setMediaList(exercise.media || [])
        setVariants((exercise.variants || []).map(apiVariantToRow))
        setVariantDraft(emptyVariantDraft())
        setVariantEditSelection(null)
      } catch (err) {
        if (!cancelled) {
          alert(err.message || 'Übung nicht ladbar')
          navigate('/exercises')
        }
      } finally {
        if (!cancelled) setLoading(false)
      }
    }
    load()
    return () => {
      cancelled = true
    }
  }, [isEdit, exerciseId, navigate])

  useEffect(() => {
    if (variantEditSelection == null || variantEditSelection === 'new') return
    if (!variants.some((v) => v.id === variantEditSelection)) {
      setVariantEditSelection(null)
    }
  }, [variants, variantEditSelection])

  useEffect(() => {
    if (variantEditSelection != null && variantsDetailsRef.current) {
      variantsDetailsRef.current.open = true
    }
  }, [variantEditSelection])

  const updateFormField = (field, value) => {
    setFormData((prev) => ({ ...prev, [field]: value }))
  }

  const addSkillRow = () => {
    const id = skillPick ? parseInt(skillPick, 10) : null
    if (!id) {
      alert('Fähigkeit wählen')
      return
    }
    if (formData.skills.some((s) => s.skill_id === id)) {
      alert('Bereits zugeordnet')
      return
    }
    updateFormField('skills', [
      ...formData.skills,
      {
        skill_id: id,
        is_primary: formData.skills.length === 0,
        intensity: '',
        required_level: '',
        target_level: '',
      },
    ])
    setSkillPick('')
  }

  const setSkillPrimary = (idx) => {
    updateFormField(
      'skills',
      formData.skills.map((s, i) => ({ ...s, is_primary: i === idx })),
    )
  }

  const updateSkillField = (idx, field, value) => {
    updateFormField(
      'skills',
      formData.skills.map((s, i) => (i === idx ? { ...s, [field]: value } : s)),
    )
  }

  const removeSkillRow = (idx) => {
    const next = formData.skills.filter((_, i) => i !== idx)
    if (next.length && !next.some((s) => s.is_primary)) next[0].is_primary = true
    updateFormField('skills', next)
  }

  const handleSubmit = async (e) => {
    e.preventDefault()
    if (!formData.title || formData.title.trim().length < 3) {
      alert('Titel mindestens 3 Zeichen')
      return
    }
    const payloadBase = {
      ...formData,
      equipment:
        typeof formData.equipmentLines === 'string'
          ? formData.equipmentLines
              .split(/[\n,]+/)
              .map((s) => s.trim())
              .filter(Boolean)
          : [],
    }
    let payload
    try {
      payload = buildExerciseApiPayload(payloadBase)
    } catch (err) {
      alert(err.message)
      return
    }
    setSaving(true)
    try {
      if (isEdit) {
        await api.updateExercise(exerciseId, payload)
        const ex = await api.getExercise(exerciseId)
        setMediaList(ex.media || [])
        setVariants((ex.variants || []).map(apiVariantToRow))
        alert('Gespeichert.')
      } else {
        const created = await api.createExercise(payload)
        navigate(`/exercises/${created.id}/edit`, { replace: true })
      }
    } catch (err) {
      alert('Fehler beim Speichern: ' + err.message)
    } finally {
      setSaving(false)
    }
  }

  const refreshMedia = async () => {
    if (!exerciseId) return
    const ex = await api.getExercise(exerciseId)
    setMediaList(ex.media || [])
  }

  const handleUploadFile = async () => {
    if (!exerciseId || !mediaFile) {
      alert('Datei wählen')
      return
    }
    const fd = new FormData()
    fd.append('file', mediaFile)
    fd.append('media_type', mediaType)
    fd.append('title', mediaTitle)
    fd.append('description', '')
    fd.append('context', mediaContext)
    fd.append('is_primary', 'false')
    try {
      await api.uploadExerciseMedia(exerciseId, fd)
      setMediaFile(null)
      setMediaTitle('')
      await refreshMedia()
    } catch (err) {
      alert('Upload: ' + err.message)
    }
  }

  const handleAddEmbed = async () => {
    if (!exerciseId || !embedUrl.trim()) {
      alert('Embed-URL eingeben')
      return
    }
    const fd = new FormData()
    fd.append('embed_url', embedUrl.trim())
    fd.append('media_type', 'video')
    fd.append('title', embedTitle)
    fd.append('description', '')
    fd.append('context', mediaContext)
    fd.append('is_primary', 'false')
    try {
      await api.uploadExerciseMedia(exerciseId, fd)
      setEmbedUrl('')
      setEmbedTitle('')
      await refreshMedia()
    } catch (err) {
      alert('Embed: ' + err.message)
    }
  }

  const handleDeleteMedia = async (mid) => {
    if (!confirm('Medium löschen?')) return
    try {
      await api.deleteExerciseMedia(exerciseId, mid)
      await refreshMedia()
    } catch (err) {
      alert(err.message)
    }
  }

  const refreshVariants = async () => {
    if (!exerciseId) return
    const ex = await api.getExercise(exerciseId)
    setVariants((ex.variants || []).map(apiVariantToRow))
  }

  const updateVariantField = (id, patch) => {
    setVariants((prev) => prev.map((v) => (v.id === id ? { ...v, ...patch } : v)))
  }

  const saveVariantRow = async (row) => {
    const payload = buildVariantPayloadFromRow(row)
    if (payload.variant_name.length < 3) {
      alert('Variantenname mindestens 3 Zeichen')
      return
    }
    setVariantSavingId(row.id)
    try {
      await api.updateExerciseVariant(exerciseId, row.id, payload)
      await refreshVariants()
    } catch (e) {
      alert(e.message || String(e))
    } finally {
      setVariantSavingId(null)
    }
  }

  const deleteVariantRow = async (id) => {
    if (!confirm('Variante wirklich löschen?')) return
    setVariantBusy(true)
    try {
      await api.deleteExerciseVariant(exerciseId, id)
      if (variantEditSelection === id) setVariantEditSelection(null)
      await refreshVariants()
    } catch (e) {
      alert(e.message || String(e))
    } finally {
      setVariantBusy(false)
    }
  }

  const moveVariantRow = async (idx, dir) => {
    const j = idx + dir
    if (j < 0 || j >= variants.length) return
    const next = [...variants]
    const tmp = next[idx]
    next[idx] = next[j]
    next[j] = tmp
    const ids = next.map((x) => x.id)
    setVariantBusy(true)
    try {
      await api.reorderExerciseVariants(exerciseId, ids)
      await refreshVariants()
    } catch (e) {
      alert(e.message || String(e))
    } finally {
      setVariantBusy(false)
    }
  }

  const createVariantSubmit = async (e) => {
    e.preventDefault()
    if (!exerciseId) return
    const payload = buildVariantPayloadFromRow(variantDraft)
    if (payload.variant_name.length < 3) {
      alert('Variantenname mindestens 3 Zeichen')
      return
    }
    setVariantBusy(true)
    try {
      const created = await api.createExerciseVariant(exerciseId, payload)
      setVariantDraft(emptyVariantDraft())
      await refreshVariants()
      if (created?.id != null) setVariantEditSelection(created.id)
      else setVariantEditSelection(null)
    } catch (err) {
      alert(err.message || String(err))
    } finally {
      setVariantBusy(false)
    }
  }

  const availableSkills = skillsCatalog.filter((s) => !formData.skills.some((x) => x.skill_id === s.id))

  const selectedVariantForEdit =
    typeof variantEditSelection === 'number' ? variants.find((v) => v.id === variantEditSelection) : null
  const selectedVariantIdx = selectedVariantForEdit
    ? variants.findIndex((v) => v.id === selectedVariantForEdit.id)
    : -1

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

  return (
    <div style={{ padding: '12px' }} className="app-page">
      <div style={{ marginBottom: '12px' }}>
        <button type="button" className="btn btn-secondary" onClick={() => navigate('/exercises')}>
          ← Übersicht
        </button>
        {isEdit && (
          <button
            type="button"
            className="btn btn-secondary"
            style={{ marginLeft: '8px' }}
            onClick={() => navigate(`/exercises/${exerciseId}`)}
          >
            Ansehen
          </button>
        )}
      </div>

      <div className="card">
        <h1 style={{ marginTop: 0, fontSize: '1.25rem' }}>{isEdit ? 'Übung bearbeiten' : 'Neue Übung'}</h1>

        <form onSubmit={handleSubmit}>
          <div className="form-row">
            <label className="form-label">Titel *</label>
            <input
              type="text"
              className="form-input"
              value={formData.title}
              onChange={(e) => updateFormField('title', e.target.value)}
              required
              minLength={3}
            />
          </div>

          <div className="form-row">
            <label className="form-label">Kurzbeschreibung</label>
            <RichTextEditor
              value={formData.summary}
              onChange={(html) => updateFormField('summary', html)}
              placeholder="Kurzbeschreibung (optional)"
              minHeight="80px"
            />
          </div>

          <div className="form-row">
            <label className="form-label">Ziel *</label>
            <RichTextEditor
              value={formData.goal}
              onChange={(html) => updateFormField('goal', html)}
              placeholder="Trainingsziel"
              minHeight="120px"
            />
          </div>

          <div className="form-row">
            <label className="form-label">Durchführung *</label>
            <RichTextEditor
              value={formData.execution}
              onChange={(html) => updateFormField('execution', html)}
              placeholder="Ablauf Schritt für Schritt"
              minHeight="180px"
            />
          </div>

          <div className="form-row">
            <label className="form-label">Vorbereitung / Aufbau</label>
            <RichTextEditor
              value={formData.preparation}
              onChange={(html) => updateFormField('preparation', html)}
              placeholder="Matten, Raum, …"
              minHeight="100px"
            />
          </div>

          <div className="form-row">
            <label className="form-label">Hinweise für Trainer</label>
            <RichTextEditor
              value={formData.trainer_notes}
              onChange={(html) => updateFormField('trainer_notes', html)}
              placeholder="Sicherheit, Varianten-Hinweise, …"
              minHeight="100px"
            />
          </div>

          <div className="form-row">
            <label className="form-label">Material (eine Zeile oder kommagetrennt)</label>
            <textarea
              className="form-input"
              rows={3}
              value={formData.equipmentLines}
              onChange={(e) => updateFormField('equipmentLines', e.target.value)}
              placeholder="Matten&#10;Pratzen"
            />
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' }}>
            <div className="form-row">
              <label className="form-label">Dauer Min</label>
              <input
                type="number"
                className="form-input"
                value={formData.duration_min}
                onChange={(e) =>
                  updateFormField('duration_min', e.target.value ? parseInt(e.target.value, 10) : '')
                }
              />
            </div>
            <div className="form-row">
              <label className="form-label">Dauer Max</label>
              <input
                type="number"
                className="form-input"
                value={formData.duration_max}
                onChange={(e) =>
                  updateFormField('duration_max', e.target.value ? parseInt(e.target.value, 10) : '')
                }
              />
            </div>
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' }}>
            <div className="form-row">
              <label className="form-label">Gruppe Min</label>
              <input
                type="number"
                className="form-input"
                value={formData.group_size_min}
                onChange={(e) =>
                  updateFormField('group_size_min', e.target.value ? parseInt(e.target.value, 10) : '')
                }
              />
            </div>
            <div className="form-row">
              <label className="form-label">Gruppe Max</label>
              <input
                type="number"
                className="form-input"
                value={formData.group_size_max}
                onChange={(e) =>
                  updateFormField('group_size_max', e.target.value ? parseInt(e.target.value, 10) : '')
                }
              />
            </div>
          </div>

          <MultiAssocBlock
            title="Fokusbereiche (0…n, ein „primär“)"
            rows={formData.focus_areas_multi}
            setRows={(r) => updateFormField('focus_areas_multi', r)}
            options={focusAreas}
            idKey="focus_area_id"
            emptyLabel="Keine Zuordnung — optional „+ Eintrag“."
          />

          <MultiAssocBlock
            title="Stilrichtungen (0…n, z. B. Shotokan)"
            rows={formData.training_styles_multi}
            setRows={(r) => updateFormField('training_styles_multi', r)}
            options={styleDirections.map((sd) => ({
              ...sd,
              name: sd.parent_style_name ? `${sd.name} (${sd.parent_style_name})` : sd.name,
            }))}
            idKey="training_style_id"
            emptyLabel="Keine Stilrichtung gewählt."
          />

          <MultiAssocBlock
            title="Trainingsstil (0…n, z. B. Breitensport / Leistungssport)"
            rows={formData.training_types_multi}
            setRows={(r) => updateFormField('training_types_multi', r)}
            options={trainingTypes}
            idKey="training_type_id"
            emptyLabel="Kein Trainingsstil gewählt."
          />

          <MultiAssocBlock
            title="Zielgruppen (0…n)"
            rows={formData.target_groups_multi}
            setRows={(r) => updateFormField('target_groups_multi', r)}
            options={targetGroups}
            idKey="target_group_id"
            emptyLabel="Keine Zielgruppe gewählt."
          />

          <div className="form-row">
            <label className="form-label">Fähigkeiten (je Übung mehrere, mit Niveau)</label>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', marginBottom: '10px' }}>
              <select
                className="form-input"
                style={{ flex: '1 1 200px' }}
                value={skillPick}
                onChange={(e) => setSkillPick(e.target.value)}
              >
                <option value="">Fähigkeit wählen…</option>
                {availableSkills.map((s) => (
                  <option key={s.id} value={s.id}>
                    {s.name} ({s.category})
                  </option>
                ))}
              </select>
              <button type="button" className="btn btn-secondary" onClick={addSkillRow}>
                Hinzufügen
              </button>
            </div>
            {formData.skills.map((row, idx) => {
              const sk = skillsCatalog.find((s) => s.id === row.skill_id)
              return (
                <div key={`${row.skill_id}-${idx}`} className="skills-editor-row">
                  <div>
                    <strong style={{ fontSize: '14px' }}>{sk?.name || `Skill #${row.skill_id}`}</strong>
                    {sk?.category && (
                      <span style={{ color: 'var(--text2)', fontSize: '12px', marginLeft: '6px' }}>
                        {sk.category}
                      </span>
                    )}
                  </div>
                  <label style={{ fontSize: '12px', display: 'flex', alignItems: 'center', gap: '4px' }}>
                    <input
                      type="radio"
                      name="skill-primary"
                      checked={row.is_primary}
                      onChange={() => setSkillPrimary(idx)}
                    />
                    primär
                  </label>
                  <select
                    className="form-input"
                    value={row.intensity || ''}
                    onChange={(e) => updateSkillField(idx, 'intensity', e.target.value)}
                  >
                    {INTENSITY_OPTIONS.map((o) => (
                      <option key={o.value || 'i'} value={o.value}>
                        {o.label}
                      </option>
                    ))}
                  </select>
                  <select
                    className="form-input"
                    value={row.required_level || ''}
                    onChange={(e) => updateSkillField(idx, 'required_level', e.target.value)}
                  >
                    {SKILL_LEVEL_OPTIONS.map((o) => (
                      <option key={`r-${o.value}`} value={o.value}>
                        von {o.label}
                      </option>
                    ))}
                  </select>
                  <select
                    className="form-input"
                    value={row.target_level || ''}
                    onChange={(e) => updateSkillField(idx, 'target_level', e.target.value)}
                  >
                    {SKILL_LEVEL_OPTIONS.map((o) => (
                      <option key={`t-${o.value}`} value={o.value}>
                        bis {o.label}
                      </option>
                    ))}
                  </select>
                  <button type="button" className="btn" style={{ fontSize: '12px', padding: '4px 8px' }} onClick={() => removeSkillRow(idx)}>
                    Entf.
                  </button>
                </div>
              )
            })}
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' }}>
            <div className="form-row">
              <label className="form-label">Sichtbarkeit</label>
              <select
                className="form-input"
                value={formData.visibility}
                onChange={(e) => updateFormField('visibility', e.target.value)}
              >
                <option value="private">Privat</option>
                <option value="club">Verein</option>
                <option value="official">Offiziell</option>
              </select>
            </div>
            <div className="form-row">
              <label className="form-label">Status</label>
              <select
                className="form-input"
                value={formData.status}
                onChange={(e) => updateFormField('status', e.target.value)}
              >
                <option value="draft">Entwurf</option>
                <option value="in_review">In Prüfung</option>
                <option value="approved">Freigegeben</option>
                <option value="archived">Archiviert</option>
              </select>
            </div>
          </div>

          <div style={{ marginTop: '16px' }}>
            <button type="submit" className="btn btn-primary" disabled={saving}>
              {saving ? 'Speichern…' : isEdit ? 'Speichern' : 'Anlegen & weiter'}
            </button>
          </div>
        </form>
      </div>

      {isEdit && (
        <details ref={variantsDetailsRef} className="card exercise-variants-details" style={{ marginTop: '16px' }}>
          <summary className="exercise-variants-summary">
            <span className="exercise-variants-summary__title">Übungsvarianten</span>
            <span className="exercise-variants-summary__badge">
              {variants.length === 0
                ? 'keine'
                : `${variants.length} ${variants.length === 1 ? 'Variante' : 'Varianten'}`}
            </span>
          </summary>
          <div className="exercise-variants-details__body">
            <p className="exercise-variants-hint">
              Pro Durchgang nur eine Variante bearbeiten – weniger Scrollen. Reihenfolge entspricht Planung und Auswahl im
              Training; „Voraussetzung“ nutzt ihr später für Progressions-Serien.
            </p>

            {variants.length > 0 && (
              <div className="form-row">
                <label className="form-label" htmlFor="variant-edit-select">
                  Variante auswählen
                </label>
                <select
                  id="variant-edit-select"
                  className="form-input"
                  value={
                    variantEditSelection === 'new'
                      ? 'new'
                      : variantEditSelection == null
                        ? ''
                        : String(variantEditSelection)
                  }
                  onChange={(e) => {
                    const val = e.target.value
                    if (val === '') setVariantEditSelection(null)
                    else if (val === 'new') setVariantEditSelection('new')
                    else setVariantEditSelection(parseInt(val, 10))
                  }}
                >
                  <option value="">— nicht bearbeiten —</option>
                  {variants.map((v) => (
                    <option key={v.id} value={v.id}>
                      {(v.variant_name && String(v.variant_name).trim()) || `Variante #${v.id}`}
                    </option>
                  ))}
                  <option value="new">+ Neue Variante anlegen…</option>
                </select>
              </div>
            )}

            {variants.length === 0 && (
              <p style={{ fontSize: '13px', color: 'var(--text3)', marginBottom: '10px' }}>
                Noch keine Varianten – optional für andere Ausführung, Dauer oder Material in Planung und Training.
              </p>
            )}

            {variants.length === 0 && variantEditSelection !== 'new' && (
              <button type="button" className="btn btn-secondary" onClick={() => setVariantEditSelection('new')}>
                Erste Variante anlegen
              </button>
            )}

            {variantEditSelection === 'new' && (
              <form
                className="exercise-variant-single-form"
                onSubmit={createVariantSubmit}
                style={{ marginTop: '14px', paddingTop: '14px', borderTop: '1px solid var(--border)' }}
              >
                <h3 style={{ marginTop: 0, fontSize: '1rem' }}>Neue Variante</h3>
                <ExerciseVariantFields
                  row={variantDraft}
                  onPatch={(patch) => setVariantDraft((d) => ({ ...d, ...patch }))}
                  prerequisiteOthers={variants}
                  rteMinHeight="110px"
                />
                <button type="submit" className="btn btn-primary" style={{ marginTop: '10px' }} disabled={variantBusy}>
                  {variantBusy ? 'Anlegen…' : 'Variante anlegen'}
                </button>
              </form>
            )}

            {selectedVariantForEdit && (
              <div
                className="exercise-variant-single-form"
                style={{ marginTop: '14px', paddingTop: '14px', borderTop: '1px solid var(--border)' }}
              >
                <div
                  style={{
                    display: 'flex',
                    flexWrap: 'wrap',
                    gap: '8px',
                    alignItems: 'center',
                    marginBottom: '12px',
                  }}
                >
                  <span style={{ fontSize: '12px', color: 'var(--text3)' }}>
                    Pos. {selectedVariantIdx + 1} von {variants.length}
                  </span>
                  <button
                    type="button"
                    className="btn btn-secondary"
                    style={{ fontSize: '11px', padding: '4px 8px' }}
                    disabled={variantBusy || selectedVariantIdx <= 0}
                    onClick={() => moveVariantRow(selectedVariantIdx, -1)}
                  >
                    Nach oben
                  </button>
                  <button
                    type="button"
                    className="btn btn-secondary"
                    style={{ fontSize: '11px', padding: '4px 8px' }}
                    disabled={variantBusy || selectedVariantIdx >= variants.length - 1}
                    onClick={() => moveVariantRow(selectedVariantIdx, 1)}
                  >
                    Nach unten
                  </button>
                  <button
                    type="button"
                    className="btn btn-primary"
                    style={{ marginLeft: 'auto', fontSize: '12px' }}
                    disabled={variantSavingId === selectedVariantForEdit.id || variantBusy}
                    onClick={() => saveVariantRow(selectedVariantForEdit)}
                  >
                    {variantSavingId === selectedVariantForEdit.id ? 'Speichern…' : 'Speichern'}
                  </button>
                  <button
                    type="button"
                    className="btn"
                    style={{ fontSize: '12px', background: 'var(--danger)', color: '#fff', border: 'none' }}
                    disabled={variantBusy}
                    onClick={() => deleteVariantRow(selectedVariantForEdit.id)}
                  >
                    Löschen
                  </button>
                </div>
                <ExerciseVariantFields
                  row={selectedVariantForEdit}
                  onPatch={(patch) => updateVariantField(selectedVariantForEdit.id, patch)}
                  prerequisiteOthers={variants.filter((o) => o.id !== selectedVariantForEdit.id)}
                  rteMinHeight="110px"
                />
              </div>
            )}

            {variants.length > 0 && variantEditSelection == null && (
              <p style={{ fontSize: '13px', color: 'var(--text3)', marginTop: '12px', marginBottom: 0 }}>
                Wähle eine Variante zum Bearbeiten oder „Neue Variante anlegen…“.
              </p>
            )}
          </div>
        </details>
      )}

      {isEdit && (
        <details className="card exercise-variants-details" style={{ marginTop: '16px' }}>
          <summary className="exercise-variants-summary">
            <span className="exercise-variants-summary__title">Progressionsgraph</span>
            <span className="exercise-variants-summary__badge">Übung → Übung</span>
          </summary>
          <div className="exercise-variants-details__body">
            <ExerciseProgressionGraphPanel anchorExerciseId={exerciseId} anchorTitle={formData.title} />
          </div>
        </details>
      )}

      {isEdit && (
        <div className="card" style={{ marginTop: '16px' }}>
          <h2 style={{ marginTop: 0, fontSize: '1.1rem' }}>Medien</h2>
          <p style={{ color: 'var(--text2)', fontSize: '13px' }}>
            Datei oder Embed (YouTube, Vimeo, Instagram, TikTok). Max. 10 pro Übung.
          </p>
          <div style={{ display: 'grid', gap: '12px', marginTop: '12px' }}>
            <div>
              <label className="form-label">Datei</label>
              <input
                type="file"
                accept="image/jpeg,image/png,image/gif,video/mp4,application/pdf"
                onChange={(e) => setMediaFile(e.target.files?.[0] || null)}
              />
              <div className="form-row" style={{ marginTop: '8px' }}>
                <select className="form-input" value={mediaType} onChange={(e) => setMediaType(e.target.value)}>
                  <option value="image">Bild</option>
                  <option value="video">Video</option>
                  <option value="document">PDF</option>
                </select>
                <input
                  type="text"
                  className="form-input"
                  placeholder="Titel (optional)"
                  value={mediaTitle}
                  onChange={(e) => setMediaTitle(e.target.value)}
                  style={{ marginTop: '8px' }}
                />
                <select
                  className="form-input"
                  value={mediaContext}
                  onChange={(e) => setMediaContext(e.target.value)}
                  style={{ marginTop: '8px' }}
                >
                  <option value="ablauf">Ablauf</option>
                  <option value="detail">Detail</option>
                  <option value="trainer_hint">Trainer-Hinweis</option>
                </select>
              </div>
              <button type="button" className="btn btn-secondary" style={{ marginTop: '8px' }} onClick={handleUploadFile}>
                Hochladen
              </button>
            </div>
            <div>
              <label className="form-label">Embed-URL</label>
              <input
                type="url"
                className="form-input"
                placeholder="https://…"
                value={embedUrl}
                onChange={(e) => setEmbedUrl(e.target.value)}
              />
              <input
                type="text"
                className="form-input"
                placeholder="Titel (optional)"
                value={embedTitle}
                onChange={(e) => setEmbedTitle(e.target.value)}
                style={{ marginTop: '8px' }}
              />
              <button type="button" className="btn btn-secondary" style={{ marginTop: '8px' }} onClick={handleAddEmbed}>
                Embed hinzufügen
              </button>
            </div>
          </div>
          {mediaList.length > 0 && (
            <ul style={{ marginTop: '12px', paddingLeft: '1.2rem' }}>
              {mediaList.map((m) => (
                <li key={m.id} style={{ marginBottom: '6px' }}>
                  {m.title || m.original_filename || m.media_type}{' '}
                  {m.embed_platform ? `(${m.embed_platform})` : ''}
                  <button
                    type="button"
                    className="btn"
                    style={{
                      marginLeft: '8px',
                      fontSize: '11px',
                      padding: '2px 8px',
                      background: 'var(--danger)',
                      color: '#fff',
                      border: 'none',
                    }}
                    onClick={() => handleDeleteMedia(m.id)}
                  >
                    Löschen
                  </button>
                </li>
              ))}
            </ul>
          )}
        </div>
      )}

      <p style={{ fontSize: '12px', color: 'var(--text3)', marginTop: '16px' }}>
        <strong>KI-Ausbaustufe:</strong> Backend laut Spec{' '}
        <code style={{ fontSize: '11px' }}>POST /api/exercises/ai/suggest</code> und{' '}
        <code style={{ fontSize: '11px' }}>POST /api/exercises/{'{id}'}/ai/regenerate</code> — z. B.{' '}
        <code>OPENROUTER_API_KEY</code>, Vorschläge nur nach Trainer-Bestätigung übernehmen (siehe{' '}
        <code>api.suggestExerciseAi</code>).
      </p>
    </div>
  )
}

export default ExerciseFormPage
