import React, { useState, useEffect, useMemo } from 'react'
import { Link } from 'react-router-dom'
import api from '../utils/api'
import { SKILL_LEVEL_OPTIONS } from '../constants/skillLevels'
import SearchableSelect from '../components/SearchableSelect'
import MultiSelectCombo from '../components/MultiSelectCombo'

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

function ExercisesListPage() {
  const [exercises, setExercises] = useState([])
  const [catalogs, setCatalogs] = useState({
    focusAreas: [],
    styleDirections: [],
    trainingTypes: [],
    targetGroups: [],
    skills: [],
  })
  const [catalogsReady, setCatalogsReady] = useState(false)
  const [loading, setLoading] = useState(true)
  const [loadingMore, setLoadingMore] = useState(false)
  const [offset, setOffset] = useState(0)
  const [hasMore, setHasMore] = useState(false)
  const [searchInput, setSearchInput] = useState('')
  const [aiSearchInput, setAiSearchInput] = useState('')
  const [debouncedSearch, setDebouncedSearch] = useState('')
  const [debouncedAiSearch, setDebouncedAiSearch] = useState('')
  const [filters, setFilters] = useState({
    focus_area_ids: [],
    style_direction_ids: [],
    training_type_ids: [],
    target_group_ids: [],
    skill_ids: [],
    skill_min_level: '',
    skill_max_level: '',
    visibility_any: [],
    status_any: [],
  })

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

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

  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 levelFilterOptions = useMemo(
    () => LEVEL_FILTER_OPTS.map((o) => ({ id: o.level, label: o.label })),
    []
  )
  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 (debouncedAiSearch) q.ai_search = debouncedAiSearch
    return q
  }, [filters, debouncedSearch, debouncedAiSearch])

  useEffect(() => {
    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 (err) {
        if (!cancelled) {
          console.error(err)
          alert('Kataloge konnten nicht geladen werden: ' + err.message)
          setCatalogsReady(true)
        }
      }
    })()
    return () => {
      cancelled = true
    }
  }, [])

  useEffect(() => {
    if (!catalogsReady) return
    let cancelled = false
    const run = async () => {
      setLoading(true)
      setOffset(0)
      try {
        const batch = await api.listExercises({ ...queryBase, limit: PAGE_SIZE, offset: 0 })
        if (cancelled) return
        setExercises(batch)
        setHasMore(batch.length === PAGE_SIZE)
        setOffset(batch.length)
      } catch (err) {
        if (!cancelled) {
          console.error('Failed to load data:', err)
          alert('Fehler beim Laden: ' + err.message)
        }
      } finally {
        if (!cancelled) setLoading(false)
      }
    }
    run()
    return () => {
      cancelled = true
    }
  }, [queryBase, catalogsReady])

  const loadMore = async () => {
    if (loadingMore || !hasMore) return
    setLoadingMore(true)
    try {
      const batch = await api.listExercises({ ...queryBase, limit: PAGE_SIZE, offset })
      setExercises((prev) => [...prev, ...batch])
      setHasMore(batch.length === PAGE_SIZE)
      setOffset((o) => o + batch.length)
    } catch (err) {
      alert('Fehler: ' + err.message)
    } finally {
      setLoadingMore(false)
    }
  }

  const handleDelete = async (exercise) => {
    if (!confirm(`Übung "${exercise.title}" wirklich löschen?`)) return
    try {
      await api.deleteExercise(exercise.id)
      setExercises((prev) => prev.filter((e) => e.id !== exercise.id))
    } catch (err) {
      alert('Fehler beim Löschen: ' + err.message)
    }
  }

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

  return (
    <div style={{ padding: '12px', maxWidth: '1200px', margin: '0 auto' }}>
      <div
        style={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          marginBottom: '12px',
          flexWrap: 'wrap',
          gap: '8px',
        }}
      >
        <h1 style={{ fontSize: '1.35rem' }}>Übungen</h1>
        <Link to="/exercises/new" className="btn btn-primary">
          + Neu
        </Link>
      </div>

      <div className="card exercise-filters-compact" style={{ marginBottom: '12px' }}>
        <p style={{ gridColumn: '1 / -1', fontSize: '12px', color: 'var(--text3)', margin: '0 0 4px' }}>
          Filter untereinander werden mit <strong>UND</strong> kombiniert. Mehrere Einträge in einem Feld mit{' '}
          <strong>ODER</strong> (die Übung muss mindestens eine der gewählten Zuordnungen erfüllen).
        </p>
        <div style={{ gridColumn: '1 / -1' }}>
          <label className="form-label">Volltextsuche (Titel, Ziel, …)</label>
          <input
            type="search"
            className="form-input"
            placeholder="Suchbegriffe…"
            value={searchInput}
            onChange={(e) => setSearchInput(e.target.value)}
            autoComplete="off"
          />
        </div>
        <div style={{ gridColumn: '1 / -1' }}>
          <label className="form-label">Ergänzende Suche / KI-Vorbereitung (Beta)</label>
          <input
            type="search"
            className="form-input"
            placeholder="zweiter Begriff — aktuell zusätzliche Volltextsuche (ODER); später KI"
            value={aiSearchInput}
            onChange={(e) => setAiSearchInput(e.target.value)}
            autoComplete="off"
          />
          <p style={{ fontSize: '12px', color: 'var(--text3)', marginTop: '6px' }}>
            Standardfilter aus Verein und Trainerrolle folgen später; die KI-Nutzung der zweiten Zeile
            kommt mit einem eigenen Endpunkt.
          </p>
        </div>
        <div>
          <label className="form-label">Fokus (mehrere möglich)</label>
          <MultiSelectCombo
            value={filters.focus_area_ids}
            onChange={(v) => setFilters({ ...filters, focus_area_ids: v })}
            options={focusOptions}
            placeholder="Fokus suchen oder „▼ Alle“ …"
          />
        </div>
        <div>
          <label className="form-label">Stilrichtung (mehrere möglich)</label>
          <MultiSelectCombo
            value={filters.style_direction_ids}
            onChange={(v) => setFilters({ ...filters, style_direction_ids: v })}
            options={styleOptions}
            placeholder="Stilrichtung suchen …"
          />
        </div>
        <div>
          <label className="form-label">Trainingsstil (mehrere möglich)</label>
          <MultiSelectCombo
            value={filters.training_type_ids}
            onChange={(v) => setFilters({ ...filters, training_type_ids: v })}
            options={trainingTypeOptions}
            placeholder="Trainingsstil suchen …"
          />
        </div>
        <div>
          <label className="form-label">Zielgruppe (mehrere möglich)</label>
          <MultiSelectCombo
            value={filters.target_group_ids}
            onChange={(v) => setFilters({ ...filters, target_group_ids: v })}
            options={targetGroupOptions}
            placeholder="Zielgruppe suchen …"
          />
        </div>
        <div>
          <label className="form-label">Fähigkeit (mehrere möglich)</label>
          <MultiSelectCombo
            value={filters.skill_ids}
            onChange={(v) => setFilters({ ...filters, skill_ids: v })}
            options={skillOptions}
            placeholder="Fähigkeit suchen …"
          />
        </div>
        <div>
          <label className="form-label">Fähigkeit Stufe von</label>
          <SearchableSelect
            value={filters.skill_min_level}
            onChange={(v) => setFilters({ ...filters, skill_min_level: v })}
            options={levelFilterOptions}
            allLabel="egal (min)"
            filterPlaceholder="Stufe suchen…"
          />
        </div>
        <div>
          <label className="form-label">Fähigkeit Stufe bis</label>
          <SearchableSelect
            value={filters.skill_max_level}
            onChange={(v) => setFilters({ ...filters, skill_max_level: v })}
            options={levelFilterOptions}
            allLabel="egal (max)"
            filterPlaceholder="Stufe suchen…"
          />
        </div>
        <div>
          <label className="form-label">Sichtbarkeit (mehrere möglich)</label>
          <MultiSelectCombo
            value={filters.visibility_any}
            onChange={(v) => setFilters({ ...filters, visibility_any: v })}
            options={visibilityOptions}
            placeholder="Sichtbarkeit wählen …"
          />
        </div>
        <div>
          <label className="form-label">Status (mehrere möglich)</label>
          <MultiSelectCombo
            value={filters.status_any}
            onChange={(v) => setFilters({ ...filters, status_any: v })}
            options={statusOptions}
            placeholder="Status wählen …"
          />
        </div>
      </div>

      {exercises.length === 0 ? (
        <div className="card">
          <p style={{ color: 'var(--text2)', textAlign: 'center' }}>
            Keine Übungen gefunden.
          </p>
        </div>
      ) : (
        <>
          <p style={{ fontSize: '13px', color: 'var(--text2)', marginBottom: '10px' }}>
            {exercises.length} angezeigt
            {hasMore ? ' · es gibt weitere Einträge' : ''}
          </p>
          <div
            style={{
              display: 'grid',
              gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))',
              gap: '12px',
            }}
          >
            {exercises.map((exercise) => (
              <div key={exercise.id} className="card exercise-card">
                <div className="exercise-card__body">
                  <h3 style={{ marginBottom: '8px', fontSize: '1.05rem', lineHeight: 1.3 }}>
                    <Link
                      to={`/exercises/${exercise.id}`}
                      style={{ color: 'inherit', textDecoration: 'none' }}
                    >
                      {exercise.title}
                    </Link>
                  </h3>
                  <div style={{ display: 'flex', gap: '6px', flexWrap: 'wrap', marginBottom: '8px' }}>
                    {exercise.focus_area && (
                      <span className="exercise-tag exercise-tag--accent">{exercise.focus_area}</span>
                    )}
                    <span className="exercise-tag">{exercise.visibility}</span>
                    <span className="exercise-tag">{exercise.status}</span>
                  </div>
                  {exercise.summary && (
                    <p style={{ color: 'var(--text2)', fontSize: '13px', lineHeight: 1.4 }}>
                      {exercise.summary.length > 160
                        ? `${exercise.summary.slice(0, 160)}…`
                        : exercise.summary}
                    </p>
                  )}
                </div>
                <div className="exercise-card__actions">
                  <Link to={`/exercises/${exercise.id}`} className="btn btn-secondary">
                    Ansehen
                  </Link>
                  <Link to={`/exercises/${exercise.id}/edit`} className="btn btn-secondary">
                    Bearbeiten
                  </Link>
                  <button
                    type="button"
                    className="btn"
                    style={{
                      background: 'var(--danger)',
                      color: 'white',
                      border: 'none',
                    }}
                    onClick={() => handleDelete(exercise)}
                  >
                    Löschen
                  </button>
                </div>
              </div>
            ))}
          </div>
          {hasMore && (
            <div style={{ textAlign: 'center', marginTop: '16px' }}>
              <button type="button" className="btn btn-secondary" disabled={loadingMore} onClick={loadMore}>
                {loadingMore ? 'Laden…' : 'Mehr laden'}
              </button>
            </div>
          )}
        </>
      )}
    </div>
  )
}

export default ExercisesListPage
