import clsx from "clsx";
import { FC, useEffect } from "react";

import CloseIcon from "@dndbeyond/fontawesome-cache/svgs/solid/x.svg";
import { Dialog, DialogProps } from "@dndbeyond/ttui/components/Dialog";

import { Button, ButtonProps } from "../Button";
import styles from "./styles.module.css";

/**
 * @heading Text for the title of the modal - defaults to "Confirm"
 * @onClose Function to call when the Close button is clicked
 * @onConfirm Function to call when the Confirm button is clicked
 * @confirmButtonText Provide text to the Confirm button - defaults to "Confirm"
 * @closeButtonText Provide text to the Close button - defaults to "Cancel"
 * @variant "default" | "remove" | "confirm-only"
 * --default: default modal with both Confirm and Close buttons using the "success" button color
 * --remove: modal with both Confirm and Close buttons using the "secondary" color for the header and Confirm button
 * --confirm-only: modal with only the Confirm button using the "success" button color
 * @size "default" | "fit-content"
 * --default: default modal size
 * --fit-content: modal size adjusts to the content
 * @color Passes a ButtonProps color to the confirm button
 * @useMobileFullScreen Boolean to set the modal to full screen on mobile breakpoint
 */
export interface ConfirmModalProps extends DialogProps {
  heading?: string;
  onClose: () => void;
  onConfirm: () => void;
  confirmButtonText?: string;
  closeButtonText?: string;
  variant?: "default" | "remove" | "confirm-only";
  size?: "default" | "fit-content";
  color?: ButtonProps["color"];
  useMobileFullScreen?: boolean;
}

export const ConfirmModal: FC<ConfirmModalProps> = ({
  children,
  className,
  heading = "Confirm",
  onClose,
  onConfirm,
  confirmButtonText = "Confirm",
  closeButtonText = "Cancel",
  open,
  variant = "default",
  size = "default",
  color = "success",
  useMobileFullScreen,
  ...props
}) => {
  const isConfirmOnly = variant === "confirm-only";

  useEffect(() => {
    const body = document.querySelector("body");
    if (!body) return;

    // Prevent scrolling when modal is visible
    if (open) {
      body.style.overflow = "hidden";
    } else {
      body.style.overflow = "";
    }
  }, [open]);

  return (
    <Dialog
      className={clsx([
        styles.confirmModal,
        useMobileFullScreen && styles.fullScreen,
        styles[variant],
        styles[size],
        className,
      ])}
      onClose={onClose}
      modal
      open={open}
      {...props}
    >
      <header className={styles.header}>
        <h2>{heading}</h2>
        <Button
          className={styles.closeButton}
          size="x-small"
          variant="text"
          onClick={onClose}
          aria-label={`Close ${heading} Modal`}
          forceThemeMode="light"
        >
          <CloseIcon className={styles.closeIcon} />
        </Button>
      </header>
      <div className={styles.content}>{children}</div>
      <footer className={styles.footer}>
        {!isConfirmOnly && (
          <Button className={styles.footerButton} onClick={onClose}>
            {closeButtonText}
          </Button>
        )}
        <Button
          className={clsx([
            styles.footerButton,
            isConfirmOnly && styles.confirmOnly,
          ])}
          color={variant === "remove" ? "secondary" : color}
          onClick={onConfirm}
          forceThemeMode="light"
          size={isConfirmOnly ? "x-small" : undefined}
        >
          {confirmButtonText}
        </Button>
      </footer>
    </Dialog>
  );
};
