import React, { forwardRef, useEffect, useRef, HTMLAttributes } from 'react';
import { clsx } from 'clsx';

export interface ModalProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onClose'> {
  isOpen: boolean;
  onClose: () => void;
  size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full';
  variant?: 'default' | 'centered' | 'drawer-left' | 'drawer-right' | 'drawer-top' | 'drawer-bottom';
  closeOnOverlayClick?: boolean;
  closeOnEscape?: boolean;
  showCloseButton?: boolean;
  preventScroll?: boolean;
  initialFocus?: React.RefObject<HTMLElement>;
  finalFocus?: React.RefObject<HTMLElement>;
  overlayClassName?: string;
  contentClassName?: string;
  portalId?: string;
}

export interface ModalHeaderProps extends HTMLAttributes<HTMLDivElement> {
  title?: string | React.ReactNode;
  subtitle?: string;
  showCloseButton?: boolean;
  onClose?: () => void;
}

export interface ModalBodyProps extends HTMLAttributes<HTMLDivElement> {
  padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
}

export interface ModalFooterProps extends HTMLAttributes<HTMLDivElement> {
  justify?: 'start' | 'end' | 'center' | 'between' | 'around' | 'evenly';
  padding?: 'none' | 'sm' | 'md' | 'lg' | 'xl';
}

const Modal = forwardRef<HTMLDivElement, ModalProps>(({
  isOpen,
  onClose,
  size = 'md',
  variant = 'default',
  closeOnOverlayClick = true,
  closeOnEscape = true,
  showCloseButton = true,
  preventScroll = true,
  initialFocus,
  finalFocus,
  overlayClassName,
  contentClassName,
  className,
  children,
  ...props
}, ref) => {
  const overlayRef = useRef<HTMLDivElement>(null);
  const contentRef = useRef<HTMLDivElement>(null);
  const previousFocusRef = useRef<HTMLElement | null>(null);

  // Handle escape key
  useEffect(() => {
    if (!isOpen || !closeOnEscape) return;

    const handleEscape = (event: KeyboardEvent) => {
      if (event.key === 'Escape') {
        onClose();
      }
    };

    document.addEventListener('keydown', handleEscape);
    return () => document.removeEventListener('keydown', handleEscape);
  }, [isOpen, closeOnEscape, onClose]);

  // Handle body scroll lock
  useEffect(() => {
    if (!isOpen || !preventScroll) return;

    const originalStyle = window.getComputedStyle(document.body).overflow;
    document.body.style.overflow = 'hidden';

    return () => {
      document.body.style.overflow = originalStyle;
    };
  }, [isOpen, preventScroll]);

  // Handle focus management
  useEffect(() => {
    if (!isOpen) return;

    // Store the currently focused element
    previousFocusRef.current = document.activeElement as HTMLElement;

    // Set focus to initial focus element or modal content
    const timer = setTimeout(() => {
      const focusTarget = initialFocus?.current || contentRef.current;
      if (focusTarget) {
        focusTarget.focus();
      }
    }, 100);

    return () => {
      clearTimeout(timer);
      // Return focus to previously focused element
      if (finalFocus?.current) {
        finalFocus.current.focus();
      } else if (previousFocusRef.current) {
        previousFocusRef.current.focus();
      }
    };
  }, [isOpen, initialFocus, finalFocus]);

  // Handle overlay click
  const handleOverlayClick = (event: React.MouseEvent<HTMLDivElement>) => {
    if (closeOnOverlayClick && event.target === event.currentTarget) {
      onClose();
    }
  };

  if (!isOpen) return null;

  const sizeClasses = {
    xs: 'max-w-xs w-full',
    sm: 'max-w-sm w-full',
    md: 'max-w-md w-full',
    lg: 'max-w-lg w-full max-h-[90vh] overflow-y-auto',
    xl: 'max-w-xl w-full max-h-[90vh] overflow-y-auto',
    '2xl': 'max-w-2xl w-full max-h-[90vh] overflow-y-auto',
    full: 'max-w-full w-full max-h-[90vh] overflow-y-auto',
  };

  const variantClasses = {
    default: {
      overlay: 'fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex items-center justify-center p-4',
      content: 'w-full transform transition-all duration-300 ease-out scale-100 opacity-100',
    },
    centered: {
      overlay: 'fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex items-center justify-center p-4',
      content: 'w-full transform transition-all duration-300 ease-out scale-100 opacity-100',
    },
    'drawer-left': {
      overlay: 'fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex justify-start',
      content: 'h-full w-full max-w-md transform transition-all duration-300 ease-out translate-x-0',
    },
    'drawer-right': {
      overlay: 'fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex justify-end',
      content: 'h-full w-full max-w-md transform transition-all duration-300 ease-out translate-x-0',
    },
    'drawer-top': {
      overlay: 'fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex flex-col justify-start',
      content: 'w-full transform transition-all duration-300 ease-out translate-y-0',
    },
    'drawer-bottom': {
      overlay: 'fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex flex-col justify-end',
      content: 'w-full transform transition-all duration-300 ease-out translate-y-0',
    },
  };

  const overlayClasses = clsx(
    variantClasses[variant].overlay,
    'animate-in fade-in duration-200',
    overlayClassName
  );

  const contentClasses = clsx(
    'relative bg-[var(--bg-primary)] border border-[var(--border-primary)] rounded-lg shadow-xl',
    'animate-in zoom-in-95 duration-200',
    variantClasses[variant].content,
    sizeClasses[size],
    {
      'rounded-none': variant.includes('drawer'),
      'rounded-t-lg rounded-b-none': variant === 'drawer-bottom',
      'rounded-b-lg rounded-t-none': variant === 'drawer-top',
      'rounded-r-lg rounded-l-none': variant === 'drawer-left',
      'rounded-l-lg rounded-r-none': variant === 'drawer-right',
    },
    contentClassName,
    className
  );

  return (
    <div
      ref={overlayRef}
      className={overlayClasses}
      onClick={handleOverlayClick}
      role="dialog"
      aria-modal="true"
      aria-labelledby="modal-title"
      aria-describedby="modal-description"
    >
      <div
        ref={ref || contentRef}
        className={contentClasses}
        {...props}
      >
        {showCloseButton && (
          <button
            type="button"
            className="absolute top-4 right-4 text-[var(--text-tertiary)] hover:text-[var(--text-primary)] transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]/20 rounded-md p-1"
            onClick={onClose}
            aria-label="Cerrar modal"
          >
            <svg
              className="w-5 h-5"
              fill="none"
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth={2}
              viewBox="0 0 24 24"
              stroke="currentColor"
            >
              <path d="M6 18L18 6M6 6l12 12" />
            </svg>
          </button>
        )}
        {children}
      </div>
    </div>
  );
});

