import { useEffect, useRef } from 'react'
import type { ReactNode } from 'react'

interface ModalProps {
  children: ReactNode
  isOpen: boolean
  onClose: () => void
  title?: string
  size?: 'small' | 'medium' | 'large' | 'full'
  showCloseButton?: boolean
  'aria-label'?: string
}

function getSizeClasses(size: ModalProps['size']): string {
  switch (size) {
    case 'small':
      return 'max-w-md'
    case 'medium':
      return 'max-w-lg'
    case 'large':
      return 'max-w-xl'
    case 'full':
      return 'max-w-full mx-4'
    default:
      return 'max-w-md'
  }
}

function CloseButton({ onClose }: { onClose: () => void }): React.ReactElement {
  return (
    <button
      onClick={onClose}
      className="text-cyber-accent hover:text-neon-cyan text-2xl transition-colors focus:outline-none focus:ring-2 focus:ring-neon-cyan rounded"
      aria-label="Close modal"
    >
      ×
    </button>
  )
}

function ModalHeader({
  title,
  showCloseButton,
  onClose,
}: {
  title?: string
  showCloseButton: boolean
  onClose: () => void
}): React.ReactElement | null {
  if (!title && !showCloseButton) {
    return null
  }
  return (
    <div className="flex justify-between items-center mb-4">
      {title && <h2 className="text-xl font-bold text-neon-cyan">{title}</h2>}
      {showCloseButton && <CloseButton onClose={onClose} />}
    </div>
  )
}

export function Modal({
  children,
  isOpen,
  onClose,
  title,
  size = 'medium',
  showCloseButton = true,
  'aria-label': ariaLabel,
}: ModalProps): React.ReactElement | null {
  const modalRef = useRef<HTMLDivElement>(null)
  const previousFocusRef = useRef<HTMLElement | null>(null)

  useEffect(() => {
    if (isOpen) {
      previousFocusRef.current = document.activeElement as HTMLElement
      const firstFocusable = modalRef.current?.querySelector(
        'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
      ) as HTMLElement | null
      if (firstFocusable) {
        firstFocusable.focus()
      }
    } else {
      previousFocusRef.current?.focus()
    }
  }, [isOpen])

  useEffect(() => {
    const handleEscape = (e: KeyboardEvent): void => {
      if (e.key === 'Escape' && isOpen) {
        onClose()
      }
    }

    if (isOpen) {
      document.addEventListener('keydown', handleEscape)
      document.body.style.overflow = 'hidden'
    }

    return () => {
      document.removeEventListener('keydown', handleEscape)
      document.body.style.overflow = ''
    }
  }, [isOpen, onClose])

  if (!isOpen) {
    return null
  }

  const sizeClasses = getSizeClasses(size)

  return (
    <div
      className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
      onClick={(e) => {
        if (e.target === e.currentTarget) {
          onClose()
        }
      }}
      role="dialog"
      aria-modal="true"
      aria-label={ariaLabel ?? title}
    >
      <div
        ref={modalRef}
        className={`bg-cyber-dark border border-neon-cyan/30 rounded-lg p-6 w-full mx-4 max-h-[90vh] overflow-y-auto shadow-glow-cyan ${sizeClasses}`}
        onClick={(e) => e.stopPropagation()}
      >
        <ModalHeader title={title} showCloseButton={showCloseButton} onClose={onClose} />
        {children}
      </div>
    </div>
  )
}
