import { useRef, useState, useSyncExternalStore } from "react";
import { createPortal } from "react-dom";
import { hintsEnabled, subscribeHints } from "../lib/hints";

type Side = "top" | "bottom";
type Coords = { left: number; top: number; placement: Side };

/** Wrap any element to show a short glass hint caption on hover — but only while the
 *  app-wide hints toggle (Settings → Appearance) is on. Rendered in a portal with
 *  fixed positioning so it is never clipped by an overflow/stacking ancestor. */
export default function Tooltip({
  hint,
  side = "top",
  children,
}: {
  hint: string;
  side?: Side;
  children: React.ReactNode;
}) {
  const enabled = useSyncExternalStore(subscribeHints, hintsEnabled, hintsEnabled);
  const ref = useRef<HTMLSpanElement>(null);
  const [coords, setCoords] = useState<Coords | null>(null);

  function show() {
    const el = ref.current;
    if (!el) return;
    const r = el.getBoundingClientRect();
    // Prefer the requested side; flip to bottom if there's no room above.
    const placement: Side = side === "bottom" || r.top < 90 ? "bottom" : "top";
    setCoords({
      left: Math.min(Math.max(r.left + r.width / 2, 92), window.innerWidth - 92),
      top: placement === "top" ? r.top - 8 : r.bottom + 8,
      placement,
    });
  }
  function hide() {
    setCoords(null);
  }

  if (!enabled || !hint) return <>{children}</>;

  return (
    <span
      ref={ref}
      onMouseEnter={show}
      onMouseLeave={hide}
      onFocus={show}
      onBlur={hide}
      className="inline-flex"
    >
      {children}
      {coords &&
        createPortal(
          <div
            role="tooltip"
            style={{
              position: "fixed",
              left: coords.left,
              top: coords.top,
              transform: `translateX(-50%) translateY(${coords.placement === "top" ? "-100%" : "0"})`,
            }}
            className="glass pointer-events-none z-[100] w-max max-w-[240px] px-2.5 py-1.5 rounded-lg text-xs leading-snug text-fg font-normal normal-case tracking-normal animate-[fadeIn_0.12s_ease]"
          >
            {hint}
          </div>,
          document.body
        )}
    </span>
  );
}
