import { IconButton } from '@/components/ui/button'
import { cn } from '@/lib/utils'
import { createContext, useContext, useEffect, useMemo, useCallback, useState, useRef } from 'react'

// 管理所有抽屉的层级顺序
export const DrawerLayerContext = createContext<{
  openOrder: string[]
  registerDrawer: (id: string) => void
  unregisterDrawer: (id: string) => void
  bringToFront: (id: string) => void
  getZIndex: (id: string) => number
}>({
  openOrder: [],
  registerDrawer: () => {},
  unregisterDrawer: () => {},
  bringToFront: () => {},
  getZIndex: () => 0,
})

export const DrawerLayerProvider = ({
  children,
  baseZIndex = 10,
}: {
  children: React.ReactNode
  baseZIndex?: number
}) => {
  const [openOrder, setOpenOrder] = useState<string[]>([])

  const registerDrawer = useCallback((id: string) => {
    setOpenOrder((prev) => (prev.includes(id) ? prev : [...prev, id]))
  }, [])

  const unregisterDrawer = useCallback((id: string) => {
    setOpenOrder((prev) => prev.filter((item) => item !== id))
  }, [])

  const bringToFront = useCallback((id: string) => {
    setOpenOrder((prev) => {
      // 如果该抽屉已经在最前面，则不需要更新
      if (prev.length > 0 && prev[prev.length - 1] === id) {
        return prev
      }
      const filtered = prev.filter((item) => item !== id)
      return [...filtered, id]
    })
  }, [])

  const getZIndex = useCallback(
    (id: string) => {
      const index = openOrder.indexOf(id)
      if (index === -1) return baseZIndex
      return baseZIndex + index
    },
    [openOrder, baseZIndex]
  )

  const value = useMemo(
    () => ({ openOrder, registerDrawer, unregisterDrawer, bringToFront, getZIndex }),
    [openOrder, registerDrawer, unregisterDrawer, bringToFront, getZIndex]
  )

  return <DrawerLayerContext.Provider value={value}>{children}</DrawerLayerContext.Provider>
}

const InlineDrawerContext = createContext<{
  id: string
  open: boolean
  onOpenChange: (open: boolean) => void
}>({
  id: '',
  open: false,
  onOpenChange: () => {},
})

export const InlineDrawer = ({
  id,
  open,
  onOpenChange,
  timestamp,
  children,
}: {
  id: string
  open: boolean
  onOpenChange: (open: boolean) => void
  timestamp?: number
  children: React.ReactNode
}) => {
  const { registerDrawer, unregisterDrawer, bringToFront } = useContext(DrawerLayerContext)

  // 当抽屉打开时注册并置顶；当关闭或卸载时移除
  // 监听 timestamp 变化，确保每次重新打开时都会置顶
  useEffect(() => {
    if (open) {
      registerDrawer(id)
      bringToFront(id)
    }
  }, [open, timestamp, id, registerDrawer, bringToFront])

  useEffect(() => {
    return () => {
      unregisterDrawer(id)
    }
  }, [id, unregisterDrawer, open])

  // 当抽屉关闭时不渲染任何内容
  if (!open) {
    return null
  }

  return (
    <InlineDrawerContext.Provider value={{ id, open, onOpenChange }}>
      {children}
    </InlineDrawerContext.Provider>
  )
}

export const InlineDrawerContent = ({
  children,
  className,
}: {
  children: React.ReactNode
  className?: string
}) => {
  const { id } = useContext(InlineDrawerContext)
  const { getZIndex, bringToFront } = useContext(DrawerLayerContext)
  const zIndex = getZIndex(id)
  return (
    <div
      className={cn(
        'bg-background-default border-outline-normal absolute inset-0 flex w-[400px] flex-col border-l border-solid',
        className
      )}
      style={{ zIndex }}
      onPointerDownCapture={() => bringToFront(id)}
    >
      {children}
    </div>
  )
}

export const InlineDrawerHeader = ({ children }: { children: React.ReactNode }) => {
  const { onOpenChange } = useContext(InlineDrawerContext)
  return (
    <div className="flex items-center gap-2 p-6">
      <IconButton
        iconfont="icon-arrow-right"
        variant="ghost"
        size="small"
        onClick={() => onOpenChange(false)}
      />
      <div className="txt-title-m min-w-0 flex-1">{children}</div>
    </div>
  )
}

export const InlineDrawerDescription = ({
  children,
  className,
}: {
  children: React.ReactNode
  className?: string
}) => {
  return <div className={cn('flex-1 overflow-y-auto px-6', className)}>{children}</div>
}

export const InlineDrawerFooter = ({
  children,
  className,
}: {
  children: React.ReactNode
  className?: string
}) => {
  return <div className={cn('flex items-center justify-end gap-4 p-6', className)}>{children}</div>
}
