/* global React */
const { useState, useEffect, useRef: useRefP } = React;

/* ---------- Panel with click-origin circular reveal ---------- */
function Panel({ open, origin, onClose, theme, children, label }) {
  const ref = useRefP(null);
  const [phase, setPhase] = useState("closed"); // closed | opening | open | closing

  useEffect(() => {
    if (open && (phase === "closed" || phase === "closing")) {
      // re-opening mid-close is fine — interrupt and open immediately
      setPhase("opening");
      requestAnimationFrame(() => {
        requestAnimationFrame(() => setPhase("open"));
      });
    } else if (!open && (phase === "open" || phase === "opening")) {
      setPhase("closing");
      const t = setTimeout(() => setPhase("closed"), 900);
      return () => clearTimeout(t);
    }
  }, [open, phase]);

  // body scroll lock
  useEffect(() => {
    if (phase === "open" || phase === "opening") document.body.classList.add("no-scroll");
    else document.body.classList.remove("no-scroll");
  }, [phase]);

  // ESC to close
  useEffect(() => {
    if (phase !== "open") return;
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [phase, onClose]);

  if (phase === "closed") return null;

  const ox = origin?.x ?? window.innerWidth / 2;
  const oy = origin?.y ?? window.innerHeight / 2;
  // radius needs to cover farthest corner
  const dx = Math.max(ox, window.innerWidth - ox);
  const dy = Math.max(oy, window.innerHeight - oy);
  const maxR = Math.ceil(Math.hypot(dx, dy)) + 50;

  const small = `circle(0px at ${ox}px ${oy}px)`;
  const big = `circle(${maxR}px at ${ox}px ${oy}px)`;

  let clip = small;
  if (phase === "opening") clip = small;
  if (phase === "open") clip = big;
  if (phase === "closing") clip = small;

  const transitionDur = phase === "closing" ? "780ms" : "900ms";
  const easing = "cubic-bezier(0.86, 0, 0.07, 1)";

  return (
    <div
      ref={ref}
      className={"panel-overlay" + (phase === "open" ? " is-open" : "") + (theme ? " " + theme : "")}
      style={{
        clipPath: clip,
        WebkitClipPath: clip,
        transition: `clip-path ${transitionDur} ${easing}, -webkit-clip-path ${transitionDur} ${easing}`,
      }}
      role="dialog"
      aria-modal="true"
      aria-label={label}
    >
      <div className="panel-inner">
        <div className="topbar">
          <div className="left mono">{label}</div>
          <div className="center mono">— {String(label || "").toUpperCase()} —</div>
          <div className="right">
            <button className="close-btn" onClick={onClose} data-cursor="hover" aria-label="Close panel">
              <span>CLOSE</span>
              <span className="x">×</span>
            </button>
          </div>
        </div>
        {children}
      </div>
    </div>
  );
}

window.Panel = Panel;
