import * as React from 'react'
import * as DialogPrimitive from '@radix-ui/react-dialog'
import { X } from 'lucide-react'
import { cn } from '../lib/cn'

export interface DialogProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  title: string
  description?: string
  size?: 'sm' | 'md' | 'lg' | 'xl' | 'full'
  children?: React.ReactNode
}

const sizeMap: Record<NonNullable<DialogProps['size']>, string> = {
  sm: 'max-w-screen-sm',
  md: 'max-w-screen-md',
  lg: 'max-w-screen-lg',
  xl: 'max-w-screen-xl',
  full: 'max-w-full',
}

const DialogRoot = ({ open, onOpenChange, title, description, size = 'md', children }: DialogProps) => (
  <DialogPrimitive.Root open={open} onOpenChange={onOpenChange}>
    <DialogPrimitive.Portal>
      <DialogPrimitive.Overlay
        className={cn(
          'fixed inset-0 z-50 bg-ink/40',
          'data-[state=open]:animate-in data-[state=closed]:animate-out motion-reduce:animate-none',
        )}
      />
      <DialogPrimitive.Content
        className={cn(
          'fixed start-1/2 top-1/2 z-50 w-full -translate-x-1/2 -translate-y-1/2 rtl:translate-x-1/2',
          'rounded border border-line bg-surface p-6 text-ink shadow',
          'focus:outline-none',
          sizeMap[size],
        )}
      >
        <DialogPrimitive.Title className="text-title-2 font-medium text-ink">
          {title}
        </DialogPrimitive.Title>
        {description ? (
          <DialogPrimitive.Description className="mt-2 text-body-2 text-ink-soft">
            {description}
          </DialogPrimitive.Description>
        ) : null}
        <div className="mt-4">{children}</div>
        <DialogPrimitive.Close
          className="absolute end-4 top-4 rounded text-ink-faint hover:text-ink focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent-border"
          aria-label="Close"
        >
          <X className="h-4 w-4" aria-hidden="true" />
        </DialogPrimitive.Close>
      </DialogPrimitive.Content>
    </DialogPrimitive.Portal>
  </DialogPrimitive.Root>
)
DialogRoot.displayName = 'Dialog'

const DialogTrigger = DialogPrimitive.Trigger

const DialogContent: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (
  <div className={cn('flex flex-col gap-4', className)} {...props} />
)
DialogContent.displayName = 'Dialog.Content'

const DialogFooter: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({ className, ...props }) => (
  <div className={cn('mt-6 flex items-center justify-end gap-2', className)} {...props} />
)
DialogFooter.displayName = 'Dialog.Footer'

interface DialogComposition {
  Trigger: typeof DialogTrigger
  Content: typeof DialogContent
  Footer: typeof DialogFooter
}

export const Dialog = Object.assign(DialogRoot, {
  Trigger: DialogTrigger,
  Content: DialogContent,
  Footer: DialogFooter,
}) as typeof DialogRoot & DialogComposition
