"use client"

import * as React from "react"
import { createPortal } from "react-dom"
import { Check, ChevronRight, Circle } from "lucide-react"
import { cn } from "@/lib/utils"

const DropdownMenuContext = React.createContext<{
  open: boolean
  setOpen: React.Dispatch<React.SetStateAction<boolean>>
  triggerRef: React.RefObject<HTMLElement>
}>({
  open: false,
  setOpen: () => {},
  triggerRef: { current: null },
})

export function DropdownMenu({
  children,
  open: controlledOpen,
  onOpenChange,
}: {
  children: React.ReactNode
  open?: boolean
  onOpenChange?: (open: boolean) => void
}) {
  const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false)
  const triggerRef = React.useRef<HTMLElement>(null)

  const isControlled = controlledOpen !== undefined
  const open = isControlled ? controlledOpen : uncontrolledOpen
  const setOpen = React.useCallback(
    (value: boolean | ((prev: boolean) => boolean)) => {
      if (isControlled) {
        const nextValue = typeof value === "function" ? value(controlledOpen) : value
        onOpenChange?.(nextValue)
      } else {
        setUncontrolledOpen(value)
      }
    },
    [isControlled, controlledOpen, onOpenChange],
  )

  return (
    <DropdownMenuContext.Provider value={{ open, setOpen, triggerRef }}>
      <div className="relative inline-block text-left">{children}</div>
    </DropdownMenuContext.Provider>
  )
}

export function DropdownMenuTrigger({
  children,
  asChild,
  className,
  ...props
}: {
  children: React.ReactNode
  asChild?: boolean
  className?: string
} & React.HTMLAttributes<HTMLButtonElement>) {
  const { open, setOpen, triggerRef } = React.useContext(DropdownMenuContext)

  const handleClick = (e: React.MouseEvent) => {
    e.preventDefault()
    setOpen(!open)
    props.onClick?.(e)
  }

  if (asChild && React.isValidElement(children)) {
    return React.cloneElement(children, {
      ref: triggerRef,
      onClick: handleClick,
      "aria-expanded": open,
      "aria-haspopup": true,
      ...props,
    })
  }

  return (
    <button
      type="button"
      ref={triggerRef as React.RefObject<HTMLButtonElement>}
      onClick={handleClick}
      className={className}
      aria-expanded={open}
      aria-haspopup={true}
      {...props}
    >
      {children}
    </button>
  )
}

export function DropdownMenuContent({
  children,
  className,
  align = "start",
  sideOffset = 4,
  alignOffset = 0,
  ...props
}: {
  children: React.ReactNode
  className?: string
  align?: "start" | "center" | "end"
  sideOffset?: number
  alignOffset?: number
} & React.HTMLAttributes<HTMLDivElement>) {
  const { open, setOpen, triggerRef } = React.useContext(DropdownMenuContext)
  const contentRef = React.useRef<HTMLDivElement>(null)
  const [mounted, setMounted] = React.useState(false)
  const [position, setPosition] = React.useState({
    top: 0,
    left: 0,
    transformOrigin: "top center",
  })

  React.useEffect(() => {
    setMounted(true)
    return () => setMounted(false)
  }, [])

  React.useEffect(() => {
    if (open && triggerRef.current && mounted) {
      const triggerRect = triggerRef.current.getBoundingClientRect()
      const viewportWidth = window.innerWidth
      const viewportHeight = window.innerHeight

      // Calculate width of content (estimate if not mounted yet)
      const contentWidth = contentRef.current?.offsetWidth || 200
      const contentHeight = contentRef.current?.offsetHeight || 200

      // Calculate left position based on alignment
      let left = 0
      if (align === "start") {
        left = triggerRect.left + alignOffset
      } else if (align === "center") {
        left = triggerRect.left + triggerRect.width / 2 - contentWidth / 2 + alignOffset
      } else if (align === "end") {
        left = triggerRect.right - contentWidth + alignOffset
      }

      // Ensure menu stays within viewport horizontally
      const rightOverflow = left + contentWidth - viewportWidth
      if (rightOverflow > 0) {
        left = Math.max(8, left - rightOverflow - 8) // 8px safety margin
      }
      if (left < 8) {
        left = 8 // 8px minimum margin from left edge
      }

      // Calculate top position
      let top = triggerRect.bottom + sideOffset
      let transformOrigin = "top center"

      // Check if menu would overflow bottom of viewport
      if (top + contentHeight > viewportHeight - 8) {
        // Position above trigger if not enough space below
        top = Math.max(8, triggerRect.top - contentHeight - sideOffset)
        transformOrigin = "bottom center"
      }

      setPosition({ top, left, transformOrigin })
    }
  }, [open, align, sideOffset, alignOffset, mounted])

  React.useEffect(() => {
    if (!mounted) return

    const handleClickOutside = (event: MouseEvent) => {
      if (
        contentRef.current &&
        !contentRef.current.contains(event.target as Node) &&
        triggerRef.current &&
        !triggerRef.current.contains(event.target as Node)
      ) {
        setOpen(false)
      }
    }

    const handleEscape = (event: KeyboardEvent) => {
      if (event.key === "Escape") {
        setOpen(false)
      }
    }

    if (open) {
      document.addEventListener("mousedown", handleClickOutside)
      document.addEventListener("keydown", handleEscape)
    }

    return () => {
      document.removeEventListener("mousedown", handleClickOutside)
      document.removeEventListener("keydown", handleEscape)
    }
  }, [open, setOpen, mounted])

  if (!mounted || !open) return null

  const content = (
    <div
      ref={contentRef}
      className={cn(
        "z-[9999] min-w-[8rem] overflow-hidden rounded-md border bg-[var(--background-primary)] p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
        className,
      )}
      style={{
        position: "fixed",
        top: `${position.top}px`,
        left: `${position.left}px`,
        transformOrigin: position.transformOrigin,
      }}
      {...props}
    >
      {children}
    </div>
  )

  return createPortal(content, document.body)
}

