import React, { createContext, useContext, useLayoutEffect, useRef, useState } from 'react'

const TabsContext = createContext<{
  value: string
  onChange: (value: string) => void
} | null>(null)

function useTabsContext() {
  const ctx = useContext(TabsContext)
  if (!ctx) throw new Error('Tab components must be used inside <Tabs>')
  return ctx
}

export const Tabs: React.FC<{
  defaultValue: string
  children: React.ReactNode
  onValueChange?: (value: string) => void
}> = ({ defaultValue, children, onValueChange }) => {
  const [value, setValue] = useState(defaultValue)

  const handleChange = (newValue: string) => {
    setValue(newValue)
    onValueChange?.(newValue)
  }

  return (
    <TabsContext.Provider value={{ value, onChange: handleChange }}>
      {children}
    </TabsContext.Provider>
  )
}

export const TabList: React.FC<{ children: React.ReactNode; className?: string }> = ({
  children,
  className = '',
}) => {
  const { value } = useTabsContext()
  const containerRef = useRef<HTMLDivElement>(null)
  const [indicator, setIndicator] = useState<{ left: number; width: number } | null>(null)

  useLayoutEffect(() => {
    const el = containerRef.current
    if (!el) return
    const updateIndicator = () => {
      const active = el.querySelector<HTMLElement>('[data-active="true"]')
      if (!active) return
      const cRect = el.getBoundingClientRect()
      const aRect = active.getBoundingClientRect()
      if (aRect.width === 0) return
      setIndicator({ left: aRect.left - cRect.left, width: aRect.width })
    }
    updateIndicator()
    const ro = new ResizeObserver(updateIndicator)
    ro.observe(el)
    return () => ro.disconnect()
  }, [value])

  return (
    <div ref={containerRef} className={`relative border-b-2 border-slate-100 flex gap-0 ${className}`}>
      {indicator && (
        <div
          className="absolute bottom-[-2px] h-0.5 bg-teal-500 pointer-events-none"
          style={{ left: indicator.left, width: indicator.width, transition: 'left 0.2s ease-out, width 0.2s ease-out' }}
        />
      )}
      {children}
    </div>
  )
}

export const Tab: React.FC<{
  value: string
  children: React.ReactNode
  className?: string
}> = ({ value, children, className = '' }) => {
  const { value: activeValue, onChange } = useTabsContext()
  const isActive = activeValue === value

  return (
    <button
      type="button"
      data-active={isActive}
      className={`px-4 py-2 text-xs transition-colors cursor-pointer ${
        isActive ? 'font-extrabold text-teal-600' : 'font-semibold text-slate-400 hover:text-slate-600'
      } ${className}`}
      onClick={() => onChange(value)}
    >
      {children}
    </button>
  )
}

export const TabContent: React.FC<{
  value: string
  children: React.ReactNode
  className?: string
}> = ({ value, children, className = '' }) => {
  const { value: activeValue } = useTabsContext()
  if (activeValue !== value) return null
  return <div className={className}>{children}</div>
}

export type TabItem = { value: string; label: string }
