import * as React from 'react'
import type { OutlineItem } from './markdown'
import { buildOutlineTree, collectBranchIds, type OutlineTreeNode } from './outlineTree'

type Props = {
  items: OutlineItem[]
  onSelect: (item: OutlineItem) => void
}

export function OutlinePanel({ items, onSelect }: Props): React.ReactElement {
  const tree = React.useMemo(() => buildOutlineTree(items), [items])
  const branchIds = React.useMemo(() => collectBranchIds(tree), [tree])
  const [collapsed, setCollapsed] = React.useState<Set<string>>(() => new Set())

  React.useEffect(() => {
    setCollapsed(new Set())
  }, [items])

  const toggleBranch = React.useCallback((id: string): void => {
    setCollapsed((prev) => {
      const next = new Set(prev)
      if (next.has(id)) next.delete(id)
      else next.add(id)
      return next
    })
  }, [])

  const expandAll = React.useCallback((): void => {
    setCollapsed(new Set())
  }, [])

  const collapseAll = React.useCallback((): void => {
    setCollapsed(new Set(branchIds))
  }, [branchIds])

  const renderNode = (node: OutlineTreeNode): React.ReactElement => {
    const hasChildren = node.children.length > 0
    const isCollapsed = collapsed.has(node.id)

    return (
      <li key={node.id} className="outline-tree-node">
        <div className="outline-tree-row">
          {hasChildren ? (
            <button
              type="button"
              className={`outline-fold-btn${isCollapsed ? ' is-collapsed' : ''}`}
              aria-expanded={!isCollapsed}
              aria-label={isCollapsed ? '展开子标题' : '收起子标题'}
              title={isCollapsed ? '展开' : '收起'}
              onClick={(e) => {
                e.stopPropagation()
                toggleBranch(node.id)
              }}
            >
              {isCollapsed ? '▸' : '▾'}
            </button>
          ) : (
            <span className="outline-fold-spacer" aria-hidden />
          )}
          <button
            type="button"
            className={`outline-tree-title outline-tree-title--h${node.level}`}
            title={node.text || node.displayText}
            onClick={() => onSelect(node)}
          >
            {node.displayText}
          </button>
        </div>
        {hasChildren && !isCollapsed ? (
          <ul className="outline-tree">{node.children.map(renderNode)}</ul>
        ) : null}
      </li>
    )
  }

  if (items.length === 0) {
    return <p className="outline-empty">当前文档没有标题</p>
  }

  const collapsedCount = collapsed.size
  const branchCount = branchIds.length

  return (
    <div className="outline-panel-wrap">
      <div className="outline-toolbar">
        <span className="outline-toolbar-title">
          大纲
          {branchCount > 0 ? (
            <span className="outline-toolbar-meta">
              {' '}
              · {branchCount - collapsedCount}/{branchCount} 已展开
            </span>
          ) : null}
        </span>
        <button type="button" className="outline-toolbar-btn" onClick={expandAll} disabled={collapsedCount === 0}>
          全部展开
        </button>
        <button
          type="button"
          className="outline-toolbar-btn"
          onClick={collapseAll}
          disabled={branchCount === 0 || collapsedCount === branchCount}
        >
          全部收起
        </button>
      </div>
      <ul className="outline-tree outline-tree--root">{tree.map(renderNode)}</ul>
    </div>
  )
}
