const EVENT_UP = 0;
const EVENT_DOWN = 1;
const EVENT_SELECT = 2;
const EVENT_BACK = 3;

const canvas = document.getElementById('display');
const context = canvas.getContext('2d');
const status = document.getElementById('status');
const buttons = Array.from(document.querySelectorAll('[data-event]'));

let wasm;

async function loadWasm() {
  const imports = {};
  const response = fetch('./pkg/kinda.wasm');

  if ('instantiateStreaming' in WebAssembly) {
    try {
      return await WebAssembly.instantiateStreaming(response, imports);
    } catch (error) {
      console.warn('Falling back to ArrayBuffer WebAssembly load', error);
    }
  }

  const bytes = await (await fetch('./pkg/kinda.wasm')).arrayBuffer();
  return WebAssembly.instantiate(bytes, imports);
}

function render() {
  const width = wasm.kinda_sim_width();
  const height = wasm.kinda_sim_height();
  const pixelPointer = wasm.kinda_sim_pixels();
  const pixelLength = wasm.kinda_sim_pixel_len();
  const pixels = new Uint8Array(wasm.memory.buffer, pixelPointer, pixelLength);

  canvas.width = width;
  canvas.height = height;

  const image = context.createImageData(width, height);
  for (let source = 0, target = 0; source < pixels.length; source += 1, target += 4) {
    const value = Math.round(18 + (pixels[source] * 230) / 255);
    image.data[target] = value;
    image.data[target + 1] = value;
    image.data[target + 2] = value;
    image.data[target + 3] = 255;
  }

  context.putImageData(image, 0, 0);
}

function sendInput(eventCode) {
  if (!wasm) {
    return;
  }

  wasm.kinda_sim_input(eventCode);
  render();
}

function keyboardEventCode(event) {
  if (event.key === 'ArrowUp') {
    return EVENT_UP;
  }

  if (event.key === 'ArrowDown') {
    return EVENT_DOWN;
  }

  if (event.key === 'Enter') {
    return EVENT_SELECT;
  }

  if (event.key === 'Escape' || event.key === 'Backspace') {
    return EVENT_BACK;
  }

  return null;
}

buttons.forEach((button) => {
  button.disabled = true;
  button.addEventListener('click', () => sendInput(Number(button.dataset.event)));
});

window.addEventListener('keydown', (event) => {
  const eventCode = keyboardEventCode(event);
  if (eventCode === null) {
    return;
  }

  event.preventDefault();
  sendInput(eventCode);
});

try {
  const instance = await loadWasm();
  wasm = instance.instance.exports;
  wasm.kinda_sim_init();
  render();
  buttons.forEach((button) => {
    button.disabled = false;
  });
  status.textContent = 'Ready. Select scans with mock WiFi results.';
} catch (error) {
  console.error(error);
  status.textContent = error instanceof Error ? error.message : 'Could not load simulator.';
}