const ModalHeader = forwardRef<HTMLDivElement, ModalHeaderProps>(({
  title,
  subtitle,
  showCloseButton = false,
  onClose,
  className,
  children,
  ...props
}, ref) => {
  const classes = clsx(
    'px-6 py-4 border-b border-[var(--border-primary)]',
    className
  );

  return (
    <div
      ref={ref}
      className={classes}
      {...props}
    >
      <div className="flex items-start justify-between">
        <div className="flex-1">
          {title && (
            typeof title === 'string' ? (
              <h2
                id="modal-title"
                className="text-lg font-semibold text-[var(--text-primary)]"
              >
                {title}
              </h2>
            ) : (
              <div id="modal-title">
                {title}
              </div>
            )
          )}
          {subtitle && (
            <p className="mt-1 text-sm text-[var(--text-secondary)]">
              {subtitle}
            </p>
          )}
          {children}
        </div>
        {showCloseButton && onClose && (
          <button
            type="button"
            className="ml-4 text-[var(--text-tertiary)] hover:text-[var(--text-primary)] transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]/20 rounded-md p-1"
            onClick={onClose}
            aria-label="Cerrar modal"
          >
            <svg
              className="w-5 h-5"
              fill="none"
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth={2}
              viewBox="0 0 24 24"
              stroke="currentColor"
            >
              <path d="M6 18L18 6M6 6l12 12" />
            </svg>
          </button>
        )}
      </div>
    </div>
  );
});

const ModalBody = forwardRef<HTMLDivElement, ModalBodyProps>(({
  padding = 'md',
  className,
  children,
  ...props
}, ref) => {
  const paddingClasses = {
    none: '',
    sm: 'p-3',
    md: 'p-6',
    lg: 'p-8',
    xl: 'p-10',
  };

  const classes = clsx(
    paddingClasses[padding],
    className
  );

  return (
    <div
      ref={ref}
      id="modal-description"
      className={classes}
      {...props}
    >
      {children}
    </div>
  );
});

const ModalFooter = forwardRef<HTMLDivElement, ModalFooterProps>(({
  justify = 'end',
  padding = 'md',
  className,
  children,
  ...props
}, ref) => {
  const paddingClasses = {
    none: '',
    sm: 'p-3',
    md: 'px-6 py-4',
    lg: 'px-8 py-5',
    xl: 'px-10 py-6',
  };

  const justifyClasses = {
    start: 'justify-start',
    end: 'justify-end',
    center: 'justify-center',
    between: 'justify-between',
    around: 'justify-around',
    evenly: 'justify-evenly',
  };

  const classes = clsx(
    'flex items-center gap-3 border-t border-[var(--border-primary)]',
    paddingClasses[padding],
    justifyClasses[justify],
    className
  );

  return (
    <div
      ref={ref}
      className={classes}
      {...props}
    >
      {children}
    </div>
  );
});

Modal.displayName = 'Modal';
ModalHeader.displayName = 'ModalHeader';
ModalBody.displayName = 'ModalBody';
ModalFooter.displayName = 'ModalFooter';

export default Modal;
export { ModalHeader, ModalBody, ModalFooter };