import type { ReactElement, ReactNode } from "react";
import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";

import { cn } from "@/lib/utils";

type Side = NonNullable<TooltipPrimitive.Positioner.Props["side"]>;

function TooltipProvider({ ...props }: TooltipPrimitive.Provider.Props) {
  return <TooltipPrimitive.Provider {...props} />;
}

function TooltipRoot({ ...props }: TooltipPrimitive.Root.Props) {
  return <TooltipPrimitive.Root data-slot="tooltip" {...props} />;
}

function TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {
  return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
}

function TooltipPopup({ className, ...props }: TooltipPrimitive.Popup.Props) {
  return (
    <TooltipPrimitive.Popup
      data-slot="tooltip-popup"
      className={cn(
        "rounded border bg-popover px-2 py-1 text-sm text-popover-foreground shadow-md",
        className,
      )}
      {...props}
    />
  );
}

function TooltipPositioner({ className, ...props }: TooltipPrimitive.Positioner.Props) {
  return (
    <TooltipPrimitive.Positioner
      data-slot="tooltip-positioner"
      className={cn("z-50", className)}
      {...props}
    />
  );
}

export type TooltipProps = {
  /** Text shown in the tooltip popup. */
  content: ReactNode;
  /** The element the tooltip is attached to. Rendered as the trigger. */
  children: ReactElement;
  /** Which side of the trigger to place the popup. Defaults to `"right"`. */
  side?: Side;
  /** Pixel gap between the trigger and the popup. */
  sideOffset?: number;
};

/**
 * Standalone tooltip: wraps its own `Provider`, so it can be dropped in
 * anywhere without an ancestor provider. `children` is delegated to the
 * Base UI trigger via `render`, so the underlying element keeps its own
 * tag/handlers (e.g. a `NavLink` for the collapsed sidebar).
 */
function Tooltip({ content, children, side = "right", sideOffset = 6 }: TooltipProps) {
  return (
    <TooltipProvider>
      <TooltipRoot>
        <TooltipTrigger render={children} />
        <TooltipPrimitive.Portal>
          <TooltipPositioner side={side} sideOffset={sideOffset}>
            <TooltipPopup>{content}</TooltipPopup>
          </TooltipPositioner>
        </TooltipPrimitive.Portal>
      </TooltipRoot>
    </TooltipProvider>
  );
}

export {
  Tooltip,
  TooltipProvider,
  TooltipRoot,
  TooltipTrigger,
  TooltipPositioner,
  TooltipPopup,
};
