'use client'
import {
  Children,
  createContext,
  useContext,
  useEffect,
  useRef,
  useState,
} from 'react'
import { Tab, TabGroup, TabList, TabPanel, TabPanels } from '@headlessui/react'
import { Tag } from './tag'
import classNames from '@/utils/classnames'
import { writeTextToClipboard } from '@/utils/clipboard'
import type { PropsWithChildren, ReactElement, ReactNode } from 'react'
const languageNames = {
  js: 'JavaScript',
  ts: 'TypeScript',
  javascript: 'JavaScript',
  typescript: 'TypeScript',
  php: 'PHP',
  python: 'Python',
  ruby: 'Ruby',
  go: 'Go',
} as { [key: string]: string }
type IChildrenProps = {
  children: React.ReactNode
  [key: string]: any
}
function ClipboardIcon(props: any) {
  return (
    
  )
}
function CopyButton({ code }: { code: string }) {
  const [copyCount, setCopyCount] = useState(0)
  const copied = copyCount > 0
  useEffect(() => {
    if (copyCount > 0) {
      const timeout = setTimeout(() => setCopyCount(0), 1000)
      return () => {
        clearTimeout(timeout)
      }
    }
  }, [copyCount])
  return (
    
  )
}
function CodePanelHeader({ tag, label }: { tag?: string; label?: string }) {
  if (!tag && !label)
    return null
  return (
    
      {tag && (
        
          {tag}
        
      )}
      {tag && label && (
        
      )}
      {label && (
        
{label}
      )}
    
 
  )
}
type CodeExample = {
  title?: string
  tag?: string
  code: string
}
type ICodePanelProps = {
  children?: React.ReactNode
  tag?: string
  label?: string
  code?: string
  title?: string
  targetCode?: CodeExample
}
function CodePanel({ tag, label, children, targetCode }: ICodePanelProps) {
  const child = Children.toArray(children)[0] as ReactElement
  return (
    
      
      
        {/* 
{children} */}
        {/* 
 */}
        {/* 
 */}
        
          {targetCode?.code ? (
            {targetCode?.code}
          ) : (
            child
          )}
        
        
       
     
  )
}
type CodeGroupHeaderProps = {
  title?: string
  tabTitles?: string[]
  selectedIndex?: number
}
function CodeGroupHeader({ title, tabTitles, selectedIndex }: CodeGroupHeaderProps) {
  const hasTabs = (tabTitles?.length ?? 0) > 1
  return (
    
      {title && (
        
          {title}
        
      )}
      {hasTabs && (
        
          {tabTitles!.map((tabTitle, tabIndex) => (
            
              {tabTitle}
            
          ))}
        
      )}
    
  )
}
type ICodeGroupPanelsProps = PropsWithChildren<{
  targetCode?: CodeExample[]
  [key: string]: any
}>
function CodeGroupPanels({ children, targetCode, ...props }: ICodeGroupPanelsProps) {
  if ((targetCode?.length ?? 0) > 1) {
    return (
      
        {targetCode!.map(code => (
          
            
          
        ))}
      
    )
  }
  return {children}
}
function usePreventLayoutShift() {
  const positionRef = useRef()
  const rafRef = useRef()
  useEffect(() => {
    return () => {
      window.cancelAnimationFrame(rafRef.current)
    }
  }, [])
  return {
    positionRef,
    preventLayoutShift(callback: () => {}) {
      const initialTop = positionRef.current.getBoundingClientRect().top
      callback()
      rafRef.current = window.requestAnimationFrame(() => {
        const newTop = positionRef.current.getBoundingClientRect().top
        window.scrollBy(0, newTop - initialTop)
      })
    },
  }
}
function useTabGroupProps(availableLanguages: string[]) {
  const [preferredLanguages, addPreferredLanguage] = useState([])
  const [selectedIndex, setSelectedIndex] = useState(0)
  const activeLanguage = [...(availableLanguages || [])].sort(
    (a, z) => preferredLanguages.indexOf(z) - preferredLanguages.indexOf(a),
  )[0]
  const languageIndex = availableLanguages?.indexOf(activeLanguage) || 0
  const newSelectedIndex = languageIndex === -1 ? selectedIndex : languageIndex
  if (newSelectedIndex !== selectedIndex)
    setSelectedIndex(newSelectedIndex)
  const { positionRef, preventLayoutShift } = usePreventLayoutShift()
  return {
    as: 'div',
    ref: positionRef,
    selectedIndex,
    onChange: (newSelectedIndex: number) => {
      preventLayoutShift(() =>
        (addPreferredLanguage(availableLanguages[newSelectedIndex]) as any),
      )
    },
  }
}
const CodeGroupContext = createContext(false)
type CodeGroupProps = PropsWithChildren<{
  /** Code example(s) to display */
  targetCode?: string | CodeExample[]
  /** Example block title */
  title?: string
  /** HTTP method tag, e.g. GET, POST */
  tag?: string
  /** API path */
  label?: string
}>
export function CodeGroup({ children, title, targetCode, ...props }: CodeGroupProps) {
  const examples = typeof targetCode === 'string' ? [{ code: targetCode }] as CodeExample[] : targetCode
  const tabTitles = examples?.map(({ title }) => title || 'Code') || []
  const tabGroupProps = useTabGroupProps(tabTitles)
  const hasTabs = tabTitles.length > 1
  const Container = hasTabs ? TabGroup : 'div'
  const containerProps = hasTabs ? tabGroupProps : {}
  const headerProps = hasTabs
    ? { selectedIndex: tabGroupProps.selectedIndex, tabTitles }
    : {}
  return (
    
      
        
        {children}
      
    
  )
}
type IChildProps = {
  children: ReactNode
  [key: string]: any
}
export function Code({ children, ...props }: IChildProps) {
  return {children}
}
export function Pre({ children, ...props }: IChildrenProps) {
  const isGrouped = useContext(CodeGroupContext)
  if (isGrouped)
    return children
  return {children}
}
export function Embed({ value, ...props }: IChildrenProps) {
  return {value}
}