import React, { useMemo, useState } from 'react'
import { archetypeCoachHint, combinationArchetypeLabel, sortCombinationSlotsForDisplay } from '../constants/combinationArchetypes'
import {
  METHOD_PROFILE_GUI_FIELDS,
  parseProfileJson,
  setFullProfileRawJson,
  updateProfileGuided,
  patchMethodProfile,
  readSlotProfilesV1,
  patchSlotTimingField,
  patchSlotAdvanceMode,
  normalizeAdvanceMode,
  parseComboRepSeriesCountUi,
  applyCircuitRotateQuickRatio,
  applyIntervalDomainQuickRatio,
} from '../utils/combinationMethodProfileUi'

function clampInt(n, min, max) {
  if (!Number.isFinite(n)) return null
  let x = n
  if (typeof min === 'number' && x < min) x = min
  if (typeof max === 'number' && x > max) x = max
  return Math.round(x)
}

/** Archetypen mit klar bezifferbarer Stationslogik · alle mit Slot-Liste sinnvoll */
const ARCHETYPES_WITH_SLOT_TIMING = new Set([
  'circuit_rotate_time',
  'sequence_linear',
  'station_parcour',
  'time_domain_interval',
  'circuit_all_parallel',
  'pair_superset',
  'free_method_block',
])

/**
 * Kombination: geführtes method_profile (+ optional Stationszeilen, ohne JSON für Trainer).
 *
 * @param {boolean} [props.plannerMode] — z. B. Planungs‑Override: keine Roh‑JSON‑Sektion.
 * @param {boolean} [props.allowExpertJson] — wenn true und nicht plannerMode: Roh‑JSON (Support).
 * @param {{ slot_index?: number|string, title?: string }[]} [props.comboSlotsOutline] — für Slot‑Felder aus der Übung
 */
