import * as React from 'react'
import * as ContextMenuPrimitive from '@radix-ui/react-context-menu'
import { Check, ChevronRight, Circle } from 'lucide-react'
import tw from 'twin.macro'

const ContextMenu = ContextMenuPrimitive.Root

const ContextMenuTrigger = ContextMenuPrimitive.Trigger

const ContextMenuGroup = ContextMenuPrimitive.Group

const ContextMenuPortal = ContextMenuPrimitive.Portal

const ContextMenuSub = ContextMenuPrimitive.Sub

const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup

const ContextMenuSubTrigger = React.forwardRef<
  React.ElementRef<typeof ContextMenuPrimitive.SubTrigger>,
  React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubTrigger> & {
    inset?: boolean
  }
>(({ inset, children, ...props }, ref) => (
  <ContextMenuPrimitive.SubTrigger
    ref={ref}
    css={[
      tw`
        flex
        cursor-default
        select-none
        items-center
        rounded-sm
        py-1.5
        px-2
        text-sm
        font-medium
        outline-none
        focus:bg-slate-100
        data-[state=open]:bg-slate-100
        dark:focus:bg-slate-700
        dark:data-[state=open]:bg-slate-700
      `,
      inset && tw`pl-8`,
    ]}
    {...props}
  >
    {children}
    <ChevronRight tw="ml-auto h-4 w-4" />
  </ContextMenuPrimitive.SubTrigger>
))
ContextMenuSubTrigger.displayName = ContextMenuPrimitive.SubTrigger.displayName

const ContextMenuSubContent = React.forwardRef<
  React.ElementRef<typeof ContextMenuPrimitive.SubContent>,
  React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.SubContent>
>((props, ref) => (
  <ContextMenuPrimitive.SubContent
    ref={ref}
    css={[
      tw`
        z-50
        min-w-[8rem]
        overflow-hidden
        rounded-md
        border
        border-slate-100
        bg-white
        p-1
        shadow-md
        animate-in
        slide-in-from-left-1
        dark:border-slate-700
        dark:bg-slate-800
      `,
    ]}
    {...props}
  />
))
ContextMenuSubContent.displayName = ContextMenuPrimitive.SubContent.displayName

const ContextMenuContent = React.forwardRef<
  React.ElementRef<typeof ContextMenuPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Content>
>((props, ref) => (
  <ContextMenuPrimitive.Portal>
    <ContextMenuPrimitive.Content
      ref={ref}
      css={[
        tw`
          z-50
          min-w-[8rem]
          overflow-hidden
          rounded-md
          border
          border-slate-100
          bg-white
          p-1
          text-slate-700
          shadow-md
          animate-in
          fade-in-80
          dark:border-slate-800
          dark:bg-slate-800
          dark:text-slate-400
        `,
      ]}
      {...props}
    />
  </ContextMenuPrimitive.Portal>
))
ContextMenuContent.displayName = ContextMenuPrimitive.Content.displayName

const ContextMenuItem = React.forwardRef<
  React.ElementRef<typeof ContextMenuPrimitive.Item>,
  React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Item> & {
    inset?: boolean
  }
>(({ inset, ...props }, ref) => (
  <ContextMenuPrimitive.Item
    ref={ref}
    css={[
      tw`
        relative
        flex
        cursor-default
        select-none
        items-center
        rounded-sm
        py-1.5
        px-2
        text-sm
        font-medium
        outline-none
        focus:bg-slate-100
        data-[disabled]:pointer-events-none
        data-[disabled]:opacity-50
        dark:focus:bg-slate-700
      `,
      inset && tw`pl-8`,
    ]}
    {...props}
  />
))
ContextMenuItem.displayName = ContextMenuPrimitive.Item.displayName

const ContextMenuCheckboxItem = React.forwardRef<
  React.ElementRef<typeof ContextMenuPrimitive.CheckboxItem>,
  React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.CheckboxItem>
