import * as React from 'react'
import * as DialogPrimitive from '@radix-ui/react-dialog'
import { X } from 'lucide-react'
import tw from 'twin.macro'

const Dialog = DialogPrimitive.Root

const DialogTrigger = DialogPrimitive.Trigger

function DialogPortal({
  children,
  ...props
}: DialogPrimitive.DialogPortalProps) {
  return (
    <DialogPrimitive.Portal {...props}>
      <div tw="fixed inset-0 z-50 flex items-start justify-center sm:items-center">
        {children}
      </div>
    </DialogPrimitive.Portal>
  )
}
DialogPortal.displayName = DialogPrimitive.Portal.displayName

const DialogOverlay = React.forwardRef<
  React.ElementRef<typeof DialogPrimitive.Overlay>,
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>((props, ref) => (
  <DialogPrimitive.Overlay
    css={[
      tw`
        fixed
        inset-0
        z-50
        bg-black/50
        backdrop-blur-sm
        transition-all
        duration-100
        data-[state=closed]:animate-out
        data-[state=open]:fade-in
        data-[state=closed]:fade-out
      `,
    ]}
    {...props}
    ref={ref}
  />
))
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName

const DialogContent = React.forwardRef<
  React.ElementRef<typeof DialogPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ children, ...props }, ref) => (
  <DialogPortal>
    <DialogOverlay />
    <DialogPrimitive.Content
      ref={ref}
      css={[
        tw`
          fixed
          z-50
          grid
          w-full
          gap-4
          rounded-b-lg
          bg-white
          p-6
          animate-in
          data-[state=open]:fade-in-90
          data-[state=open]:slide-in-from-bottom-10
          sm:max-w-lg
          sm:rounded-lg sm:zoom-in-90
          data-[state=open]:sm:slide-in-from-bottom-0
          dark:bg-slate-900
        `,
      ]}
      {...props}
    >
      {children}
      <DialogPrimitive.Close
        css={tw`
        absolute
        top-4
        right-4
        rounded-sm
        opacity-70
        transition-opacity
        hover:opacity-100
        focus:outline-none
        focus:ring-2
        focus:ring-slate-400
        focus:ring-offset-2
        disabled:pointer-events-none
        data-[state=open]:bg-slate-100
        dark:focus:ring-slate-400
        dark:focus:ring-offset-slate-900
        dark:data-[state=open]:bg-slate-800
      `}
      >
        <X tw="h-4 w-4" />
        <span tw="sr-only">Close</span>
      </DialogPrimitive.Close>
    </DialogPrimitive.Content>
  </DialogPortal>
))
DialogContent.displayName = DialogPrimitive.Content.displayName

function DialogHeader(props: React.HTMLAttributes<HTMLDivElement>) {
  return (
    <div tw="flex flex-col space-y-2 text-center sm:text-left" {...props} />
  )
}
DialogHeader.displayName = 'DialogHeader'

function DialogFooter(props: React.HTMLAttributes<HTMLDivElement>) {
  return (
    <div
      tw="flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2"
      {...props}
    />
  )
}
DialogFooter.displayName = 'DialogFooter'

const DialogTitle = React.forwardRef<
  React.ElementRef<typeof DialogPrimitive.Title>,
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
>((props, ref) => (
  <DialogPrimitive.Title
    ref={ref}
    css={[tw`text-lg font-semibold text-slate-900`, tw`dark:text-slate-50`]}
    {...props}
  />
))
DialogTitle.displayName = DialogPrimitive.Title.displayName

const DialogDescription = React.forwardRef<
  React.ElementRef<typeof DialogPrimitive.Description>,
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
>((props, ref) => (
  <DialogPrimitive.Description
    ref={ref}
    css={[tw`text-sm text-slate-500`, tw`dark:text-slate-400`]}
    {...props}
  />
))
DialogDescription.displayName = DialogPrimitive.Description.displayName

const _Dialog = Dialog
export {
  _Dialog as Root,
  DialogTrigger as Trigger,
  DialogContent as Content,
  DialogHeader as Header,
  DialogFooter as Footer,
  DialogTitle as Title,
  DialogDescription as Description,
}
