import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { ChevronDown, ChevronRight } from 'lucide-react'
import {
  allExpandableKeys,
  buildSkillCatalogTree,
  collectSkillLeavesFromTree,
  defaultExpandedKeysForSkillTree,
  filterSkillTreeByQuery,
} from '../utils/skillCatalogTree'

function normExclude(excludeIds) {
  return new Set(
    (excludeIds instanceof Set ? [...excludeIds] : excludeIds || [])
      .map((x) => Number(x))
      .filter((n) => Number.isFinite(n))
  )
}

function SkillTreeNodes({ nodes, depth, expanded, exclude, onToggle, onPickSkill, pickMode }) {
  if (!nodes?.length) {
    return <li className="skill-tree__empty">Keine Fähigkeiten</li>
  }

  return nodes.map((node) => {
    if (node.type === 'skill') {
      if (exclude.has(node.skillId)) return null
      return (
        <li key={node.key} className="skill-tree__leaf" style={{ paddingLeft: `${8 + depth * 14}px` }}>
          <button
            type="button"
            className="skill-tree__pick"
            onMouseDown={(e) => e.preventDefault()}
            onClick={() => onPickSkill(node.skillId, node.skill)}
          >
            {node.label}
          </button>
        </li>
      )
    }

    const hasKids = node.children?.length > 0
    const isOpen = expanded.has(node.key)
    return (
      <li key={node.key} className="skill-tree__branch">
        <div className="skill-tree__branch-head" style={{ paddingLeft: `${4 + depth * 14}px` }}>
          {hasKids ? (
            <button
              type="button"
              className="skill-tree__toggle"
              aria-expanded={isOpen}
              onClick={() => onToggle(node.key)}
            >
              {isOpen ? <ChevronDown size={16} aria-hidden /> : <ChevronRight size={16} aria-hidden />}
            </button>
          ) : (
            <span className="skill-tree__toggle-spacer" aria-hidden />
          )}
          <span className={`skill-tree__group-label skill-tree__group-label--${node.type}`}>
            {node.label}
          </span>
        </div>
        {hasKids && isOpen ? (
          <ul className="skill-tree__children" role={pickMode === 'multi' ? 'group' : 'tree'}>
            <SkillTreeNodes
              nodes={node.children}
              depth={depth + 1}
              expanded={expanded}
              exclude={exclude}
              onToggle={onToggle}
              onPickSkill={onPickSkill}
              pickMode={pickMode}
            />
          </ul>
        ) : null}
      </li>
    )
  })
}

/**
 * Ausklappbare Baumliste: Hauptgruppe → Kategorie → Fähigkeit (nur Hauptgruppe standard offen).
 */
export default function SkillTreePickerPanel({
  skills = [],
  excludeIds,
  searchQuery = '',
  onPickSkill,
  pickMode = 'single',
  className = '',
}) {
  const exclude = useMemo(() => normExclude(excludeIds), [excludeIds])
  const fullTree = useMemo(() => buildSkillCatalogTree(skills), [skills])
  const displayTree = useMemo(
    () => filterSkillTreeByQuery(fullTree, searchQuery),
    [fullTree, searchQuery]
  )
  const [expanded, setExpanded] = useState(() => new Set())

  useEffect(() => {
    if (searchQuery.trim()) {
      setExpanded(new Set(allExpandableKeys(displayTree)))
    } else {
      setExpanded(new Set(defaultExpandedKeysForSkillTree(displayTree)))
    }
  }, [searchQuery, displayTree])

  useEffect(() => {
    if (!searchQuery.trim()) {
      setExpanded(new Set(defaultExpandedKeysForSkillTree(fullTree)))
    }
  }, [fullTree, searchQuery])

  const onToggle = useCallback((key) => {
    setExpanded((prev) => {
      const next = new Set(prev)
      if (next.has(key)) next.delete(key)
      else next.add(key)
      return next
    })
  }, [])

  const flatSearchHits = useMemo(() => {
    const q = searchQuery.trim()
    if (!q) return []
    return collectSkillLeavesFromTree(fullTree, exclude).filter((leaf) =>
      leaf.pathLabel.toLowerCase().includes(q.toLowerCase())
    )
  }, [fullTree, exclude, searchQuery])

  if (searchQuery.trim() && flatSearchHits.length > 0) {
    return (
      <ul className={`skill-tree skill-tree--flat-hits ${className}`.trim()} role="listbox">
        {flatSearchHits.map((leaf) => (
          <li key={leaf.id}>
            <button
              type="button"
              className="skill-tree__pick skill-tree__pick--path"
              onMouseDown={(e) => e.preventDefault()}
              onClick={() => onPickSkill(leaf.id, leaf.skill)}
            >
              <span className="skill-tree__pick-name">{leaf.label}</span>
              <span className="skill-tree__pick-path">{leaf.pathLabel}</span>
            </button>
          </li>
        ))}
      </ul>
    )
  }

  return (
    <ul className={`skill-tree ${className}`.trim()} role="tree">
      <SkillTreeNodes
        nodes={displayTree}
        depth={0}
        expanded={expanded}
        exclude={exclude}
        onToggle={onToggle}
        onPickSkill={onPickSkill}
        pickMode={pickMode}
      />
    </ul>
  )
}
