"use client";

import { Fragment, ReactNode, useEffect, useCallback, useRef } from "react";
import { Dialog, Transition } from "@headlessui/react";
import { X } from "lucide-react";

export type ModalSize = "sm" | "md" | "lg" | "xl" | "2xl" | "full";

interface BaseModalProps {
  isOpen: boolean;
  onClose: () => void;
  title: string;
  subtitle?: string;
  size?: ModalSize;
  children: ReactNode;
  footer?: ReactNode;
  showCloseButton?: boolean;
  closeOnOverlayClick?: boolean;
  closeOnEscape?: boolean;
  dir?: "ltr" | "rtl";
  headerClassName?: string;
  contentClassName?: string;
  footerClassName?: string;
  titleIcon?: ReactNode;
  loading?: boolean;
}

const sizeClasses: Record<ModalSize, string> = {
  sm: "max-w-sm",
  md: "max-w-lg",
  lg: "max-w-2xl",
  xl: "max-w-4xl",
  "2xl": "max-w-6xl",
  full: "max-w-[95vw]",
};

/**
 * BaseModal - A reusable modal component with consistent styling and behavior
 *
 * Features:
 * - Accessible (uses Headless UI Dialog)
 * - Focus trap (built into Dialog)
 * - Escape key handling (built into Dialog, can be disabled)
 * - Overlay click handling (configurable)
 * - Smooth enter/exit transitions
 * - RTL/LTR support
 * - Multiple size options
 * - Customizable header, content, and footer sections
 *
 * @example
 * ```tsx
 * <BaseModal
 *   isOpen={isOpen}
 *   onClose={handleClose}
 *   title="Edit Profile"
 *   subtitle="Update your information"
 *   size="lg"
 *   footer={<div className="flex gap-3">...</div>}
 * >
 *   {children}
 * </BaseModal>
 * ```
 */
export function BaseModal({
  isOpen,
  onClose,
  title,
  subtitle,
  size = "md",
  children,
  footer,
  showCloseButton = true,
  closeOnOverlayClick = true,
  closeOnEscape = true,
  dir = "ltr",
  headerClassName = "",
  contentClassName = "",
  footerClassName = "",
  titleIcon,
  loading = false,
}: BaseModalProps) {
  const initialFocusRef = useRef<HTMLButtonElement>(null);

  // Handle escape key when closeOnEscape is false
  const handleKeyDown = useCallback(
    (event: KeyboardEvent) => {
      if (!closeOnEscape && event.key === "Escape") {
        event.preventDefault();
        event.stopPropagation();
      }
    },
    [closeOnEscape],
  );

  useEffect(() => {
    if (!closeOnEscape && isOpen) {
      document.addEventListener("keydown", handleKeyDown, true);
      return () => {
        document.removeEventListener("keydown", handleKeyDown, true);
      };
    }
  }, [closeOnEscape, isOpen, handleKeyDown]);

  // Handle overlay click
  const handleClose = () => {
    if (!loading) {
      onClose();
    }
  };

  // Prevent close on overlay click if disabled or loading
  const handleDialogClose =
    closeOnOverlayClick && !loading ? handleClose : () => {};

  return (
    <Transition appear show={isOpen} as={Fragment}>
      <Dialog
        as="div"
        className="relative z-50"
        onClose={handleDialogClose}
        initialFocus={initialFocusRef}
      >
        {/* Backdrop */}
        <Transition.Child
          as={Fragment}
          enter="ease-out duration-300"
          enterFrom="opacity-0"
          enterTo="opacity-100"
          leave="ease-in duration-200"
          leaveFrom="opacity-100"
          leaveTo="opacity-0"
        >
          <div className="fixed inset-0 bg-black/50 backdrop-blur-sm" />
        </Transition.Child>

        {/* Modal Container */}
        <div className="fixed inset-0 overflow-y-auto">
          <div className="flex min-h-full items-center justify-center p-4">
            <Transition.Child
              as={Fragment}
              enter="ease-out duration-300"
              enterFrom="opacity-0 scale-95"
              enterTo="opacity-100 scale-100"
              leave="ease-in duration-200"
              leaveFrom="opacity-100 scale-100"
              leaveTo="opacity-0 scale-95"
            >
              <Dialog.Panel
                className={`w-full ${sizeClasses[size]} transform overflow-hidden rounded-2xl bg-white shadow-2xl transition-all`}
                dir={dir}
              >
                {/* Header */}
                <div
                  className={`flex items-center justify-between border-b border-slate-100 px-6 py-4 ${headerClassName}`}
                >
                  <div className="flex items-center gap-3">
                    {titleIcon && (
                      <div className="flex-shrink-0">{titleIcon}</div>
                    )}
                    <div>
                      <Dialog.Title className="text-lg font-semibold text-slate-900">
                        {title}
                      </Dialog.Title>
                      {subtitle && (
                        <p className="text-sm text-slate-500 mt-0.5">
                          {subtitle}
                        </p>
                      )}
                    </div>
                  </div>
                  {showCloseButton && (
                    <button
                      ref={initialFocusRef}
                      onClick={handleClose}
                      disabled={loading}
                      className="rounded-lg p-2 text-slate-400 hover:text-slate-600 hover:bg-slate-100 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
                      aria-label="Close modal"
                    >
                      <X className="h-5 w-5" />
                    </button>
                  )}
                </div>

                {/* Content */}
                <div className={`px-6 py-4 ${contentClassName}`}>
                  {children}
                </div>

                {/* Footer */}
                {footer && (
                  <div
                    className={`border-t border-slate-100 px-6 py-4 ${footerClassName}`}
                  >
                    {footer}
                  </div>
                )}
              </Dialog.Panel>
            </Transition.Child>
          </div>
        </div>
      </Dialog>
    </Transition>
  );
}

