import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { Link, useNavigate, useParams } from 'react-router-dom'
import api from '../utils/api'
import ExercisePickerModal from '../components/ExercisePickerModal'
import { hydrateExercisePlanningRow } from '../utils/trainingUnitSectionsForm'
import { useAuth } from '../context/AuthContext'
import { activeClubMemberships, getResolvedActiveClubIdForUi } from '../utils/activeClub'

function nextLocalKey() {
  return `m-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`
}

function swapItems(arr, i, j) {
  if (i === j || i < 0 || j < 0 || i >= arr.length || j >= arr.length) return [...arr]
  const n = [...arr]
  ;[n[i], n[j]] = [n[j], n[i]]
  return n
}

export default function TrainingModuleEditPage() {
  const { id: routeId } = useParams()
  const navigate = useNavigate()
  const isNew = !routeId || routeId === 'new'
  const moduleId = !isNew ? parseInt(routeId, 10) : NaN

  const [loading, setLoading] = useState(!isNew)
  const [saving, setSaving] = useState(false)
  const [methods, setMethods] = useState([])
  const [pickerOpen, setPickerOpen] = useState(false)
  const [error, setError] = useState('')

  const [title, setTitle] = useState('')
  const [summary, setSummary] = useState('')
  const [goal, setGoal] = useState('')
  const [recommendedDurationMin, setRecommendedDurationMin] = useState('')
  const [targetGroupNotes, setTargetGroupNotes] = useState('')
  const [deploymentContextNotes, setDeploymentContextNotes] = useState('')
  const [visibility, setVisibility] = useState('club')
  const [clubIdField, setClubIdField] = useState('')
  const [primaryMethodId, setPrimaryMethodId] = useState('')
  const [items, setItems] = useState([])

  const { user } = useAuth()
  const clubChoices = useMemo(() => activeClubMemberships(user?.clubs ?? []), [user?.clubs])

  useEffect(() => {
    if (!isNew || visibility !== 'club') return
    if ((clubIdField || '').trim() !== '') return
    if (clubChoices.length === 1) setClubIdField(String(clubChoices[0].id))
    else {
      const r = getResolvedActiveClubIdForUi(user)
      if (r) setClubIdField(String(r))
    }
  }, [isNew, visibility, clubIdField, clubChoices, user])

  const itemsPayload = items.map((it, i) => {
    if (it.item_type === 'note') {
      return { item_type: 'note', order_index: i, note_body: it.note_body ?? '' }
    }
    const vid =
      it.exercise_variant_id !== '' && it.exercise_variant_id != null
        ? parseInt(it.exercise_variant_id, 10)
        : null
    return {
      item_type: 'exercise',
      order_index: i,
      exercise_id: parseInt(it.exercise_id, 10),
      exercise_variant_id: Number.isFinite(vid) ? vid : null,
      planned_duration_min:
        it.planned_duration_min !== '' && it.planned_duration_min != null
          ? parseInt(String(it.planned_duration_min), 10)
          : null,
      notes: it.notes?.trim() ? it.notes.trim() : null,
    }
  })

  const loadCatalogs = useCallback(async () => {
    try {
      const m = await api.listMethods({})
      setMethods(Array.isArray(m) ? m : [])
    } catch {
      setMethods([])
    }
  }, [])

  useEffect(() => {
    loadCatalogs()
  }, [loadCatalogs])

  useEffect(() => {
    if (isNew || !Number.isFinite(moduleId)) {
      setLoading(false)
      return
    }
    let cancelled = false
    async function load() {
      setLoading(true)
      setError('')
      try {
        const m = await api.getTrainingModule(moduleId)
        if (cancelled) return
        setTitle((m.title || '').trim())
        setSummary((m.summary || '').trim())
        setGoal(m.goal || '')
        setRecommendedDurationMin(
          m.recommended_duration_min != null && m.recommended_duration_min !== ''
            ? String(m.recommended_duration_min)
            : ''
        )
        setTargetGroupNotes(m.target_group_notes || '')
        setDeploymentContextNotes(m.deployment_context_notes || '')
        setVisibility((m.visibility || 'club').trim())
        setClubIdField(m.club_id != null ? String(m.club_id) : '')
        setPrimaryMethodId(m.primary_method_id != null ? String(m.primary_method_id) : '')
        const nextItems = []
        for (const row of Array.isArray(m.items) ? m.items : []) {
          if (row.item_type === 'note') {
            nextItems.push({ localKey: nextLocalKey(), item_type: 'note', note_body: row.note_body || '' })
            continue
          }
          const ex = await hydrateExercisePlanningRow({
            id: row.exercise_id,
            title: '',
            variants: [],
          })
          if (ex) {
            ex.localKey = nextLocalKey()
            if (row.exercise_variant_id) ex.exercise_variant_id = String(row.exercise_variant_id)
            ex.planned_duration_min =
              row.planned_duration_min != null && row.planned_duration_min !== ''
                ? String(row.planned_duration_min)
                : ''
            ex.notes = row.notes || ''
            nextItems.push(ex)
          }
        }
        setItems(nextItems)
      } catch (e) {
        if (!cancelled) setError(e.message || 'Laden fehlgeschlagen')
      } finally {
        if (!cancelled) setLoading(false)
      }
    }
    load()
    return () => {
      cancelled = true
    }
  }, [isNew, moduleId])

  const buildBody = () => {
    let cid = null
    if (visibility === 'club') {
      const raw = (clubIdField || '').trim()
      if (raw !== '') {
        const p = parseInt(raw, 10)
        if (Number.isFinite(p) && p >= 1) cid = p
      } else if (clubChoices.length === 1) {
        cid = clubChoices[0].id
      }
    }
    const pm =
      primaryMethodId !== '' && primaryMethodId != null ? parseInt(primaryMethodId, 10) : null
    return {
      title: title.trim(),
      summary: summary.trim() || null,
      goal: goal.trim() || null,
      recommended_duration_min:
        recommendedDurationMin !== '' ? parseInt(recommendedDurationMin, 10) : null,
      target_group_notes: targetGroupNotes.trim() || null,
      deployment_context_notes: deploymentContextNotes.trim() || null,
      visibility,
      club_id:
        cid != null && Number.isFinite(cid) && cid >= 1
          ? cid
          : visibility === 'club'
            ? undefined
            : null,
      primary_method_id:
        pm != null && Number.isFinite(pm) && pm >= 1 ? pm : null,
      items: itemsPayload.filter((row) =>
        row.item_type === 'note' ? true : Number.isFinite(row.exercise_id) && row.exercise_id >= 1
      ),
    }
  }

  const handleSave = async (e) => {
    e.preventDefault()
    if (!title.trim()) {
      alert('Titel ist Pflicht.')
      return
    }
    setSaving(true)
    setError('')
    try {
      const body = buildBody()
      if (isNew) {
        const created = await api.createTrainingModule(body)
        navigate(`/planning/training-modules/${created.id}`, { replace: true })
      } else {
        await api.updateTrainingModule(moduleId, body)
        alert('Trainingsmodul gespeichert.')
      }
    } catch (err) {
      setError(err.message || 'Speichern fehlgeschlagen')
    } finally {
      setSaving(false)
    }
  }

  const pickExercise = async (ex) => {
    if (!ex?.id) return
    const row = await hydrateExercisePlanningRow(ex)
    if (row) row.localKey = nextLocalKey()
    if (row) setItems((prev) => [...prev, row])
    setPickerOpen(false)
  }

  return (
    <div className="app-page">
      <p style={{ marginBottom: '0.75rem' }}>
        <Link to="/planning/training-modules" style={{ color: 'var(--accent-dark)', fontWeight: 600 }}>
          ← Zurück zur Modul‑Bibliothek
        </Link>
      </p>
      <h1 className="page-title">{isNew ? 'Neues Trainingsmodul' : 'Trainingsmodul bearbeiten'}</h1>
      <p style={{ color: 'var(--text2)', fontSize: '0.95rem', marginBottom: '1.25rem', maxWidth: '40rem' }}>
        Reihenfolge der Positionen entspricht der späteren Übernahme in einen Abschnitt der Einheit (Kopie).
      </p>

      {error ? <p style={{ color: 'var(--danger)', marginBottom: '1rem' }}>{error}</p> : null}
      {loading ? (
        <p style={{ color: 'var(--text2)' }}>Laden …</p>
      ) : (
        <form className="card" style={{ padding: 'clamp(14px, 3vw, 1.75rem)', maxWidth: '720px' }} onSubmit={handleSave}>
          <div className="form-row">
            <label className="form-label">Titel *</label>
            <input className="form-input" value={title} onChange={(e) => setTitle(e.target.value)} />
          </div>
          <div className="form-row">
            <label className="form-label">Kurzbeschreibung</label>
            <textarea className="form-input" rows={2} value={summary} onChange={(e) => setSummary(e.target.value)} />
          </div>
          <div className="form-row">
            <label className="form-label">Ziel</label>
            <textarea className="form-input" rows={3} value={goal} onChange={(e) => setGoal(e.target.value)} />
          </div>
          <div className="form-row" style={{ display: 'grid', gap: '1rem', gridTemplateColumns: '1fr 1fr' }}>
            <div>
              <label className="form-label">Empfohlene Dauer (Min.)</label>
              <input
                className="form-input"
                type="number"
                min={0}
                value={recommendedDurationMin}
                onChange={(e) => setRecommendedDurationMin(e.target.value)}
              />
            </div>
            <div>
              <label className="form-label">Primäre Trainingsmethode</label>
              <select
                className="form-input"
                value={primaryMethodId}
                onChange={(e) => setPrimaryMethodId(e.target.value)}
              >
                <option value="">—</option>
                {methods.map((m) => (
                  <option key={m.id} value={String(m.id)}>
                    {(m.name || '').trim() || `Methode #${m.id}`}
                  </option>
                ))}
              </select>
            </div>
          </div>
          <div className="form-row">
            <label className="form-label">Empfohlene Zielgruppe (Freitext)</label>
            <textarea
              className="form-input"
              rows={2}
              value={targetGroupNotes}
              onChange={(e) => setTargetGroupNotes(e.target.value)}
            />
          </div>
          <div className="form-row">
            <label className="form-label">Einsatz / Kontext</label>
            <textarea
              className="form-input"
              rows={2}
              value={deploymentContextNotes}
              onChange={(e) => setDeploymentContextNotes(e.target.value)}
            />
          </div>

          <div className="form-row" style={{ display: 'grid', gap: '1rem', gridTemplateColumns: '1fr 1fr' }}>
            <div>
              <label className="form-label">Sichtbarkeit</label>
              <select
                className="form-input"
                value={visibility}
                onChange={(e) => {
                  const v = e.target.value
                  setVisibility(v)
                  if (v !== 'club') {
                    setClubIdField('')
                    return
                  }
                  const xs = clubChoices
                  if (xs.length === 1) setClubIdField(String(xs[0].id))
                  else if (xs.length === 0) setClubIdField('')
                  else {
                    const resolved = getResolvedActiveClubIdForUi(user)
                    setClubIdField(resolved != null ? String(resolved) : '')
                  }
                }}
              >
                <option value="private">Privat</option>
                <option value="club">Vereinsintern</option>
                <option value="official">Offiziell</option>
              </select>
            </div>
            <div>
              <label className="form-label">Verein (bei „Vereinsintern“)</label>
              {visibility !== 'club' ? (
                <p style={{ margin: '0.25rem 0 0', fontSize: '0.85rem', color: 'var(--text3)', lineHeight: 1.45 }}>
                  Bei privaten oder offiziellen Modulen ist keine Vereinszuordnung nötig (Server legt keine
                  Vereinsbindung fest).
                </p>
              ) : clubChoices.length === 0 ? (
                <p style={{ margin: '0.25rem 0 0', fontSize: '0.85rem', color: 'var(--danger)', lineHeight: 1.45 }}>
                  Kein aktiver Verein im Profil — bitte zuerst einem Verein beitreten.
                </p>
              ) : clubChoices.length === 1 ? (
                <>
                  <input
                    className="form-input"
                    disabled
                    readOnly
                    value={
                      (clubChoices[0].short_name || clubChoices[0].name || '').trim() ||
                      `Verein #${clubChoices[0].id}`
                    }
                  />
                  <p style={{ margin: '0.35rem 0 0', fontSize: '0.82rem', color: 'var(--text3)', lineHeight: 1.45 }}>
                    Fixiert durch deine Mitgliedschaft. Verein-ID {clubChoices[0].id} wird beim Speichern verwendet.
                  </p>
                </>
              ) : (
                <>
                  <select
                    className="form-input"
                    value={clubIdField}
                    onChange={(e) => setClubIdField(e.target.value)}
                  >
                    <option value="">Automatisch (aktueller Verein im Profil)</option>
                    {clubChoices.map((c) => {
                      const ln = `${((c.short_name || c.name || '').trim() || '') || `Verein #${c.id}`}`
                      return (
                        <option key={c.id} value={String(c.id)}>
                          {ln}
                        </option>
                      )
                    })}
                  </select>
                  <p style={{ margin: '0.35rem 0 0', fontSize: '0.82rem', color: 'var(--text3)', lineHeight: 1.45 }}>
                    Bei „Automatisch“ entscheidet der aktiv gewählte Verein beim Speichern (wie bei anderen
                    Bibliotheksinhalten).
                  </p>
                </>
              )}
            </div>
          </div>

          <hr style={{ border: 'none', borderTop: '1px solid var(--border)', margin: '1.25rem 0' }} />

          <h3 style={{ fontSize: '1rem', marginBottom: '0.75rem' }}>Positionen</h3>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px', marginBottom: '12px' }}>
            <button type="button" className="btn btn-secondary" onClick={() => setPickerOpen(true)}>
              Übung hinzufügen
            </button>
            <button
              type="button"
              className="btn btn-secondary"
              onClick={() =>
                setItems((prev) => [...prev, { localKey: nextLocalKey(), item_type: 'note', note_body: '' }])
              }
            >
              Notiz hinzufügen
            </button>
          </div>

          <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: '10px' }}>
            {items.map((it, idx) => (
              <li key={it.localKey || idx} style={{ padding: '10px', background: 'var(--surface2)', borderRadius: '8px' }}>
                {it.item_type === 'note' ? (
                  <div>
                    <span style={{ fontWeight: 600, fontSize: '0.85rem', color: 'var(--text3)' }}>Notiz</span>
                    <textarea
                      className="form-input"
                      style={{ marginTop: '8px' }}
                      rows={2}
                      value={it.note_body}
                      onChange={(e) => {
                        const v = e.target.value
                        setItems((prev) =>
                          prev.map((x, j) =>
                            j === idx && x.item_type === 'note' ? { ...x, note_body: v } : x
                          )
                        )
                      }}
                    />
                  </div>
                ) : (
                  <>
                    <div style={{ fontWeight: 700, wordBreak: 'break-word', marginBottom: '8px' }}>
                      {(it.exercise_title || '').trim() || `Übung #${it.exercise_id}`}
                    </div>
                    <div style={{ display: 'grid', gap: '8px', gridTemplateColumns: '1fr 1fr' }}>
                      <div>
                        <label className="form-label" style={{ fontSize: '0.78rem' }}>
                          Variante
                        </label>
                        <select
                          className="form-input"
                          value={String(it.exercise_variant_id ?? '')}
                          onChange={(e) => {
                            const v = e.target.value
                            setItems((prev) =>
                              prev.map((row, j) =>
                                j === idx && row.item_type === 'exercise' ? { ...row, exercise_variant_id: v } : row
                              )
                            )
                          }}
                        >
                          <option value="">—</option>
                          {(it.variants || []).map((v) => (
                            <option key={v.id} value={String(v.id)}>
                              {(v.name || '').trim() || `Variante #${v.id}`}
                            </option>
                          ))}
                        </select>
                      </div>
                      <div>
                        <label className="form-label" style={{ fontSize: '0.78rem' }}>
                          Minuten (plan)
                        </label>
                        <input
                          className="form-input"
                          type="number"
                          min={0}
                          value={it.planned_duration_min}
                          onChange={(e) =>
                            setItems((prev) =>
                              prev.map((row, j) =>
                                j === idx && row.item_type === 'exercise'
                                  ? { ...row, planned_duration_min: e.target.value }
                                  : row
                              )
                            )
                          }
                        />
                      </div>
                    </div>
                    <div style={{ marginTop: '8px' }}>
                      <label className="form-label" style={{ fontSize: '0.78rem' }}>
                        Hinweis zur Position
                      </label>
                      <input
                        className="form-input"
                        value={it.notes ?? ''}
                        onChange={(e) =>
                          setItems((prev) =>
                            prev.map((row, j) =>
                              j === idx && row.item_type === 'exercise' ? { ...row, notes: e.target.value } : row
                            )
                          )
                        }
                      />
                    </div>
                  </>
                )}
                <div style={{ display: 'flex', gap: '8px', marginTop: '10px', flexWrap: 'wrap' }}>
                  <button
                    type="button"
                    className="btn btn-secondary"
                    disabled={idx < 1}
                    onClick={() => setItems((prev) => swapItems(prev, idx, idx - 1))}
                  >
                    Nach oben
                  </button>
                  <button
                    type="button"
                    className="btn btn-secondary"
                    disabled={idx >= items.length - 1}
                    onClick={() => setItems((prev) => swapItems(prev, idx, idx + 1))}
                  >
                    Nach unten
                  </button>
                  <button
                    type="button"
                    className="btn btn-secondary"
                    onClick={() => setItems((prev) => prev.filter((_, j) => j !== idx))}
                  >
                    Entfernen
                  </button>
                </div>
              </li>
            ))}
          </ul>

          <div style={{ display: 'flex', gap: '10px', marginTop: '1.5rem', flexWrap: 'wrap' }}>
            <button type="submit" className="btn btn-primary" disabled={saving}>
              {saving ? 'Speichern …' : isNew ? 'Anlegen' : 'Speichern'}
            </button>
            <Link to="/planning/training-modules" className="btn btn-secondary" style={{ textDecoration: 'none' }}>
              Abbrechen
            </Link>
          </div>
        </form>
      )}

      <ExercisePickerModal open={pickerOpen} onClose={() => setPickerOpen(false)} onSelectExercise={pickExercise} />
    </div>
  )
}
