'use client'

import * as React from 'react'
import { Drawer as DrawerPrimitive } from 'vaul'
import { cn } from '../../utils'
import {
  ButtonSet,
  type ButtonSetSize,
  type ButtonSetOrientation,
} from '../Button/ButtonSet'
import { typographyVariants } from '../Typography'

type DrawerTriggerProps = React.ComponentPropsWithoutRef<
  typeof DrawerPrimitive.Trigger
>
type DrawerCloseProps = React.ComponentPropsWithoutRef<
  typeof DrawerPrimitive.Close
>
type DrawerOverlayProps = React.ComponentPropsWithoutRef<
  typeof DrawerPrimitive.Overlay
>
type DrawerContentProps = React.ComponentPropsWithoutRef<
  typeof DrawerPrimitive.Content
>
type DrawerTitleProps = React.ComponentPropsWithoutRef<
  typeof DrawerPrimitive.Title
>
type DrawerDescriptionProps = React.ComponentPropsWithoutRef<
  typeof DrawerPrimitive.Description
>

const Drawer = ({
  shouldScaleBackground = true,
  ...props
}: React.ComponentProps<typeof DrawerPrimitive.Root>) => (
  <DrawerPrimitive.Root
    shouldScaleBackground={shouldScaleBackground}
    {...props}
  />
)
Drawer.displayName = 'Drawer'

const DrawerTrigger: React.FC<DrawerTriggerProps> = (props) => (
  <DrawerPrimitive.Trigger {...props} />
)
DrawerTrigger.displayName = 'DrawerTrigger'

const DrawerPortal = DrawerPrimitive.Portal

const DrawerClose: React.FC<DrawerCloseProps> = (props) => (
  <DrawerPrimitive.Close {...props} />
)
DrawerClose.displayName = 'DrawerClose'

const DrawerOverlay: React.ForwardRefExoticComponent<
  DrawerOverlayProps & React.RefAttributes<HTMLDivElement>
> = React.forwardRef<HTMLDivElement, DrawerOverlayProps>(
  ({ className, ...props }, ref) => (
    <DrawerPrimitive.Overlay
      ref={ref}
      className={cn('fixed inset-0 z-50 bg-black/80', className)}
      {...props}
    />
  ),
)
DrawerOverlay.displayName = 'DrawerOverlay'

const DrawerHandle = React.forwardRef<
  React.ElementRef<typeof DrawerPrimitive.Handle>,
  React.ComponentPropsWithoutRef<typeof DrawerPrimitive.Handle>
>(({ className, ...props }, ref) => (
  <DrawerPrimitive.Handle
    ref={ref}
    className={cn('mt-4 h-2 w-[100px] rounded-full bg-muted', className)}
    {...props}
  />
))
DrawerHandle.displayName = 'DrawerHandle'

const DrawerContent: React.ForwardRefExoticComponent<
  DrawerContentProps & React.RefAttributes<HTMLDivElement>
> = React.forwardRef<HTMLDivElement, DrawerContentProps>(
  ({ className, children, ...props }, ref) => (
    <DrawerPortal>
      <DrawerOverlay />
      <DrawerPrimitive.Content
        ref={ref}
        className={cn(
          'fixed inset-x-0 bottom-0 z-50 flex w-full flex-col rounded-t-xl border border-border bg-background text-foreground focus:outline-none',
          className,
        )}
        {...props}
      >
        {children}
      </DrawerPrimitive.Content>
    </DrawerPortal>
  ),
)
DrawerContent.displayName = 'DrawerContent'

const DrawerHeader = ({
  className,
  ...props
}: React.HTMLAttributes<HTMLDivElement>) => (
  <div
    className={cn('grid gap-1.5 p-4 text-center sm:text-left', className)}
    {...props}
  />
)
DrawerHeader.displayName = 'DrawerHeader'

const DrawerFooter = ({
  className,
  size,
  orientation,
  children,
  ...props
}: React.HTMLAttributes<HTMLDivElement> & {
  size?: ButtonSetSize
  orientation?: ButtonSetOrientation
}) => (
  <ButtonSet
    size={size}
    orientation={orientation}
    className={cn('w-full justify-center p-4', className)}
    {...(props as any)}
  >
    {children}
  </ButtonSet>
)
DrawerFooter.displayName = 'DrawerFooter'

const DrawerTitle: React.ForwardRefExoticComponent<
  DrawerTitleProps & React.RefAttributes<HTMLHeadingElement>
> = React.forwardRef<HTMLHeadingElement, DrawerTitleProps>(
  ({ className, ...props }, ref) => (
    <DrawerPrimitive.Title
      ref={ref}
      className={cn(
        typographyVariants({ variant: 'body-semi-s' }),
        '!max-w-none text-center leading-none tracking-tight',
        className,
      )}
      {...props}
    />
  ),
)
DrawerTitle.displayName = 'DrawerTitle'

const DrawerDescription: React.ForwardRefExoticComponent<
  DrawerDescriptionProps & React.RefAttributes<HTMLParagraphElement>
> = React.forwardRef<HTMLParagraphElement, DrawerDescriptionProps>(
  ({ className, ...props }, ref) => (
    <DrawerPrimitive.Description
      ref={ref}
      className={cn('text-sm text-muted-foreground', className)}
      {...props}
    />
  ),
)
DrawerDescription.displayName = 'DrawerDescription'

export {
  Drawer,
  DrawerPortal,
  DrawerOverlay,
  DrawerTrigger,
  DrawerClose,
  DrawerContent,
  DrawerHeader,
  DrawerFooter,
  DrawerTitle,
  DrawerDescription,
  DrawerHandle,
}
