/**
 * Übungssuche mit Volltext-, KI-/Semantikfeld (aktuell gleiche Engine wie Suche) und erweiterten Filtern.
 * Paginierung bis max. 100 Treffer pro Request (API-Limit).
 */
import React, { useState, useEffect, useMemo, useCallback } from 'react'
import api from '../utils/api'
import { SKILL_LEVEL_OPTIONS } from '../constants/skillLevels'
import MultiSelectCombo from './MultiSelectCombo'

const PAGE_SIZE = 100
const LEVEL_FILTER_OPTS = SKILL_LEVEL_OPTIONS.filter((o) => o.level != null)

const INITIAL_FILTERS = {
  focus_area_ids: [],
  style_direction_ids: [],
  training_type_ids: [],
  target_group_ids: [],
  skill_ids: [],
  skill_min_level: '',
  skill_max_level: '',
  visibility_any: [],
  status_any: [],
}

export default function ExercisePickerModal({
  open,
  onClose,
  onSelectExercise,
  multiSelect = false,
  onSelectExercises = null,
}) {
  const [catalogs, setCatalogs] = useState({
    focusAreas: [],
    styleDirections: [],
    trainingTypes: [],
    targetGroups: [],
    skills: [],
  })
  const [catalogsReady, setCatalogsReady] = useState(false)
  const [searchInput, setSearchInput] = useState('')
  const [aiSearchInput, setAiSearchInput] = useState('')
  const [debouncedSearch, setDebouncedSearch] = useState('')
  const [debouncedAi, setDebouncedAi] = useState('')
  const [filters, setFilters] = useState(() => ({ ...INITIAL_FILTERS }))
  const [filterOpen, setFilterOpen] = useState(false)
  const [list, setList] = useState([])
  const [loading, setLoading] = useState(false)
  const [loadingMore, setLoadingMore] = useState(false)
  const [offset, setOffset] = useState(0)
  const [hasMore, setHasMore] = useState(false)
  const [multiPicked, setMultiPicked] = useState([])

  const toggleMultiPick = (ex) => {
    setMultiPicked((prev) =>
      prev.some((p) => p.id === ex.id) ? prev.filter((p) => p.id !== ex.id) : [...prev, ex]
    )
  }

  useEffect(() => {
    const t = setTimeout(() => setDebouncedSearch(searchInput.trim()), 350)
    return () => clearTimeout(t)
  }, [searchInput])

  useEffect(() => {
    const t = setTimeout(() => setDebouncedAi(aiSearchInput.trim()), 350)
    return () => clearTimeout(t)
  }, [aiSearchInput])

  useEffect(() => {
    if (!open) return
    let cancelled = false
    ;(async () => {
      try {
        const [fa, sd, tt, tg, sk] = await Promise.all([
          api.listFocusAreas(),
          api.listStyleDirections(),
          api.listTrainingTypes(),
          api.listTargetGroups(),
          api.listSkills(),
        ])
        if (!cancelled) {
          setCatalogs({
            focusAreas: fa,
            styleDirections: sd,
            trainingTypes: tt,
            targetGroups: tg,
            skills: sk,
          })
          setCatalogsReady(true)
        }
      } catch (e) {
        console.error(e)
        if (!cancelled) setCatalogsReady(true)
      }
    })()
    return () => {
      cancelled = true
    }
  }, [open])

  useEffect(() => {
    if (!open) {
      setSearchInput('')
      setAiSearchInput('')
      setDebouncedSearch('')
      setDebouncedAi('')
      setFilters({ ...INITIAL_FILTERS })
      setFilterOpen(false)
      setList([])
      setOffset(0)
      setHasMore(false)
      setMultiPicked([])
    }
  }, [open])

  const focusOptions = useMemo(
    () => catalogs.focusAreas.map((fa) => ({ id: fa.id, label: `${fa.icon || ''} ${fa.name || ''}`.trim() })),
    [catalogs.focusAreas]
  )
  const styleOptions = useMemo(
    () => catalogs.styleDirections.map((s) => ({ id: s.id, label: s.name || String(s.id) })),
    [catalogs.styleDirections]
  )
  const trainingTypeOptions = useMemo(
    () => catalogs.trainingTypes.map((t) => ({ id: t.id, label: t.name || String(t.id) })),
    [catalogs.trainingTypes]
  )
  const targetGroupOptions = useMemo(
    () => catalogs.targetGroups.map((g) => ({ id: g.id, label: g.name || String(g.id) })),
    [catalogs.targetGroups]
  )
  const skillOptions = useMemo(
    () => catalogs.skills.map((s) => ({ id: s.id, label: s.name || String(s.id) })),
    [catalogs.skills]
  )
  const visibilityOptions = useMemo(
    () => [
      { id: 'private', label: 'Privat' },
      { id: 'club', label: 'Verein' },
      { id: 'official', label: 'Offiziell' },
    ],
    []
  )
  const statusOptions = useMemo(
    () => [
      { id: 'draft', label: 'Entwurf' },
      { id: 'in_review', label: 'In Prüfung' },
      { id: 'approved', label: 'Freigegeben' },
      { id: 'archived', label: 'Archiviert' },
    ],
    []
  )

  const queryBase = useMemo(() => {
    const q = {}
    const n = (v) => (v === '' || v == null ? undefined : Number(v))
    const ids = (arr) =>
      Array.isArray(arr) && arr.length ? arr.map((x) => Number(x)).filter((x) => !Number.isNaN(x)) : undefined
    const fa = ids(filters.focus_area_ids)
    if (fa?.length) q.focus_area_ids = fa
    const sd = ids(filters.style_direction_ids)
    if (sd?.length) q.style_direction_ids = sd
    const tt = ids(filters.training_type_ids)
    if (tt?.length) q.training_type_ids = tt
    const tg = ids(filters.target_group_ids)
    if (tg?.length) q.target_group_ids = tg
    const sk = ids(filters.skill_ids)
    if (sk?.length) q.skill_ids = sk
    if (filters.skill_min_level) q.skill_min_level = n(filters.skill_min_level)
    if (filters.skill_max_level) q.skill_max_level = n(filters.skill_max_level)
    if (filters.visibility_any?.length) q.visibility_any = [...filters.visibility_any]
    if (filters.status_any?.length) q.status_any = [...filters.status_any]
    if (debouncedSearch) q.search = debouncedSearch
    if (debouncedAi) q.ai_search = debouncedAi
    return q
  }, [filters, debouncedSearch, debouncedAi])

  const reload = useCallback(async () => {
    if (!open || !catalogsReady) return
    setLoading(true)
    setOffset(0)
    try {
      const batch = await api.listExercises({
        ...queryBase,
        include_variants: true,
        limit: PAGE_SIZE,
        offset: 0,
      })
      setList(Array.isArray(batch) ? batch : [])
      setHasMore(batch?.length === PAGE_SIZE)
      setOffset(batch?.length ?? 0)
    } catch (e) {
      console.error(e)
      alert(e.message || 'Laden fehlgeschlagen')
      setList([])
      setHasMore(false)
    } finally {
      setLoading(false)
    }
  }, [open, catalogsReady, queryBase])

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

  const loadMore = async () => {
    if (!hasMore || loadingMore || loading) return
    setLoadingMore(true)
    try {
      const batch = await api.listExercises({
        ...queryBase,
        include_variants: true,
        limit: PAGE_SIZE,
        offset,
      })
      setList((prev) => [...prev, ...(Array.isArray(batch) ? batch : [])])
      setHasMore(batch?.length === PAGE_SIZE)
      setOffset((o) => o + (batch?.length ?? 0))
    } catch (e) {
      console.error(e)
      alert(e.message || 'Mehr laden fehlgeschlagen')
    } finally {
      setLoadingMore(false)
    }
  }

  const resetFilters = () => setFilters({ ...INITIAL_FILTERS })

  if (!open) return null

  return (
    <div
      className="admin-modal-backdrop"
      role="presentation"
      onClick={(e) => {
        if (e.target === e.currentTarget) onClose()
      }}
    >
      <div
        className="admin-modal-sheet"
        role="dialog"
        aria-modal="true"
        style={{ maxWidth: '920px', width: '100%', maxHeight: '92vh', display: 'flex', flexDirection: 'column' }}
        onClick={(e) => e.stopPropagation()}
      >
        <div className="admin-modal-sheet__header">
          <h3 className="admin-modal-sheet__title">
            {multiSelect ? 'Übungen auswählen' : 'Übung auswählen'}
          </h3>
          <button type="button" className="btn btn-secondary admin-modal-sheet__close" onClick={onClose}>
            Schließen
          </button>
        </div>

        <div style={{ padding: '0 1rem 0.75rem', borderBottom: '1px solid var(--border)', flexShrink: 0 }}>
          <div style={{ display: 'grid', gap: '0.65rem' }}>
            <div>
              <label className="form-label">Volltextsuche</label>
              <input
                type="search"
                className="form-input"
                placeholder="Stichwort, Titelfragment…"
                value={searchInput}
                onChange={(e) => setSearchInput(e.target.value)}
                autoComplete="off"
              />
            </div>
            <div>
              <label className="form-label">
                Semantisch /{' '}
                <span title="aktuell gleiche Datenbanksuche wie Volltext; später KI-Verfeinerung möglich">KI-Feld</span>
              </label>
              <input
                type="search"
                className="form-input"
                placeholder="zweites Suchkonzept oder Umschreibung…"
                value={aiSearchInput}
                onChange={(e) => setAiSearchInput(e.target.value)}
                autoComplete="off"
              />
            </div>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem', alignItems: 'center' }}>
              <button type="button" className="btn btn-secondary" onClick={() => setFilterOpen(!filterOpen)}>
                {filterOpen ? 'Filter ausblenden' : 'Erweiterte Filter'}
              </button>
              <button type="button" className="btn" onClick={resetFilters}>
                Filter zurücksetzen
              </button>
              {loading && <span style={{ fontSize: '13px', color: 'var(--text2)' }}>Suche läuft…</span>}
            </div>

            {filterOpen && (
              <div style={{ marginTop: '0.35rem', fontSize: '13px', color: 'var(--text2)' }}>
                  <p style={{ margin: '0 0 12px 0' }}>
                  Zwischen den Bereichen gilt <strong>UND</strong>, innerhalb ODER wie in der Übungsübersicht.
                </p>
                <div className="exercise-filters-modal-grid">
                  <div>
                    <label className="form-label">Fokus</label>
                    <MultiSelectCombo
                      value={filters.focus_area_ids}
                      onChange={(v) => setFilters((f) => ({ ...f, focus_area_ids: v }))}
                      options={focusOptions}
                      placeholder="Fokus …"
                    />
                  </div>
                  <div>
                    <label className="form-label">Stilrichtung</label>
                    <MultiSelectCombo
                      value={filters.style_direction_ids}
                      onChange={(v) => setFilters((f) => ({ ...f, style_direction_ids: v }))}
                      options={styleOptions}
                      placeholder="Stilrichtung …"
                    />
                  </div>
                  <div>
                    <label className="form-label">Trainingsstil</label>
                    <MultiSelectCombo
                      value={filters.training_type_ids}
                      onChange={(v) => setFilters((f) => ({ ...f, training_type_ids: v }))}
                      options={trainingTypeOptions}
                      placeholder="Trainingsstil …"
                    />
                  </div>
                  <div>
                    <label className="form-label">Zielgruppe</label>
                    <MultiSelectCombo
                      value={filters.target_group_ids}
                      onChange={(v) => setFilters((f) => ({ ...f, target_group_ids: v }))}
                      options={targetGroupOptions}
                      placeholder="Zielgruppe …"
                    />
                  </div>
                </div>
                <div style={{ marginTop: 12 }}>
                  <label className="form-label">Fähigkeit</label>
                  <MultiSelectCombo
                    value={filters.skill_ids}
                    onChange={(v) => setFilters((f) => ({ ...f, skill_ids: v }))}
                    options={skillOptions}
                    placeholder="Fähigkeit …"
                  />
                  <div className="exercise-filter-skill-levels-row" style={{ marginTop: 8 }}>
                    <select
                      className="form-input exercise-filter-level-select"
                      title="von"
                      value={filters.skill_min_level}
                      onChange={(e) => setFilters((f) => ({ ...f, skill_min_level: e.target.value }))}
                    >
                      <option value="">Stufe von</option>
                      {LEVEL_FILTER_OPTS.map((o) => (
                        <option key={o.value} value={String(o.level)}>
                          {o.level}
                        </option>
                      ))}
                    </select>
                    <select
                      className="form-input exercise-filter-level-select"
                      title="bis"
                      value={filters.skill_max_level}
                      onChange={(e) => setFilters((f) => ({ ...f, skill_max_level: e.target.value }))}
                    >
                      <option value="">Stufe bis</option>
                      {LEVEL_FILTER_OPTS.map((o) => (
                        <option key={`m-${o.value}`} value={String(o.level)}>
                          {o.level}
                        </option>
                      ))}
                    </select>
                  </div>
                </div>
                <div className="exercise-filters-modal-grid exercise-filters-modal-grid--two" style={{ marginTop: 12 }}>
                  <div>
                    <label className="form-label">Sichtbarkeit</label>
                    <MultiSelectCombo
                      value={filters.visibility_any}
                      onChange={(v) => setFilters((f) => ({ ...f, visibility_any: v }))}
                      options={visibilityOptions}
                      placeholder="Sichtbarkeit …"
                    />
                  </div>
                  <div>
                    <label className="form-label">Status</label>
                    <MultiSelectCombo
                      value={filters.status_any}
                      onChange={(v) => setFilters((f) => ({ ...f, status_any: v }))}
                      options={statusOptions}
                      placeholder="Status …"
                    />
                  </div>
                </div>
              </div>
            )}
          </div>
        </div>

        <div style={{ flex: 1, minHeight: 0, overflowY: 'auto', padding: '12px 1rem' }}>
          {!catalogsReady || (loading && list.length === 0) ? (
            <div style={{ textAlign: 'center', padding: '2rem' }}>
              <div className="spinner" />
            </div>
          ) : list.length === 0 ? (
            <p style={{ color: 'var(--text2)', textAlign: 'center' }}>Keine Treffer.</p>
          ) : (
            <>
              <p style={{ fontSize: '13px', color: 'var(--text2)', marginBottom: 10 }}>
                {list.length} angezeigt{hasMore ? ' · weiter unten „Mehr laden“' : ''}
              </p>
              <ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>
                {list.map((ex) => {
                  const picked = multiPicked.some((p) => p.id === ex.id)
                  const rowInner = (
                    <>
                      <strong style={{ display: 'block' }}>{ex.title}</strong>
                      {(ex.summary || '').trim().length > 0 && (
                        <span style={{ fontSize: '12px', color: 'var(--text2)' }}>
                          {(ex.summary || '').length > 120
                            ? `${(ex.summary || '').slice(0, 120)}…`
                            : ex.summary}
                        </span>
                      )}
                      {ex.focus_area && (
                        <span className="exercise-tag exercise-tag--accent" style={{ marginTop: 6 }}>
                          {ex.focus_area}
                        </span>
                      )}
                    </>
                  )
                  if (multiSelect) {
                    return (
                      <li key={ex.id}>
                        <label
                          className="tu-ex-picker-multi-row"
                          style={{
                            display: 'flex',
                            gap: '10px',
                            alignItems: 'flex-start',
                            width: '100%',
                            textAlign: 'left',
                            padding: '10px 12px',
                            marginBottom: 8,
                            borderRadius: '8px',
                            border: picked ? '2px solid var(--accent)' : '1px solid var(--border)',
                            background: 'var(--surface2)',
                            cursor: 'pointer',
                            boxSizing: 'border-box',
                          }}
                        >
                          <input
                            type="checkbox"
                            checked={picked}
                            onChange={() => toggleMultiPick(ex)}
                            style={{ marginTop: '0.35rem', flexShrink: 0 }}
                            aria-label={ex.title ? `Auswahl: ${ex.title}` : 'Auswahl'}
                          />
                          <div style={{ flex: 1, minWidth: 0 }}>{rowInner}</div>
                        </label>
                      </li>
                    )
                  }
                  return (
                    <li key={ex.id}>
                      <button
                        type="button"
                        onClick={() => {
                          onSelectExercise(ex)
                          onClose()
                        }}
                        style={{
                          width: '100%',
                          textAlign: 'left',
                          padding: '10px 12px',
                          marginBottom: 8,
                          borderRadius: '8px',
                          border: '1px solid var(--border)',
                          background: 'var(--surface2)',
                          cursor: 'pointer',
                        }}
                      >
                        {rowInner}
                      </button>
                    </li>
                  )
                })}
              </ul>
              {hasMore && (
                <div style={{ textAlign: 'center', marginTop: 12 }}>
                  <button type="button" className="btn btn-secondary" disabled={loadingMore} onClick={loadMore}>
                    {loadingMore ? 'Laden…' : 'Mehr laden'}
                  </button>
                </div>
              )}
              {multiSelect && typeof onSelectExercises === 'function' ? (
                <div
                  className="exercise-picker-multi-footer"
                  style={{
                    position: 'sticky',
                    bottom: 0,
                    marginTop: 16,
                    paddingTop: 12,
                    borderTop: '1px solid var(--border)',
                    background: 'var(--surface)',
                    display: 'flex',
                    flexWrap: 'wrap',
                    gap: '10px',
                    alignItems: 'center',
                    justifyContent: 'space-between',
                  }}
                >
                  <span style={{ fontSize: '0.92rem', color: 'var(--text2)' }}>
                    {multiPicked.length} ausgewählt
                  </span>
                  <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px' }}>
                    <button
                      type="button"
                      className="btn btn-secondary"
                      onClick={() => setMultiPicked([])}
                      disabled={!multiPicked.length}
                    >
                      Auswahl leeren
                    </button>
                    <button
                      type="button"
                      className="btn btn-primary"
                      disabled={!multiPicked.length}
                      onClick={() => {
                        onSelectExercises([...multiPicked])
                        onClose()
                      }}
                    >
                      Übernehmen
                    </button>
                  </div>
                </div>
              ) : null}
            </>
          )}
        </div>
      </div>
    </div>
  )
}
