'use client'

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

interface DialogContextValue {
  isLoading: boolean
  setIsLoading: (loading: boolean) => void
  canClose: boolean
  setCanClose: (canClose: boolean) => void
}

const DialogContext = React.createContext<DialogContextValue | null>(null)

function useDialogContext() {
  const context = React.useContext(DialogContext)
  if (!context) {
    throw new Error('Dialog components must be used within BaseDialog')
  }
  return context
}

export interface BaseDialogProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  children: React.ReactNode
  size?: 'sm' | 'md' | 'lg'
  loading?: boolean
}

const sizeClasses = {
  sm: 'max-w-sm',
  md: 'max-w-md',
  lg: 'max-w-lg',
}

export function BaseDialog({
  open,
  onOpenChange,
  children,
  size = 'md',
  loading = false,
}: BaseDialogProps) {
  const [isLoading, setIsLoading] = React.useState(loading)
  const [canClose, setCanClose] = React.useState(!loading)

  React.useEffect(() => {
    setIsLoading(loading)
    setCanClose(!loading)
  }, [loading])

  const handleOpenChange = React.useCallback(
    (newOpen: boolean) => {
      if (!newOpen && !canClose) {
        return
      }
      onOpenChange(newOpen)
    },
    [canClose, onOpenChange]
  )

  const contextValue = React.useMemo(
    () => ({ isLoading, setIsLoading, canClose, setCanClose }),
    [isLoading, canClose]
  )

  return (
    <DialogContext.Provider value={contextValue}>
      <DialogPrimitive.Root open={open} onOpenChange={handleOpenChange}>
        <DialogPrimitive.Portal>
          <DialogPrimitive.Overlay className="fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" />
          <DialogPrimitive.Content
            className={cn(
              'fixed left-[50%] top-[50%] z-50 grid w-full translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
              sizeClasses[size]
            )}
            onInteractOutside={(e) => {
              if (!canClose) e.preventDefault()
            }}
            onEscapeKeyDown={(e) => {
              if (!canClose) e.preventDefault()
            }}
          >
            {children}
          </DialogPrimitive.Content>
        </DialogPrimitive.Portal>
      </DialogPrimitive.Root>
    </DialogContext.Provider>
  )
}

export interface DialogHeaderProps {
  children: React.ReactNode
  className?: string
}

function DialogHeader({ children, className }: DialogHeaderProps) {
  const { canClose } = useDialogContext()

  return (
    <div className={cn('flex items-start justify-between', className)}>
      <div className="flex flex-col space-y-1.5">{children}</div>
      <DialogPrimitive.Close
        className={cn(
          'rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none',
          !canClose && 'pointer-events-none opacity-30'
        )}
        disabled={!canClose}
      >
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="16"
          height="16"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth="2"
          strokeLinecap="round"
          strokeLinejoin="round"
        >
          <line x1="18" y1="6" x2="6" y2="18" />
          <line x1="6" y1="6" x2="18" y2="18" />
        </svg>
        <span className="sr-only">Close</span>
      </DialogPrimitive.Close>
    </div>
  )
}

export interface DialogTitleProps {
  children: React.ReactNode
  className?: string
}

function DialogTitle({ children, className }: DialogTitleProps) {
  return (
    <DialogPrimitive.Title
      className={cn(
        'text-lg font-semibold leading-none tracking-tight',
        className
      )}
    >
      {children}
    </DialogPrimitive.Title>
  )
}

export interface DialogBodyProps {
  children: React.ReactNode
  className?: string
}

function DialogBody({ children, className }: DialogBodyProps) {
  return (
    <div className={cn('py-4 overflow-y-auto', className)}>{children}</div>
  )
}

export interface DialogFooterProps {
  children: React.ReactNode
  className?: string
}

function DialogFooter({ children, className }: DialogFooterProps) {
  return (
    <div
      className={cn(
        'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
        className
      )}
    >
      {children}
    </div>
  )
}

// Compound component pattern
BaseDialog.Header = DialogHeader
BaseDialog.Title = DialogTitle
BaseDialog.Body = DialogBody
BaseDialog.Footer = DialogFooter

export { useDialogContext }
