import { useEffect, useId, useRef, type CSSProperties, type ReactNode } from "react";
import { createPortal } from "react-dom";
import { translateReactNode, usePlatformLanguage } from "../i18n/LanguageContext";
import { shouldCloseDialogOnBackdrop } from "./dialogInteractions";
import {
  dialogIsTopmost,
  nextDialogActivationOrder,
  registerDialog,
  type DialogStackId
} from "./dialogStack";

export type DialogProps = {
  open: boolean;
  title: ReactNode;
  children: ReactNode;
  footer?: ReactNode;
  role?: "dialog" | "alertdialog";
  ariaDescribedBy?: string;
  closeLabel?: string;
  closeOnBackdrop?: boolean;
  showCloseButton?: boolean;
  closeDisabled?: boolean;
  onClose?: () => void;
  className?: string;
  backdropClassName?: string;
  headerClassName?: string;
  titleClassName?: string;
  bodyClassName?: string;
  footerClassName?: string;
  portal?: boolean;
  panelStyle?: CSSProperties;
  backdropStyle?: CSSProperties;
};

function joinClasses(...classes: Array<string | undefined | false>) {
  return classes.filter(Boolean).join(" ");
}

export default function Dialog({
  open,
  title,
  children,
  footer,
  role = "dialog",
  ariaDescribedBy,
  closeLabel = "i18n:govoplan-core.close.bbfa773e",
  closeOnBackdrop = true,
  showCloseButton = true,
  closeDisabled = false,
  onClose,
  className = "",
  backdropClassName = "",
  headerClassName = "",
  titleClassName = "",
  bodyClassName = "",
  footerClassName = "",
  portal = false,
  panelStyle,
  backdropStyle
}: DialogProps) {
  const titleId = useId();
  const canClose = Boolean(onClose) && !closeDisabled;
  const panelRef = useRef<HTMLElement | null>(null);
  const stackIdRef = useRef<DialogStackId>(Symbol("govoplan-dialog"));
  const activationOrderRef = useRef<number | null>(null);
  const canCloseRef = useRef(canClose);
  const onCloseRef = useRef(onClose);
  const restoreFocusRef = useRef<HTMLElement | null>(
    typeof document !== "undefined" && typeof HTMLElement !== "undefined" && document.activeElement instanceof HTMLElement
      ? document.activeElement
      : null
  );
  canCloseRef.current = canClose;
  onCloseRef.current = onClose;
  if (!open) activationOrderRef.current = null;
  else if (activationOrderRef.current === null) activationOrderRef.current = nextDialogActivationOrder();
  const { translateText } = usePlatformLanguage();
  const renderedTitle = translateReactNode(title, translateText);
  const renderedChildren = translateReactNode(children, translateText);
  const renderedFooter = translateReactNode(footer, translateText);
  const translatedCloseLabel = translateText(closeLabel);

  useEffect(() => {
    if (open || typeof document === "undefined") return undefined;

    const rememberFocusedElement = () => {
      const activeElement = document.activeElement;
      if (!(activeElement instanceof HTMLElement)) return;
      if (panelRef.current?.contains(activeElement)) return;
      restoreFocusRef.current = activeElement;
    };

    rememberFocusedElement();
    document.addEventListener("focusin", rememberFocusedElement);
    return () => document.removeEventListener("focusin", rememberFocusedElement);
  }, [open]);

  useEffect(() => {
    if (!open || typeof document === "undefined") return undefined;

    const panel = panelRef.current;
    const activationOrder = activationOrderRef.current;
    if (!panel || activationOrder === null) return undefined;

    return registerDialog({
      id: stackIdRef.current,
      activationOrder,
      panel,
      restoreFocus: restoreFocusRef.current,
      canClose: () => canCloseRef.current,
      onClose: () => onCloseRef.current?.()
    }, document.activeElement);
  }, [open]);

  if (!open) return null;

  const dialog = (
    <div
      className={joinClasses("dialog-backdrop", backdropClassName)}
      style={backdropStyle}
      role="presentation"
      onMouseDown={(event) => {
        if (
          dialogIsTopmost(stackIdRef.current)
          && shouldCloseDialogOnBackdrop(event.target, event.currentTarget, closeOnBackdrop, canClose)
        ) onClose?.();
      }}
    >
      <section
        ref={panelRef}
        tabIndex={-1}
        className={joinClasses("dialog-panel", className)}
        style={panelStyle}
        role={role}
        aria-modal="true"
        data-dialog-stack-state="topmost"
        aria-labelledby={titleId}
        aria-describedby={ariaDescribedBy}
      >
        <div className={joinClasses("dialog-header", headerClassName)}>
          <h2 id={titleId} className={joinClasses("dialog-title", titleClassName)}>{renderedTitle}</h2>
          {showCloseButton && onClose && (
            <button
              type="button"
              className="dialog-close"
              onClick={onClose}
              aria-label={translatedCloseLabel}
              disabled={closeDisabled}
            >
              ×
            </button>
          )}
        </div>
        <div className={joinClasses("dialog-body", bodyClassName)}>{renderedChildren}</div>
        {footer && <div className={joinClasses("dialog-footer", footerClassName)}>{renderedFooter}</div>}
      </section>
    </div>
  );

  return portal && typeof document !== "undefined"
    ? createPortal(dialog, document.body)
    : dialog;
}