export function DropdownMenuItem({
  children,
  className,
  disabled,
  onSelect,
  ...props
}: {
  children: React.ReactNode
  className?: string
  disabled?: boolean
  onSelect?: () => void
} & React.HTMLAttributes<HTMLDivElement>) {
  const { setOpen } = React.useContext(DropdownMenuContext)

  const handleClick = (e: React.MouseEvent) => {
    if (disabled) return
    onSelect?.()
    setOpen(false)
    props.onClick?.(e)
  }

  return (
    <div
      className={cn(
        "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
        disabled ? "pointer-events-none opacity-50" : "cursor-pointer hover:bg-accent hover:text-accent-foreground",
        className,
      )}
      onClick={handleClick}
      data-disabled={disabled ? true : undefined}
      {...props}
    >
      {children}
    </div>
  )
}

export function DropdownMenuCheckboxItem({
  children,
  className,
  checked,
  onCheckedChange,
  disabled,
  ...props
}: {
  children: React.ReactNode
  className?: string
  checked?: boolean
  onCheckedChange?: (checked: boolean) => void
  disabled?: boolean
} & React.HTMLAttributes<HTMLDivElement>) {
  const handleSelect = () => {
    if (disabled) return
    onCheckedChange?.(!checked)
  }

  return (
    <DropdownMenuItem
      className={cn(
        "relative flex cursor-default select-none items-center rounded-sm pl-8 pr-2 py-1.5 text-sm",
        className,
      )}
      disabled={disabled}
      onSelect={handleSelect}
      {...props}
    >
      <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
        {checked && <Check className="h-4 w-4" />}
      </span>
      {children}
    </DropdownMenuItem>
  )
}

export function DropdownMenuRadioItem({
  children,
  className,
  checked,
  onSelect,
  disabled,
  ...props
}: {
  children: React.ReactNode
  className?: string
  checked?: boolean
  onSelect?: () => void
  disabled?: boolean
} & React.HTMLAttributes<HTMLDivElement>) {
  return (
    <DropdownMenuItem
      className={cn(
        "relative flex cursor-default select-none items-center rounded-sm pl-8 pr-2 py-1.5 text-sm",
        className,
      )}
      disabled={disabled}
      onSelect={onSelect}
      {...props}
    >
      <span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
        {checked && <Circle className="h-2 w-2 fill-current" />}
      </span>
      {children}
    </DropdownMenuItem>
  )
}

export function DropdownMenuLabel({
  children,
  className,
  inset,
  ...props
}: {
  children: React.ReactNode
  className?: string
  inset?: boolean
} & React.HTMLAttributes<HTMLDivElement>) {
  return (
    <div className={cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className)} {...props}>
      {children}
    </div>
  )
}

export function DropdownMenuSeparator({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
  return <div className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} />
}

export function DropdownMenuShortcut({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) {
  return <span className={cn("ml-auto text-xs tracking-widest opacity-60", className)} {...props} />
}

export function DropdownMenuGroup({ children, className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
  return (
    <div className={cn("", className)} {...props}>
      {children}
    </div>
  )
}

export function DropdownMenuSub({
  children,
  ...props
}: {
  children: React.ReactNode
}) {
  return <>{children}</>
}

export function DropdownMenuSubTrigger({
  children,
  className,
  ...props
}: {
  children: React.ReactNode
  className?: string
} & React.HTMLAttributes<HTMLDivElement>) {
  return (
    <div
      className={cn(
        "flex cursor-default select-none items-center rounded-sm px-1 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
        className,
      )}
      {...props}
    >
      {children}
      <ChevronRight className="ml-auto h-4 w-4" />
    </div>
  )
}

export function DropdownMenuSubContent({
  children,
  className,
  ...props
}: {
  children: React.ReactNode
  className?: string
} & React.HTMLAttributes<HTMLDivElement>) {
  return (
    <div
      className={cn(
        "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-[var(--background-primary)] p-1 text-popover-foreground shadow-md animate-in -ml-1",
        className,
      )}
      {...props}
    >
      {children}
    </div>
  )
}

export function DropdownMenuRadioGroup({ children, className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
  return (
    <div className={cn("", className)} {...props}>
      {children}
    </div>
  )
}
