import { create, type StoreApi, type UseBoundStore } from "zustand";
import type { LibrarySlug } from "./libraries";

type InputState = {
  keys: Set<string>;
  injectKeys: string[] | null;
  joyX: number;
  joyY: number;
  yaw: number;
  pitch: number;
  x: number;
  y: number;
  z: number;
  speed: number;
  pointerLocked: boolean;
};

export type VistaId = "strata" | "watcher" | "tern";

export type WorldUi = {
  webgl: boolean;
  nearestLibrary: LibrarySlug | null;
  nearestVista: VistaId | null;
  alignedVista: VistaId | null;
  hint: string | null;
  enterStore: boolean;
};

type GrokGlobal = typeof globalThis & {
  __strataInput?: InputState;
  __strataWorldUi?: UseBoundStore<StoreApi<WorldUi>>;
};

const g = globalThis as GrokGlobal;

/** Mutable input sampled by the 3D loop — singleton so HUD and canvas share it. */
export const input: InputState = (g.__strataInput ??= {
  keys: new Set<string>(),
  injectKeys: null,
  joyX: 0,
  joyY: 0,
  yaw: 0,
  pitch: -0.06,
  x: 0,
  y: 0,
  z: 14,
  speed: 0,
  pointerLocked: false,
});

export const useWorldUi: UseBoundStore<StoreApi<WorldUi>> = (g.__strataWorldUi ??=
  create<WorldUi>(() => ({
    webgl: true,
    nearestLibrary: null,
    nearestVista: null,
    alignedVista: null,
    hint: null,
    enterStore: false,
  })));

export function heldKeys(): Set<string> {
  if (input.injectKeys) return new Set(input.injectKeys);
  return input.keys;
}

export function installControlsTest() {
  window.__controlsTest = {
    getYaw: () => input.yaw,
    getSpeed: () => input.speed,
    setKeys: (codes) => {
      input.injectKeys = codes.length ? codes : null;
    },
    getPosition: () => ({ x: input.x, y: input.y, z: input.z }),
  };
}
