import { forwardRef, useId, useRef, useState, useCallback, useEffect } from 'react'
import type { ReactNode, CSSProperties } from 'react'
import { cn } from '@/lib/utils'

export type ScrollbarVisibility = 'auto' | 'always' | 'hidden'

export interface ScrollbarProps {
  children: ReactNode
  className?: string
  style?: CSSProperties
  maxHeight?: number | string
  /** auto: 默认透明，滚动时与 hover 时可见；always: 始终可见；hidden: 隐藏 */
  scrollbarVisibility?: ScrollbarVisibility
  scrollbarWidth?: number
}

export const Scrollbar = forwardRef<HTMLDivElement, ScrollbarProps>(
  function Scrollbar(
    {
      children,
      className,
      style,
      maxHeight,
      scrollbarVisibility = 'auto',
      scrollbarWidth = 6,
    },
    ref
  ) {
    const scrollId = useId().replace(/:/g, '')
    const scrollClassName = `Scrollbar-${scrollId}`
    const scrollEndTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
    const [isScrolling, setIsScrolling] = useState(false)

    const handleScroll = useCallback(() => {
      if (scrollbarVisibility !== 'auto') return
      setIsScrolling(true)
      if (scrollEndTimerRef.current) clearTimeout(scrollEndTimerRef.current)
      scrollEndTimerRef.current = setTimeout(() => {
        scrollEndTimerRef.current = null
        setIsScrolling(false)
      }, 800)
    }, [scrollbarVisibility])

    useEffect(() => {
      return () => {
        if (scrollEndTimerRef.current) clearTimeout(scrollEndTimerRef.current)
      }
    }, [])

    const getScrollbarStyles = () => {
      if (scrollbarVisibility === 'hidden') {
        return `
          .${scrollClassName}::-webkit-scrollbar { display: none; }
          .${scrollClassName} { scrollbar-width: none; }
        `
      }
      const isAuto = scrollbarVisibility === 'auto'
      const thumbColor =
        scrollbarVisibility === 'always'
          ? 'var(--color-fill-secondary)'
          : 'transparent'
      const thumbHoverColor = 'var(--color-fill-secondary)'
      const autoVisible = isAuto
        ? `
        .${scrollClassName}:hover::-webkit-scrollbar-thumb,
        .${scrollClassName}.Scrollbar-isScrolling::-webkit-scrollbar-thumb {
          background-color: ${thumbHoverColor};
        }
      `
        : `
        .${scrollClassName}:hover::-webkit-scrollbar-thumb {
          background-color: ${thumbHoverColor};
        }
      `
      return `
        .${scrollClassName}::-webkit-scrollbar {
          width: ${scrollbarWidth}px !important;
          height: ${scrollbarWidth}px !important;
        }
        .${scrollClassName}::-webkit-scrollbar-track { background: transparent; }
        .${scrollClassName}::-webkit-scrollbar-thumb {
          background-color: ${thumbColor};
          border-radius: ${Math.max(scrollbarWidth / 2, 2)}px;
          min-height: var(--spacing-8);
          transition: background-color 0.2s ease;
        }
        ${autoVisible}
        .${scrollClassName}::-webkit-scrollbar-corner { background: transparent; }
      `
    }

    const computedStyle: CSSProperties = { ...style, maxHeight }

    return (
      <>
        <style>{getScrollbarStyles()}</style>
        <div
          ref={ref}
          className={cn(
            scrollClassName,
            'overflow-y-auto',
            isScrolling && 'Scrollbar-isScrolling',
            className
          )}
          style={computedStyle}
          onScroll={scrollbarVisibility === 'auto' ? handleScroll : undefined}
        >
          {children}
        </div>
      </>
    )
  }
)
Scrollbar.displayName = 'Scrollbar'
