// @wuys/map · interactions/keyboard.js
// Arrow keys (held, with modifiers) for nav. Plus shortcuts: G (toggle globe),
// F (toggle flags), T (cycle theme), Space (reset), ? (help).

import { NAV_ZOOM_MIN, NAV_ZOOM_MAX, NAV_LAT_MAX } from "../core/state.js";

const ARROWS = new Set(["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"]);

export function attachKeyboard({ state, events, nav, renderer, themesAvail, isActive }) {
  const held = new Set();
  let raf = 0;
  let last = 0;
  let modShift = false, modCtrl = false;

  function tick(now) {
    raf = 0;
    if (!last) last = now;
    const dt = Math.min(0.05, (now - last) / 1000);
    last = now;
    let mult = 1;
    if (modShift) mult = 3;
    if (modCtrl)  mult = 6;
    const speedDegPerSec = state.view.mode === "globe" ? 31 : 26;
    const step = speedDegPerSec * mult * dt / Math.max(1, state.nav.zoom * 0.4);
    if (held.has("ArrowLeft"))  state.nav.tLon -= step;
    if (held.has("ArrowRight")) state.nav.tLon += step;
    if (held.has("ArrowUp"))    state.nav.tLat = Math.min(NAV_LAT_MAX,  state.nav.tLat + step);
    if (held.has("ArrowDown"))  state.nav.tLat = Math.max(-NAV_LAT_MAX, state.nav.tLat - step);
    while (state.nav.tLon >  180) state.nav.tLon -= 360;
    while (state.nav.tLon < -180) state.nav.tLon += 360;
    // Continuous key-hold: sync current → target for instant feedback
    state.nav.lon = state.nav.tLon;
    state.nav.lat = state.nav.tLat;
    if (renderer) renderer.patch();
    events.emit("nav:change", state.nav);
    if (held.size > 0) {
      raf = requestAnimationFrame(tick);
    } else {
      last = 0;
    }
  }

  window.addEventListener("keydown", (ev) => {
    modShift = ev.shiftKey;
    modCtrl  = ev.ctrlKey || ev.metaKey;
    if (!isActive()) return;
    const tag = ev.target && ev.target.tagName;
    if (tag === "INPUT" || tag === "TEXTAREA" || ev.target.isContentEditable) return;

    if (ARROWS.has(ev.key)) {
      ev.preventDefault();
      held.add(ev.key);
      if (!raf) { last = 0; raf = requestAnimationFrame(tick); }
      return;
    }

    // Shortcuts
    if (ev.key === "+" || ev.key === "=") { nav.zoomBy(1.5); }
    else if (ev.key === "-")              { nav.zoomBy(1 / 1.5); }
    else if (ev.key === " ")              { ev.preventDefault(); nav.reset(); }
    else if (ev.key === "g" || ev.key === "G") {
      const next = state.view.mode === "flat" ? "globe" : "flat";
      events.emit("view:request", next);
    }
    else if (ev.key === "f" || ev.key === "F") {
      events.emit("flags:toggle", null);
    }
    else if (ev.key === "?") {
      events.emit("help:toggle", null);
    }
  });

  window.addEventListener("keyup", (ev) => {
    modShift = ev.shiftKey;
    modCtrl  = ev.ctrlKey || ev.metaKey;
    held.delete(ev.key);
  });

  window.addEventListener("blur", () => held.clear());
}
