import { useCallback, useRef, useState, type ReactNode } from "react";

const STORAGE_KEY = "typst-leaf.split";
const MIN_PCT = 25;
const DEFAULT_PCT = 55;

function loadRatio(): number {
  try {
    const v = Number(localStorage.getItem(STORAGE_KEY));
    return v >= MIN_PCT && v <= 100 - MIN_PCT ? v : DEFAULT_PCT;
  } catch {
    return DEFAULT_PCT;
  }
}

function persistRatio(v: number) {
  try {
    localStorage.setItem(STORAGE_KEY, String(v));
  } catch { /* ignore */ }
}

function clampPct(v: number): number {
  return Math.max(MIN_PCT, Math.min(100 - MIN_PCT, v));
}

export function ResizableSplit({
  left,
  right,
  onResize,
}: {
  left: ReactNode;
  right: ReactNode;
  onResize?: () => void;
}) {
  const [leftPct, setLeftPct] = useState(loadRatio);
  const leftPctRef = useRef(leftPct);
  const containerRef = useRef<HTMLDivElement | null>(null);

  const startDrag = useCallback((e: React.PointerEvent) => {
    e.preventDefault();
    const el = e.currentTarget as HTMLElement;
    el.setPointerCapture(e.pointerId);
    const onMove = (ev: PointerEvent) => {
      if (!containerRef.current) return;
      const rect = containerRef.current.getBoundingClientRect();
      const pct = clampPct(((ev.clientX - rect.left) / rect.width) * 100);
      leftPctRef.current = pct;
      setLeftPct(pct);
      onResize?.();
    };
    const onUp = () => {
      persistRatio(leftPctRef.current);
      onResize?.();
      window.removeEventListener("pointermove", onMove);
      window.removeEventListener("pointerup", onUp);
    };
    window.addEventListener("pointermove", onMove);
    window.addEventListener("pointerup", onUp);
  }, [onResize]);

  return (
    <div ref={containerRef} className="flex h-full min-h-0 w-full flex-1">
      <div className="min-w-[280px] overflow-hidden" style={{ width: `${leftPct}%` }}>
        {left}
      </div>
      <div
        role="separator"
        aria-orientation="vertical"
        className="w-1 bg-zinc-200 hover:bg-emerald-300 cursor-col-resize shrink-0 transition-colors duration-75"
        onPointerDown={startDrag}
        onDoubleClick={() => {
          const pct = DEFAULT_PCT;
          leftPctRef.current = pct;
          setLeftPct(pct);
          persistRatio(pct);
        }}
      />
      <div className="flex-1 min-w-[280px] overflow-hidden">
        {right}
      </div>
    </div>
  );
}
