// <SettingsMenu> — a single header icon-button + popover holding the
// client-local overrides swarm-ui currently has (theme, reduced
// motion). Mirrors `LinksMenu`'s shape (icon button, popover, close on
// outside-click/Escape) — same "quiet chrome, not another nav item"
// affordance, not a coincidence: the operator, when asked how big this
// settings surface should be, said "small thing somewhere" since there
// are only two overrides right now — a full `/settings` route + nav
// entry would be over-building for two selects. Grows into a real page
// only if the setting count outgrows a popover; nothing here assumes
// it can't.
import { useEffect, useRef, useState } from 'preact/hooks';
import { useThemeOverride, type ThemeOverride } from '../lib/theme-apply.js';
import { useMotionOverride, type MotionOverride } from '../lib/motion-apply.js';
import './SettingsMenu.css';

const THEME_OPTIONS: ThemeOverride[] = ['system', 'light', 'dark'];
const MOTION_OPTIONS: MotionOverride[] = ['system', 'allow', 'reduce'];

export function SettingsMenu() {
  const [open, setOpen] = useState(false);
  const rootRef = useRef<HTMLDivElement>(null);
  const [theme, setTheme] = useThemeOverride();
  const [motion, setMotion] = useMotionOverride();

  // Close on an outside click or Escape — only listens while open, same
  // pattern (and same rationale) as `LinksMenu`.
  useEffect(() => {
    if (!open) return;
    function onPointerDown(e: MouseEvent) {
      if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false);
    }
    function onKeyDown(e: KeyboardEvent) {
      if (e.key === 'Escape') setOpen(false);
    }
    document.addEventListener('pointerdown', onPointerDown);
    document.addEventListener('keydown', onKeyDown);
    return () => {
      document.removeEventListener('pointerdown', onPointerDown);
      document.removeEventListener('keydown', onKeyDown);
    };
  }, [open]);

  return (
    <div class="settings-menu" ref={rootRef}>
      <button
        type="button"
        class="settings-menu-button"
        aria-haspopup="true"
        aria-expanded={open}
        aria-label="settings"
        onClick={() => setOpen((v) => !v)}
      >
        {/* Feather/lucide "settings" glyph, not the bare `⚙` character —
            reported live by mara: icon styles/sizes inconsistent between
            this button and LinksMenu's. `⚙` is a plain text glyph so it does
            scale with `font-size`/`color`, but its exact shape and
            optical weight are down to whatever font the browser
            substitutes for that one codepoint — not guaranteed to match
            an SVG icon at all, which is what LinksMenu's link glyph is
            now built from too. One shared rendering path for both. */}
        <svg
          width="1.3em"
          height="1.3em"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          stroke-linecap="round"
          stroke-linejoin="round"
          aria-hidden="true"
        >
          <circle cx="12" cy="12" r="3" />
          <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" />
        </svg>
      </button>
      {open ? (
        <div class="settings-menu-popover" role="menu">
          <label class="settings-menu-row">
            <span>theme</span>
            <select
              value={theme}
              onChange={(e) => setTheme((e.target as HTMLSelectElement).value as ThemeOverride)}
            >
              {THEME_OPTIONS.map((o) => (
                <option key={o} value={o}>
                  {o}
                </option>
              ))}
            </select>
          </label>
          <label class="settings-menu-row">
            <span>motion</span>
            <select
              value={motion}
              onChange={(e) => setMotion((e.target as HTMLSelectElement).value as MotionOverride)}
            >
              {MOTION_OPTIONS.map((o) => (
                <option key={o} value={o}>
                  {o}
                </option>
              ))}
            </select>
          </label>
        </div>
      ) : null}
    </div>
  );
}