export default function CombinationMethodProfileEditor({
  methodArchetype,
  methodProfileJson,
  onChangeMethodProfileJson,
  plannerMode = false,
  allowExpertJson = false,
  comboSlotsOutline = null,
  omitPerSlotTiming = false,
}) {
  const arch = typeof methodArchetype === 'string' ? methodArchetype.trim() : ''
  const fieldsGui = METHOD_PROFILE_GUI_FIELDS[arch]
  const fields = Array.isArray(fieldsGui) ? fieldsGui : null
  const parseState = useMemo(() => parseProfileJson(methodProfileJson || '{}'), [methodProfileJson])
  const [rawOpenError, setRawOpenError] = useState(null)
  const [rawDraft, setRawDraft] = useState(null)
  const [presetHint, setPresetHint] = useState(null)

  const profileObj = parseState.ok ? parseState.obj : {}

  const outlineSorted = useMemo(() => {
    if (!comboSlotsOutline || !Array.isArray(comboSlotsOutline) || comboSlotsOutline.length === 0) return []
    return sortCombinationSlotsForDisplay(comboSlotsOutline)
  }, [comboSlotsOutline])

  const showSlotTiming =
    !omitPerSlotTiming && ARCHETYPES_WITH_SLOT_TIMING.has(arch) && outlineSorted.length > 0

  const slotRowsModel = useMemo(() => readSlotProfilesV1(profileObj), [profileObj])

  const lookupSlotTiming = (slotIndex) =>
    slotRowsModel.find((r) => Number(r.slot_index) === Number(slotIndex)) || {}

  const applyGuided = (key, value, kind) => {
    if (kind === 'bool') {
      const res = updateProfileGuided(arch, methodProfileJson || '{}', key, value, 'bool')
      if (!res.ok) return
      onChangeMethodProfileJson(res.json)
      setPresetHint(null)
      return
    }
    if (value === '' || value === undefined || value === null) {
      const res = updateProfileGuided(arch, methodProfileJson || '{}', key, '', 'int')
      if (!res.ok) return
      onChangeMethodProfileJson(res.json)
      setPresetHint(null)
      return
    }
    const num = typeof value === 'number' ? value : parseInt(String(value), 10)
    if (!Number.isFinite(num)) return
    const def = METHOD_PROFILE_GUI_FIELDS[arch]?.find((f) => f.key === key && f.kind === 'int')
    const c = clampInt(num, def?.min, def?.max)
    if (c == null) return
    const res = updateProfileGuided(arch, methodProfileJson || '{}', key, c, 'int')
    if (!res.ok) return
    onChangeMethodProfileJson(res.json)
    setPresetHint(null)
  }

  const onSlotField = (slotIx, field, rawStr) => {
    const patched = patchMethodProfile(methodProfileJson || '{}', (d) =>
      patchSlotTimingField(d, slotIx, field, rawStr)
    )
    if (!patched.ok) return
    onChangeMethodProfileJson(patched.json)
    setPresetHint(null)
  }

  const onSlotAdvanceChange = (slotIx, rawMode) => {
    const patched = patchMethodProfile(methodProfileJson || '{}', (d) =>
      patchSlotAdvanceMode(d, slotIx, rawMode)
    )
    if (!patched.ok) return
    onChangeMethodProfileJson(patched.json)
    setPresetHint(null)
  }

  const onSlotRepSeriesCount = (slotIx, rawStr) => {
    const trimmed = String(rawStr ?? '').trim()
    const effective = trimmed === '' ? '1' : trimmed
    const pn = parseInt(effective, 10)
    const clearIntra = !Number.isFinite(pn) || pn < 2
    const patched = patchMethodProfile(methodProfileJson || '{}', (d) => {
      patchSlotTimingField(d, slotIx, 'rep_series_count', effective)
      if (clearIntra) patchSlotTimingField(d, slotIx, 'intra_rep_rest_sec', '')
    })
    if (!patched.ok) return
    onChangeMethodProfileJson(patched.json)
    setPresetHint(null)
  }

  const runCircuitPreset = (presetId) => {
    const r = patchMethodProfile(methodProfileJson || '{}', (draft) => {
      const pr = applyCircuitRotateQuickRatio(draft, presetId)
      if (!pr.ok) setPresetHint(pr.error || '')
      else setPresetHint(null)
    })
    if (!r.ok) return
    onChangeMethodProfileJson(r.json)
  }

  const runIntervalPreset = (presetId) => {
    const r = patchMethodProfile(methodProfileJson || '{}', (draft) => {
      const pr = applyIntervalDomainQuickRatio(draft, presetId)
      if (!pr.ok) setPresetHint(pr.error || '')
      else setPresetHint(null)
    })
    if (!r.ok) return
    onChangeMethodProfileJson(r.json)
  }

  const archeLabel = arch ? combinationArchetypeLabel(arch) : null

  const openAdvanced = () => {
    setRawOpenError(null)
    const p = parseProfileJson(methodProfileJson || '{}')
    setRawDraft(p.ok ? JSON.stringify(p.obj, null, 2) : String(methodProfileJson || ''))
  }

  const showExpertSection = allowExpertJson && !plannerMode

  return (
    <div style={{ marginTop: '10px' }}>
      {presetHint ? (
        <p style={{ fontSize: '12px', color: 'var(--danger)', margin: '0 0 8px', lineHeight: 1.4 }}>{presetHint}</p>
      ) : null}

      {arch ? (
        <p style={{ fontSize: '12px', color: 'var(--text2)', lineHeight: 1.48, margin: '0 0 12px' }}>
          <strong style={{ color: 'var(--text1)' }}>
            Coach &amp; Planung:{' '}
            {archeLabel && archeLabel !== arch ? `${archeLabel} · ` : ''}
          </strong>
          {archetypeCoachHint(arch)}
        </p>
      ) : (
        <p style={{ fontSize: '12px', color: 'var(--text3)', margin: '0 0 12px' }}>
          Wähle einen Methoden‑Archetyp — besonders beim <strong>freien Methodenblock</strong> stehen alle
          typischen Stations‑Zeiten zur Verfügung. Ohne Archetyp keine geführten Eingaben.
        </p>
      )}

      {!parseState.ok ? (
        <p style={{ color: 'var(--danger)', fontSize: '13px', marginBottom: '10px' }}>{parseState.error}</p>
      ) : null}

      {fields && fields.length > 0 ? (
        <div style={{ display: 'flex', flexDirection: 'column', gap: '10px', marginBottom: '12px' }}>
          {arch === 'circuit_rotate_time' ? (
            <div
              style={{
                display: 'flex',
                flexWrap: 'wrap',
                gap: '6px',
                marginBottom: '4px',
                alignItems: 'center',
              }}
            >
              <span style={{ fontSize: '11px', color: 'var(--text3)', marginRight: '6px' }}>Schnellwahl:</span>
              <button type="button" className="btn btn-secondary framework-ctrl framework-ctrl--xs" onClick={() => runCircuitPreset('transition_equals_work')}>
                Wechsel ≈ Arbeit
              </button>
              <button type="button" className="btn btn-secondary framework-ctrl framework-ctrl--xs" onClick={() => runCircuitPreset('round_rest_equals_work')}>
                Runden‑Pause ≈ Arbeit
              </button>
              <button type="button" className="btn btn-secondary framework-ctrl framework-ctrl--xs" onClick={() => runCircuitPreset('round_rest_two_thirds_work')}>
                Runden‑Pause ≈ ⅔ Arbeit
              </button>
            </div>
          ) : null}
          {arch === 'time_domain_interval' ? (
            <div
              style={{
                display: 'flex',
                flexWrap: 'wrap',
                gap: '6px',
                marginBottom: '4px',
                alignItems: 'center',
              }}
            >
              <span style={{ fontSize: '11px', color: 'var(--text3)', marginRight: '6px' }}>Schnellwahl:</span>
              <button type="button" className="btn btn-secondary framework-ctrl framework-ctrl--xs" onClick={() => runIntervalPreset('rest_equals_work')}>
                Erholung = Belastung
              </button>
              <button type="button" className="btn btn-secondary framework-ctrl framework-ctrl--xs" onClick={() => runIntervalPreset('rest_two_thirds_work')}>
                Erholung ≈ ⅔ Belastung
              </button>
            </div>
          ) : null}

          {fields.map((def) => {
            if (def.kind === 'bool') {
              const ck = !!profileObj[def.key]
              return (
                <label
                  key={def.key}
                  style={{ display: 'flex', gap: '8px', alignItems: 'center', cursor: 'pointer', fontSize: '0.9rem' }}
                >
                  <input type="checkbox" checked={ck} onChange={(e) => applyGuided(def.key, e.target.checked, 'bool')} />
                  <span>{def.label}</span>
                </label>
              )
            }
            const v = profileObj[def.key]
            const str =
              v === undefined || v === null ? '' : typeof v === 'number' && Number.isFinite(v) ? String(v) : String(v)

            return (
              <div className="form-row" key={def.key}>
                <label className="form-label" style={{ fontSize: '12px' }}>
                  {def.label}
                </label>
                <input
                  type="number"
                  className="form-input"
                  min={def.min}
                  max={def.max}
                  value={str}
                  placeholder="optional"
                  onChange={(e) => {
                    const t = e.target.value
                    if (t.trim() === '') applyGuided(def.key, '', 'int')
                    else applyGuided(def.key, parseInt(t, 10), 'int')
                  }}
                />
              </div>
            )
          })}
        </div>
      ) : arch && fields && fields.length === 0 ? (
        <div style={{ marginBottom: '12px' }}>
          <p style={{ fontSize: '12px', color: 'var(--text3)', margin: '0 0 10px', lineHeight: 1.45 }}>
            Dieser Archetyp ist für <strong>maximal flexible</strong> Stationsblöcke gedacht — die Zeit‑Eckdaten sind
            unten je Station möglich. Freitexte der Kombination beschreiben alles Organisatorische, was nicht in
            Sekunden gefasst wird.
          </p>
        </div>
      ) : null}

      {showSlotTiming ? (
        <div
          style={{
            marginTop: '6px',
            marginBottom: '14px',
            padding: '12px 14px',
            borderRadius: '10px',
            border: '1px solid var(--border)',
            background: 'var(--surface)',
          }}
        >
          <div style={{ fontSize: '0.88rem', fontWeight: 700, marginBottom: '10px', color: 'var(--text1)' }}>
            Pro Station / Slot — Steuerung &amp; Sekunden
          </div>
          <p style={{ fontSize: '11px', color: 'var(--text3)', margin: '0 0 12px', lineHeight: 1.45 }}>
            <strong>Steuerung:</strong> zeitlich (Arbeits‑Countdown), Zielzahl Wiederholungen oder Coach‑geführt ohne
            Arbeitsuhr. Pausen/Wechsel bleiben unabhängig planbar.&nbsp;Felder können leer bleiben — z.&nbsp;B. nutzt der
            Zirkel erst die globalen Arbeit‑Sekunden.
          </p>
          <div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
            {outlineSorted.map((slot, ordIdx) => {
              const siRaw = slot.slot_index
              const si =
                siRaw === '' || siRaw == null ? null : typeof siRaw === 'number' ? siRaw : parseInt(String(siRaw), 10)
              if (!Number.isFinite(si)) return null
              const row = lookupSlotTiming(si)
              const ttl = ((slot.title || '').trim() || `Station ${ordIdx + 1}`).trim()
              const slotAdv = normalizeAdvanceMode(row.advance_mode)
              const serieLabel =
                slotAdv === 'timed' ? 'Wdh. ohne Wechsel' : slotAdv === 'rep' ? 'Wdh. / Serie' : 'Richtwert'
              const showMultiSeries = slotAdv === 'rep' || slotAdv === 'manual'
              const serienUi = parseComboRepSeriesCountUi(row.rep_series_count)
              const showInterSeriesPause = showMultiSeries && serienUi >= 2
              const intraLabel = slotAdv === 'timed' ? 'Pause zwischen Wdh.' : 'Pause zw. Serien'
              return (
                <div
                  key={`slot-timing-${si}`}
                  style={{
                    padding: '10px',
                    borderRadius: '10px',
                    border: '1px solid var(--border)',
                    background: 'var(--surface2)',
                  }}
                >
                  <div style={{ marginBottom: '10px', fontWeight: 700, color: 'var(--text1)', fontSize: '0.9rem' }}>{ttl}</div>
                  <div className="form-row" style={{ marginBottom: '10px', maxWidth: '22rem' }}>
                    <label className="form-label" style={{ fontSize: '11px' }}>
                      Steuerung
                    </label>
                    <select
                      className="form-input"
                      style={{ fontSize: '0.8125rem' }}
                      value={slotAdv}
                      onChange={(e) => onSlotAdvanceChange(si, e.target.value)}
                    >
                      <option value="timed">Zeit (Arbeit in Sekunden)</option>
                      <option value="rep">Wiederholungen (Ziel)</option>
                      <option value="manual">Coach (ohne Arbeitsuhr)</option>
                    </select>
                  </div>
                  <div
                    style={{
                      display: 'grid',
                      gridTemplateColumns: 'repeat(auto-fill, minmax(120px, 1fr))',
                      gap: '10px',
                      alignItems: 'end',
                    }}
                  >
                    {slotAdv === 'timed' ? (
                      <div className="form-row" style={{ marginBottom: 0 }}>
                        <label className="form-label" style={{ fontSize: '11px' }}>
                          Belastung (s)
                        </label>
                        <input
                          type="number"
                          min={0}
                          className="form-input"
                          placeholder="–"
                          value={row.load_sec != null ? String(row.load_sec) : ''}
                          onChange={(e) => onSlotField(si, 'load_sec', e.target.value)}
                        />
                      </div>
                    ) : null}
                    <div className="form-row" style={{ marginBottom: 0 }}>
                      <label className="form-label" style={{ fontSize: '11px' }}>
                        {serieLabel}
                      </label>
                      <input
                        type="number"
                        min={slotAdv === 'rep' ? 1 : undefined}
                        className="form-input"
                        placeholder={slotAdv === 'manual' ? 'optional' : 'oft 1'}
                        value={row.consecutive_reps != null ? String(row.consecutive_reps) : ''}
                        onChange={(e) => onSlotField(si, 'consecutive_reps', e.target.value)}
                      />
                    </div>
                    {showMultiSeries ? (
                      <div className="form-row" style={{ marginBottom: 0 }}>
                        <label
                          className="form-label"
                          style={{ fontSize: '11px' }}
                          title="Wie oft die Wdh.-Zahl pro Serie hintereinander (mit Pause zwischen den Serien)?"
                        >
                          Serien
                        </label>
                        <input
                          type="number"
                          min={slotAdv === 'rep' ? 1 : undefined}
                          className="form-input"
                          placeholder="1"
                          value={String(parseComboRepSeriesCountUi(row.rep_series_count))}
                          onChange={(e) => onSlotRepSeriesCount(si, e.target.value)}
                        />
                      </div>
                    ) : null}
                    {slotAdv === 'timed' || showInterSeriesPause ? (
                      <div className="form-row" style={{ marginBottom: 0 }}>
                        <label className="form-label" style={{ fontSize: '11px' }}>
                          {intraLabel} (s)
                        </label>
                        <input
                          type="number"
                          min={0}
                          className="form-input"
                          placeholder="–"
                          value={row.intra_rep_rest_sec != null ? String(row.intra_rep_rest_sec) : ''}
                          onChange={(e) => onSlotField(si, 'intra_rep_rest_sec', e.target.value)}
                        />
                      </div>
                    ) : null}
                    <div className="form-row" style={{ marginBottom: 0 }}>
                      <label className="form-label" style={{ fontSize: '11px' }}>
                        Wechsel (s)
                      </label>
                      <input
                        type="number"
                        min={0}
                        className="form-input"
                        placeholder="–"
                        value={row.transition_after_sec != null ? String(row.transition_after_sec) : ''}
                        onChange={(e) => onSlotField(si, 'transition_after_sec', e.target.value)}
                      />
                    </div>
                  </div>
                  {showMultiSeries && serienUi < 2 ? (
                    <p style={{ fontSize: '10px', color: 'var(--text3)', margin: '6px 0 0', lineHeight: 1.38 }}>
                      <strong>Wechsel (s)</strong> zur <strong>nächsten Station</strong>. „Pause zw. Serien“ nur ab&nbsp;2
                      Serien.
                    </p>
                  ) : null}
                </div>
              )
            })}
          </div>
        </div>
      ) : null}

      {showExpertSection ? (
        <details
          style={{
            marginTop: '4px',
            borderRadius: '8px',
            border: '1px solid var(--border)',
            padding: '8px 10px',
            background: 'var(--surface2)',
          }}
          onToggle={(ev) => {
            if (ev.target.open) openAdvanced()
          }}
        >
          <summary style={{ cursor: 'pointer', fontSize: '0.82rem', fontWeight: 600 }}>
            Support / Entwicklung: Rohdaten (JSON)
          </summary>
          <p style={{ fontSize: '11px', color: 'var(--text3)', margin: '8px 0 6px', lineHeight: 1.4 }}>
            Für Migrationen und Sonderfälle. Geführte Felder setzen weiterhin gültige Standardschlüssel.
          </p>
          <textarea
            className="form-input"
            rows={8}
            style={{ fontFamily: 'Consolas,monospace', fontSize: '12px' }}
            value={rawDraft != null ? rawDraft : methodProfileJson || '{}'}
            onChange={(e) => {
              setRawDraft(e.target.value)
              setRawOpenError(null)
            }}
            spellCheck={false}
            onBlur={() => {
              const src = rawDraft != null ? rawDraft : methodProfileJson
              const res = setFullProfileRawJson(src || '{}')
              if (!res.ok) {
                setRawOpenError(res.error)
                return
              }
              setRawOpenError(null)
              setRawDraft(null)
              onChangeMethodProfileJson(res.json)
            }}
          />
          {rawOpenError ? (
            <p style={{ color: 'var(--danger)', fontSize: '12px', marginTop: '6px' }}>{rawOpenError}</p>
          ) : null}
        </details>
      ) : null}
    </div>
  )
}
