"use client";

import cx from "classnames";
import React from "react";
import { useHydrationSafeId, useStatic } from "../../utils/hooks";
import TooltipStatic from "./Tooltip.static";

const CLASS_ROOT = "tooltip";

export type TooltipPlacement =
  | "auto"
  | "top"
  | "top-start"
  | "top-end"
  | "bottom"
  | "bottom-start"
  | "bottom-end"
  | "right"
  | "right-start"
  | "right-end"
  | "left"
  | "left-start"
  | "left-end";

export interface TooltipProps extends React.HTMLAttributes<HTMLElement> {
  /** Tooltip dialog content */
  dialog?: React.ReactNode;
  /** Tooltip ID */
  id?: string;
  /** Preferred placement, if there is enough room. Defaults to top. */
  placement?: TooltipPlacement;
  /** Custom trigger renderer. Passes required aria attributes and children in an object as argument. */
  renderTrigger?: (props: {
    "data-tooltip-trigger": true;
    "aria-describedby": string;
    "aria-owns": string;
    children: React.ReactNode;
  }) => React.ReactNode;
  /** Render dialog as */
  tag?: "span"; // restrict tag to "span" for ref compatibility
  /** Additional CSS classes */
  className?: string;
  children?: React.ReactNode;
}

const Tooltip: React.FC<TooltipProps> = ({
  dialog,
  id,
  placement,
  tag = "span", // default and only allowed tag is "span"
  className,
  renderTrigger,
  children,
  ...other
}) => {
  const currentId = useHydrationSafeId(id);
  const classes = cx(CLASS_ROOT, className);
  const Tag = tag;

  const [dialogRef] = useStatic(TooltipStatic as any, {
    removeDialogOnDestroy: true,
  });

  const triggerProps = {
    "data-tooltip-trigger": true,
    "aria-describedby": currentId,
    "aria-owns": currentId,
    children,
  } as const;

  return (
    <>
      {renderTrigger ? (
        renderTrigger(triggerProps)
      ) : (
        <button type="button" {...triggerProps}>
          {children}
        </button>
      )}
      <Tag
        id={currentId}
        className={classes}
        role="tooltip"
        hidden
        ref={dialogRef}
        data-tooltip
        data-tooltip-placement={placement}
        {...other}
      >
        <Tag className="tooltip__arrow" />
        <Tag className="tooltip__dialog">{dialog}</Tag>
      </Tag>
    </>
  );
};

Tooltip.displayName = "Tooltip";

export { Tooltip };
