/**
 * Kombinationsübung im Coach: Archetyp-Hinweis + Katalog-Inhalt je Slot/Kandidat.
 */
import React, { useEffect, useMemo, useState } from 'react'
import { Link } from 'react-router-dom'
import api from '../utils/api'
import ExerciseRichTextBlock from './ExerciseRichTextBlock'
import {
  archetypeCoachHint,
  combinationArchetypeLabel,
  sortCombinationSlotsForDisplay,
} from '../constants/combinationArchetypes'
import {
  describeGlobalComboProfile,
  effectiveStationTimingSummary,
  METHOD_PROFILE_GUI_FIELDS,
  readSlotProfilesV1,
} from '../utils/combinationMethodProfileUi'

function formatInlineProfileValue(val) {
  if (val === null || val === undefined) return '—'
  if (typeof val === 'boolean') return val ? 'ja' : 'nein'
  if (typeof val === 'number' && Number.isFinite(val)) return String(val)
  if (typeof val === 'string') return val.trim() === '' ? '—' : val
  try {
    return JSON.stringify(val)
  } catch {
    return String(val)
  }
}

export default function CombinationCoachSlots({
  combinationSlots,
  methodArchetype,
  methodProfile,
  compactPlanningView = false,
  omitGlobalKeyValueBlock = false,
  /** Wenn gesetzt: Kandidaten als Button → Peek (kein Router-Wechsel, PWA-sicher) */
  onOpenCandidatePeek,
}) {
  const slots = useMemo(() => sortCombinationSlotsForDisplay(combinationSlots), [combinationSlots])

  const candidateIds = useMemo(() => {
    const set = new Set()
    for (const s of slots) {
      if (Array.isArray(s.candidates) && s.candidates.length) {
        for (const c of s.candidates) {
          const raw = c.exercise_id
          if (raw == null) continue
          const n = typeof raw === 'number' ? raw : parseInt(String(raw), 10)
          if (Number.isFinite(n)) set.add(n)
        }
      } else {
        for (const id of s.candidate_exercise_ids || []) {
          const n = typeof id === 'number' ? id : parseInt(String(id), 10)
          if (Number.isFinite(n)) set.add(n)
        }
      }
    }
    return [...set]
  }, [slots])

  const [byId, setById] = useState({})
  const [errById, setErrById] = useState({})
  const [loadingIds, setLoadingIds] = useState(false)

  const sig = candidateIds.slice().sort((a, b) => a - b).join(',')

  useEffect(() => {
    let cancelled = false
    setById({})
    setErrById({})

    if (candidateIds.length === 0) {
      setLoadingIds(false)
      return () => {
        cancelled = true
      }
    }

    setLoadingIds(true)
    Promise.all(
      candidateIds.map((id) =>
        api.getExercise(id).then(
          (ex) => ({ id, ok: true, ex }),
          (e) => ({
            id,
            ok: false,
            err: e?.message || String(e),
          }),
        ),
      ),
    ).then((results) => {
      if (cancelled) return
      const map = {}
      const emap = {}
      for (const r of results) {
        if (r.ok) map[r.id] = r.ex
        else emap[r.id] = r.err
      }
      setById(map)
      setErrById(emap)
      setLoadingIds(false)
    })

    return () => {
      cancelled = true
    }
  }, [sig])

  const archeKey = methodArchetype != null ? String(methodArchetype).trim() : ''
  const archDisplay = archeKey ? combinationArchetypeLabel(archeKey) : null

  const slotTimingByIx = useMemo(() => {
    if (!methodProfile || typeof methodProfile !== 'object' || Array.isArray(methodProfile)) return new Map()
    const rows = readSlotProfilesV1(methodProfile)
    const m = new Map()
    for (const r of rows) {
      m.set(Number(r.slot_index), r)
    }
    return m
  }, [methodProfile])

  const globalComboRows = useMemo(
    () => describeGlobalComboProfile(archeKey, methodProfile || {}),
    [archeKey, methodProfile],
  )

  const profileExtraEntries = useMemo(() => {
    if (!methodProfile || typeof methodProfile !== 'object' || Array.isArray(methodProfile)) return []
    const known = new Set(['slot_profiles_v1'])
    for (const f of METHOD_PROFILE_GUI_FIELDS[archeKey] || []) {
      known.add(f.key)
    }
    const out = []
    for (const [k, val] of Object.entries(methodProfile)) {
      if (known.has(k)) continue
      if (val === null || val === undefined || val === '') continue
      out.push([k, val])
    }
    return out.sort((a, b) => String(a[0]).localeCompare(String(b[0]), 'de'))
  }, [methodProfile, archeKey])

  return (
    <section
      className="card"
      style={{
        marginBottom: '14px',
        padding: '12px 14px',
        borderLeft: '3px solid var(--accent-dark)',
        background: 'var(--surface2)',
      }}
    >
      <h3
        style={{
          fontSize: '0.72rem',
          textTransform: 'uppercase',
          color: 'var(--text3)',
          margin: '0 0 6px',
          letterSpacing: '0.04em',
        }}
      >
        {compactPlanningView ? 'Stationen & Einzelübungen (Katalog)' : 'Kombination · Stationen & Einzelübungen'}
      </h3>
      {archDisplay ? (
        <p style={{ margin: '0 0 6px', fontSize: '0.95rem', fontWeight: 700 }}>{archDisplay}</p>
      ) : null}
      {compactPlanningView ? null : (
      <p style={{ margin: '0 0 14px', fontSize: '0.88rem', color: 'var(--text2)', lineHeight: 1.48 }}>
        {archetypeCoachHint(archeKey)}
      </p>
      )}

      {methodProfile && typeof methodProfile === 'object' && !Array.isArray(methodProfile) && Object.keys(methodProfile).length && !omitGlobalKeyValueBlock ? (
        <div
          style={{
            margin: '0 0 14px',
            padding: '8px 10px',
            borderRadius: '8px',
            background: 'var(--surface)',
            border: '1px solid var(--border)',
          }}
        >
          <div style={{ fontSize: '0.7rem', fontWeight: 700, color: 'var(--text3)', textTransform: 'uppercase', marginBottom: '6px' }}>
            Globale Eckdaten (wie im Editor)
          </div>
          {globalComboRows.length === 0 && profileExtraEntries.length === 0 ? (
            <p style={{ margin: 0, fontSize: '0.82rem', color: 'var(--text3)', lineHeight: 1.42 }}>
              Keine globalen Zahlenfelder gesetzt — Zeiten und Steuerung siehe je Station unter „Plan:“ (oder nur im Freitext der Kombination).
            </p>
          ) : (
            <dl style={{ margin: 0, fontSize: '0.82rem', lineHeight: 1.45 }}>
              {globalComboRows.map((row) => (
                <div
                  key={row.key}
                  style={{
                    marginBottom: '6px',
                    display: 'grid',
                    gridTemplateColumns: 'minmax(88px,1fr) minmax(0,1.4fr)',
                    gap: '6px 10px',
                  }}
                >
                  <dt style={{ margin: 0, fontWeight: 600, color: 'var(--text3)' }}>{row.detailLabel}</dt>
                  <dd style={{ margin: 0, color: 'var(--text1)', fontWeight: 600 }}>{row.value}</dd>
                </div>
              ))}
              {profileExtraEntries.map(([k, val]) => (
                <div
                  key={k}
                  style={{
                    marginBottom: '4px',
                    display: 'grid',
                    gridTemplateColumns: 'minmax(88px,1fr) minmax(0,1.4fr)',
                    gap: '6px 10px',
                  }}
                >
                  <dt style={{ margin: 0, fontWeight: 600, color: 'var(--text3)', wordBreak: 'break-all' }}>{k}</dt>
                  <dd style={{ margin: 0, color: 'var(--text1)' }}>{formatInlineProfileValue(val)}</dd>
                </div>
              ))}
            </dl>
          )}
        </div>
      ) : null}

      {!slots.length ? (
        <p style={{ margin: 0, color: 'var(--text3)', fontSize: '0.88rem' }}>Keine Stationen hinterlegt.</p>
      ) : (
        <ol style={{ margin: 0, paddingLeft: '1.1rem', display: 'flex', flexDirection: 'column', gap: '14px' }}>
          {slots.map((slot, si) => {
            const candIdsRaw = slot.candidate_exercise_ids || []
            const candIds = candIdsRaw
              .map((id) => (typeof id === 'number' ? id : parseInt(String(id), 10)))
              .filter((n) => Number.isFinite(n))

            const slotTitle =
              (slot.title && String(slot.title).trim()) ||
              (candIds.length <= 1 && slot.candidates?.[0]?.title) ||
              `Station ${si + 1}`

            const ix = slot.slot_index != null ? Number(slot.slot_index) : si
            const timingSummary = effectiveStationTimingSummary(archeKey, methodProfile || {}, slotTimingByIx.get(ix))

            return (
              <li key={`${slot.slot_index ?? si}-${slotTitle}`} style={{ lineHeight: 1.45 }}>
                <div style={{ fontWeight: 700, fontSize: '0.92rem', marginBottom: timingSummary ? '4px' : candIds.length > 1 ? '6px' : '8px' }}>
                  {slotTitle}
                </div>
                {timingSummary ? (
                  <p style={{ margin: '0 0 8px', fontSize: '0.78rem', color: 'var(--text2)', lineHeight: 1.42 }}>
                    Plan: <span style={{ color: 'var(--text1)', fontWeight: 600 }}>{timingSummary}</span>
                  </p>
                ) : null}
                {candIds.length === 0 ? (
                  <p style={{ margin: 0, color: 'var(--text3)', fontSize: '0.86rem' }}>Keine Übung zugeordnet.</p>
                ) : (
                  <div style={{ display: 'flex', flexDirection: 'column', gap: '12px', paddingLeft: 0 }}>
                    {candIds.map((cid, ci) => {
                      const ex = byId[cid]
                      const err = errById[cid]
                      const candTitleFallback =
                        slot.candidates?.find((c) => Number(c.exercise_id) === cid)?.title ||
                        slot.candidates?.[ci]?.title

                      const isAlt = candIds.length > 1

                      return (
                        <div
                          key={`${cid}-${ci}`}
                          style={{
                            padding: '10px 11px',
                            borderRadius: '8px',
                            border: '1px solid var(--border)',
                            background: 'var(--surface)',
                          }}
                        >
                          {isAlt ? (
                            <div style={{ fontSize: '0.72rem', textTransform: 'uppercase', color: 'var(--text3)', marginBottom: '4px' }}>
                              {candIds.length > 2 ? `Alternative ${ci + 1}` : ci === 0 ? 'Alternative A' : 'Alternative B'}
                            </div>
                          ) : null}
                          {!ex && loadingIds ? (
                            <div style={{ display: 'flex', gap: '8px', alignItems: 'center', fontSize: '0.86rem', color: 'var(--text2)' }}>
                              <span className="spinner" style={{ transform: 'scale(0.7)' }} />
                              Übung #{cid} laden…
                            </div>
                          ) : err ? (
                            <p style={{ margin: 0, color: 'var(--danger)', fontSize: '0.88rem' }}>
                              Übung #{cid}: {err}
                            </p>
                          ) : ex ? (
                            compactPlanningView ? (
                              <>
                                <p style={{ margin: '0 0 4px', fontSize: '0.96rem', fontWeight: 700 }}>{ex.title}</p>
                                <p style={{ margin: 0 }}>
                                  {typeof onOpenCandidatePeek === 'function' ? (
                                    <button
                                      type="button"
                                      className="combo-coach-cand-link"
                                      onClick={() => onOpenCandidatePeek(cid)}
                                    >
                                      Details anzeigen
                                    </button>
                                  ) : (
                                    <Link to={`/exercises/${cid}`} style={{ fontSize: '0.82rem', color: 'var(--accent)' }}>
                                      Im Katalog öffnen
                                    </Link>
                                  )}
                                </p>
                              </>
                            ) : (
                            <>
                              <p style={{ margin: '0 0 6px', fontSize: '0.96rem', fontWeight: 700 }}>{ex.title}</p>
                              {ex.summary ? (
                                <div style={{ marginBottom: ex.execution ? '8px' : 0 }}>
                                  <ExerciseRichTextBlock html={ex.summary} exerciseId={ex.id} media={ex.media} />
                                </div>
                              ) : (
                                <p style={{ margin: '0 0 6px', fontSize: '0.86rem', color: 'var(--text3)' }}>
                                  Keine Kurzbeschreibung im Katalog.
                                </p>
                              )}
                              {ex.execution ? (
                                <details style={{ marginTop: '4px' }}>
                                  <summary style={{ cursor: 'pointer', fontSize: '0.82rem', color: 'var(--accent-dark)', fontWeight: 600 }}>
                                    Ablauf (Detail)
                                  </summary>
                                  <div style={{ marginTop: '8px' }}>
                                    <ExerciseRichTextBlock html={ex.execution} exerciseId={ex.id} media={ex.media} />
                                  </div>
                                </details>
                              ) : null}
                              {ex.trainer_notes ? (
                                <details style={{ marginTop: '6px' }}>
                                  <summary style={{ cursor: 'pointer', fontSize: '0.82rem', color: 'var(--accent-dark)', fontWeight: 600 }}>
                                    Hinweise Trainer
                                  </summary>
                                  <div style={{ marginTop: '8px' }}>
                                    <ExerciseRichTextBlock html={ex.trainer_notes} exerciseId={ex.id} media={ex.media} />
                                  </div>
                                </details>
                              ) : null}
                              <p style={{ marginTop: '8px', marginBottom: 0 }}>
                                {typeof onOpenCandidatePeek === 'function' ? (
                                  <button
                                    type="button"
                                    className="combo-coach-cand-link"
                                    onClick={() => onOpenCandidatePeek(cid)}
                                  >
                                    Volle Übungsansicht
                                  </button>
                                ) : (
                                  <Link to={`/exercises/${cid}`} style={{ fontSize: '0.84rem', color: 'var(--accent)' }}>
                                    Volle Übungsseite
                                  </Link>
                                )}
                              </p>
                            </>
                            )
                          ) : (
                            <p style={{ margin: 0, fontSize: '0.86rem', color: 'var(--text2)' }}>
                              {candTitleFallback || `Übung #${cid}`}
                            </p>
                          )}
                        </div>
                      )
                    })}
                  </div>
                )}
              </li>
            )
          })}
        </ol>
      )}
    </section>
  )
}
