import { type JSX, onCleanup, onMount } from "solid-js";
import { OverlayPortal } from "../../App/OverlayHost";
import texts from "../../i18n";
import { Icon } from "./Icon";

const DIALOG_WIDTHS = {
  md: "max-w-[calc(var(--ui-control-size-xl)*7.5)]",
  lg: "max-w-[calc(var(--ui-control-size-xl)*9.25)]",
} as const;

export function Dialog(props: {
  bodyClass?: string;
  children: JSX.Element;
  label: string;
  lockPageScroll?: boolean;
  onClose: () => void;
  title: JSX.Element;
  variant: "reader" | "site";
  width: keyof typeof DIALOG_WIDTHS;
}) {
  onMount(() => {
    const scrollRoots = [document.documentElement, document.body];
    const overflowStyles = props.lockPageScroll
      ? scrollRoots.map((root) => ({
          priority: root.style.getPropertyPriority("overflow"),
          value: root.style.getPropertyValue("overflow"),
        }))
      : [];
    const closeOnEscape = (event: KeyboardEvent) => {
      if (event.key !== "Escape") {
        return;
      }
      event.preventDefault();
      event.stopImmediatePropagation();
      props.onClose();
    };
    if (props.lockPageScroll) {
      for (const root of scrollRoots) {
        root.style.setProperty("overflow", "hidden", "important");
      }
    }
    window.addEventListener("keydown", closeOnEscape, true);
    onCleanup(() => {
      window.removeEventListener("keydown", closeOnEscape, true);
      if (props.lockPageScroll) {
        scrollRoots.forEach((root, index) => {
          const previous = overflowStyles[index];
          if (previous?.value) {
            root.style.setProperty("overflow", previous.value, previous.priority);
          } else {
            root.style.removeProperty("overflow");
          }
        });
      }
    });
  });

  const reader = () => props.variant === "reader";

  return (
    <OverlayPortal>
      <div
        class="fixed inset-0 z-dialog box-border flex items-center justify-center overflow-hidden ui-p-lg bg-black/65 pointer-events-auto font-sans"
        role="dialog"
        aria-modal="true"
        aria-label={props.label}
        onClick={(event: MouseEvent) => {
          event.stopPropagation();
          if (event.target === event.currentTarget) {
            props.onClose();
          }
        }}
        onPointerDown={(event: PointerEvent) => event.stopPropagation()}
        onWheel={(event: WheelEvent) => event.stopPropagation()}
      >
        <div
          class={`box-border flex w-full ${DIALOG_WIDTHS[props.width]} max-h-[min(calc(var(--ui-control-size-xl)*12.75),calc(100dvh_-_var(--ui-space-lg)_-_var(--ui-space-lg)))] flex-col overflow-hidden ui-rounded-lg border shadow-xl ${
            reader()
              ? "border-[var(--color-border)] bg-[var(--color-background)] text-[var(--color-text)]"
              : "ehp-color-site-border ehp-color-site-elevated ehp-color-site-text"
          }`}
        >
          <div class={`flex box-border min-h-[var(--ui-control-size-lg)] flex-none items-center justify-between ui-gap-md ui-py-sm ui-pl-lg ui-pr-sm border-0 border-b ${
            reader()
              ? "border-[var(--color-border)]"
              : "ehp-color-site-border-subtle-b"
          }`}>
            <h2 class="m-0 textsize-lg font-700">{props.title}</h2>
            <button
              type="button"
              class={`inline-flex w-[var(--ui-control-size-md)] h-[var(--ui-control-size-md)] flex-none items-center justify-center p-0 ui-rounded-md border-0 bg-transparent cursor-pointer ${
                reader()
                  ? "text-[var(--color-text)] hover:bg-[var(--color-badge)]"
                  : "ehp-color-site-text hover:bg-[var(--color-site-item-hover)]"
              }`}
              aria-label={texts.common.actions.close}
              title={texts.common.actions.close}
              onClick={() => props.onClose()}
            >
              <Icon name="close" size="var(--ui-icon-size-md)" />
            </button>
          </div>
          <div class={`min-h-0 overflow-y-auto overscroll-contain ui-pb-lg [&>:last-child]:!border-b-0 ${props.bodyClass ?? ""}`}>
            {props.children}
          </div>
        </div>
      </div>
    </OverlayPortal>
  );
}