>(({ children, checked, ...props }, ref) => (
  <ContextMenuPrimitive.CheckboxItem
    ref={ref}
    css={[
      tw`
        relative
        flex
        cursor-default
        select-none
        items-center
        rounded-sm
        py-1.5
        pl-8
        pr-2
        text-sm
        font-medium
        outline-none
        focus:bg-slate-100
        data-[disabled]:pointer-events-none
        data-[disabled]:opacity-50
        dark:focus:bg-slate-700
      `,
    ]}
    checked={checked}
    {...props}
  >
    <span tw="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
      <ContextMenuPrimitive.ItemIndicator>
        <Check tw="h-4 w-4" />
      </ContextMenuPrimitive.ItemIndicator>
    </span>
    {children}
  </ContextMenuPrimitive.CheckboxItem>
))
ContextMenuCheckboxItem.displayName =
  ContextMenuPrimitive.CheckboxItem.displayName

const ContextMenuRadioItem = React.forwardRef<
  React.ElementRef<typeof ContextMenuPrimitive.RadioItem>,
  React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.RadioItem>
>(({ children, ...props }, ref) => (
  <ContextMenuPrimitive.RadioItem
    ref={ref}
    css={[
      tw`
        relative
        flex
        cursor-default
        select-none
        items-center
        rounded-sm
        py-1.5
        pl-8
        pr-2
        text-sm
        font-medium
        outline-none
        focus:bg-slate-100
        data-[disabled]:pointer-events-none
        data-[disabled]:opacity-50
        dark:focus:bg-slate-700
      `,
    ]}
    {...props}
  >
    <span tw="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
      <ContextMenuPrimitive.ItemIndicator>
        <Circle tw="h-2 w-2 fill-current" />
      </ContextMenuPrimitive.ItemIndicator>
    </span>
    {children}
  </ContextMenuPrimitive.RadioItem>
))
ContextMenuRadioItem.displayName = ContextMenuPrimitive.RadioItem.displayName

const ContextMenuLabel = React.forwardRef<
  React.ElementRef<typeof ContextMenuPrimitive.Label>,
  React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Label> & {
    inset?: boolean
  }
>(({ inset, ...props }, ref) => (
  <ContextMenuPrimitive.Label
    ref={ref}
    css={[
      tw`px-2 py-1.5 text-sm font-semibold text-slate-900 dark:text-slate-300`,

      inset && tw`pl-8`,
    ]}
    {...props}
  />
))
ContextMenuLabel.displayName = ContextMenuPrimitive.Label.displayName

const ContextMenuSeparator = React.forwardRef<
  React.ElementRef<typeof ContextMenuPrimitive.Separator>,
  React.ComponentPropsWithoutRef<typeof ContextMenuPrimitive.Separator>
>((props, ref) => (
  <ContextMenuPrimitive.Separator
    ref={ref}
    css={[tw`-mx-1 my-1 h-px bg-slate-100 dark:bg-slate-700`]}
    {...props}
  />
))
ContextMenuSeparator.displayName = ContextMenuPrimitive.Separator.displayName

function ContextMenuShortcut({
  ...props
}: React.HTMLAttributes<HTMLSpanElement>) {
  return (
    <span
      css={[tw`ml-auto text-xs tracking-widest text-slate-500`]}
      {...props}
    />
  )
}
ContextMenuShortcut.displayName = 'ContextMenuShortcut'

const _ContextMenu = ContextMenu
export {
  _ContextMenu as Root,
  ContextMenuTrigger as Trigger,
  ContextMenuContent as Content,
  ContextMenuItem as Item,
  ContextMenuCheckboxItem as CheckboxItem,
  ContextMenuRadioItem as RadioItem,
  ContextMenuLabel as Label,
  ContextMenuSeparator as Separator,
  ContextMenuShortcut as Shortcut,
  ContextMenuGroup as Group,
  ContextMenuPortal as Portal,
  ContextMenuSub as Sub,
  ContextMenuSubContent as SubContent,
  ContextMenuSubTrigger as SubTrigger,
  ContextMenuRadioGroup as RadioGroup,
}