/**
 * ModalFooter - A convenience component for common footer layouts
 */
interface ModalFooterProps {
  children: ReactNode;
  align?: "start" | "end" | "center" | "between";
}

const alignClasses: Record<string, string> = {
  start: "justify-start",
  end: "justify-end",
  center: "justify-center",
  between: "justify-between",
};

export function ModalFooter({ children, align = "end" }: ModalFooterProps) {
  return (
    <div className={`flex items-center gap-3 ${alignClasses[align]}`}>
      {children}
    </div>
  );
}

/**
 * ModalButton - Styled buttons for modal actions
 */
interface ModalButtonProps {
  children: ReactNode;
  onClick?: () => void;
  variant?: "primary" | "secondary" | "danger";
  disabled?: boolean;
  loading?: boolean;
  type?: "button" | "submit";
  icon?: ReactNode;
}

export function ModalButton({
  children,
  onClick,
  variant = "secondary",
  disabled = false,
  loading = false,
  type = "button",
  icon,
}: ModalButtonProps) {
  const variantClasses = {
    primary:
      "bg-brand-green text-white hover:bg-brand-greenHover disabled:bg-brand-green/50",
    secondary:
      "border border-slate-200 text-slate-700 hover:bg-slate-50 disabled:bg-slate-50",
    danger: "bg-red-600 text-white hover:bg-red-700 disabled:bg-red-400",
  };

  return (
    <button
      type={type}
      onClick={onClick}
      disabled={disabled || loading}
      className={`inline-flex items-center justify-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors disabled:opacity-50 disabled:cursor-not-allowed ${variantClasses[variant]}`}
    >
      {loading ? (
        <svg
          className="h-4 w-4 animate-spin"
          xmlns="http://www.w3.org/2000/svg"
          fill="none"
          viewBox="0 0 24 24"
        >
          <circle
            className="opacity-25"
            cx="12"
            cy="12"
            r="10"
            stroke="currentColor"
            strokeWidth="4"
          />
          <path
            className="opacity-75"
            fill="currentColor"
            d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
          />
        </svg>
      ) : icon ? (
        icon
      ) : null}
      {children}
    </button>
  );
}

export default BaseModal;
