'use client';

import React, {
  useEffect,
  useRef,
  type ReactNode,
  type KeyboardEvent as ReactKeyboardEvent,
} from 'react';
import { Box } from './Box';
import { Text } from './Text';
import { Heading } from './Heading';
import { Button } from './Button';

interface ModalProps {
  title: string;
  description?: string;
  children?: ReactNode;
  primaryActionLabel?: string;
  secondaryActionLabel?: string;
  onPrimaryAction?: () => void | Promise<void>;
  onSecondaryAction?: () => void;
  onOpenChange?: (open: boolean) => void;
  isOpen: boolean;
}

export function Modal({
  title,
  description,
  children,
  primaryActionLabel,
  secondaryActionLabel,
  onPrimaryAction,
  onSecondaryAction,
  onOpenChange,
  isOpen,
}: ModalProps) {
  const dialogRef = useRef<HTMLDivElement | null>(null);
  const previouslyFocusedElementRef = useRef<Element | null>(null);

  useEffect(() => {
    if (isOpen) {
      previouslyFocusedElementRef.current = document.activeElement;
      const focusable = getFirstFocusable(dialogRef.current);
      if (focusable) {
        focusable.focus();
      } else if (dialogRef.current) {
        dialogRef.current.focus();
      }
      return;
    }

    if (!isOpen && previouslyFocusedElementRef.current instanceof HTMLElement) {
      previouslyFocusedElementRef.current.focus();
    }
  }, [isOpen]);

  const handleKeyDown = (event: ReactKeyboardEvent<HTMLDivElement>) => {
    if (event.key === 'Escape') {
      if (onOpenChange) {
        onOpenChange(false);
      }
      return;
    }

    if (event.key === 'Tab') {
      const focusable = getFocusableElements(dialogRef.current);
      if (focusable.length === 0) return;

      const first = focusable[0];
      const last = focusable[focusable.length - 1] ?? first;

      if (!first || !last) {
        return;
      }

      if (!event.shiftKey && document.activeElement === last) {
        event.preventDefault();
        first.focus();
      } else if (event.shiftKey && document.activeElement === first) {
        event.preventDefault();
        last.focus();
      }
    }
  };

  const handleBackdropClick = (event: React.MouseEvent<HTMLDivElement>) => {
    if (event.target === event.currentTarget && onOpenChange) {
      onOpenChange(false);
    }
  };

  if (!isOpen) {
    return null;
  }

  return (
    <Box
      style={{ position: 'fixed', inset: 0, zIndex: 60, display: 'flex', alignItems: 'center', justifyContent: 'center', backgroundColor: 'rgba(0, 0, 0, 0.6)', padding: '0 1rem' }}
      role="dialog"
      aria-modal="true"
      aria-labelledby="modal-title"
      aria-describedby={description ? 'modal-description' : undefined}
      onKeyDown={handleKeyDown}
      onClick={handleBackdropClick}
    >
      <Box
        ref={dialogRef}
        style={{ width: '100%', maxWidth: '28rem', borderRadius: '1rem', backgroundColor: '#0f1115', border: '1px solid #262626', boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.5)', outline: 'none' }}
        tabIndex={-1}
      >
        <Box p={6} style={{ borderBottom: '1px solid rgba(38, 38, 38, 0.8)' }}>
          <Heading level={2} id="modal-title">{title}</Heading>
          {description && (
            <Text
              id="modal-description"
              size="sm"
              color="text-gray-400"
              block
              mt={2}
            >
              {description}
            </Text>
          )}
        </Box>

        <Box p={6}>
          <Text size="sm" color="text-gray-100">{children}</Text>
        </Box>

        {(primaryActionLabel || secondaryActionLabel) && (
          <Box p={6} style={{ borderTop: '1px solid rgba(38, 38, 38, 0.8)', display: 'flex', justifyContent: 'flex-end', gap: '0.75rem' }}>
            {secondaryActionLabel && (
              <Button
                type="button"
                onClick={() => {
                  onSecondaryAction?.();
                  onOpenChange?.(false);
                }}
                variant="secondary"
                size="sm"
              >
                {secondaryActionLabel}
              </Button>
            )}
            {primaryActionLabel && (
              <Button
                type="button"
                onClick={async () => {
                  if (onPrimaryAction) {
                    await onPrimaryAction();
                  }
                }}
                variant="primary"
                size="sm"
              >
                {primaryActionLabel}
              </Button>
            )}
          </Box>
        )}
      </Box>
    </Box>
  );
}

function getFocusableElements(root: HTMLElement | null): HTMLElement[] {
  if (!root) return [];
  const selectors = [
    'a[href]',
    'button:not([disabled])',
    'textarea:not([disabled])',
    'input:not([disabled])',
    'select:not([disabled])',
    '[tabindex]:not([tabindex="-1"])',
  ];
  const nodes = Array.from(
    root.querySelectorAll<HTMLElement>(selectors.join(',')),
  );
  return nodes.filter((el) => !el.hasAttribute('disabled') && !el.getAttribute('aria-hidden'));
}

function getFirstFocusable(root: HTMLElement | null): HTMLElement | null {
  const elements = getFocusableElements(root);
  return elements[0] ?? null;
}
