// packages/core/src/components/dialog/dialog-content.tsx
import type { JSX } from "solid-js";
import { Show, createEffect, onCleanup, splitProps } from "solid-js";
import { createDismiss } from "../../utilities/dismiss/create-dismiss";
import { createFocusTrap } from "../../utilities/focus-trap/create-focus-trap";
import { createScrollLock } from "../../utilities/scroll-lock/create-scroll-lock";
import { useInternalDialogContext } from "./dialog-context";
import type { DialogContentProps } from "./dialog.props";

export type { DialogContentProps };

/**
 * Dialog content panel. Manages focus trap, scroll lock, and dismiss.
 * Renders inline; wrap with Dialog.Portal to control portaling.
 * Only renders when open (unless forceMount is set).
 */
export function DialogContent(props: DialogContentProps): JSX.Element {
  const [local, rest] = splitProps(props, [
    "children",
    "onOpenAutoFocus",
    "onCloseAutoFocus",
    "forceMount",
  ]);
  const ctx = useInternalDialogContext();
  let contentRef: HTMLDialogElement | undefined;

  const focusTrap = createFocusTrap(() => contentRef ?? null);
  const scrollLock = createScrollLock();
  const dismiss = createDismiss({
    getContainer: () => contentRef ?? null,
    onDismiss: () => ctx.setOpen(false),
  });

  createEffect(() => {
    if (ctx.isOpen() && ctx.modal()) {
      focusTrap.activate();
      scrollLock.lock();
      dismiss.attach();
    } else {
      focusTrap.deactivate();
      scrollLock.unlock();
      dismiss.detach();
    }
    onCleanup(() => {
      focusTrap.deactivate();
      scrollLock.unlock();
      dismiss.detach();
    });
  });

  return (
    <Show when={local.forceMount || ctx.isOpen()}>
      <dialog
        ref={contentRef}
        id={ctx.contentId()}
        open
        aria-modal={ctx.modal() || undefined}
        aria-labelledby={ctx.titleId() || undefined}
        aria-describedby={ctx.descriptionId() || undefined}
        data-state={ctx.isOpen() ? "open" : "closed"}
        {...rest}
      >
        {local.children}
      </dialog>
    </Show>
  );
}
