// SPDX-FileCopyrightText: 2026 Stan Grams <sjg@haxx.space>
//
// SPDX-License-Identifier: GPL-2.0-or-later

// Mirrors the `window.trx` host contract that app.ts publishes and that
// src/plugins/host.ts consumes.  Feature bundles read all application state
// and services through it, so every plugin test needs it on its stub window.

export function createHost({ state = {}, core = {}, modules = {} } = {}) {
  const calls = [];
  const record = (name, result) => (...args) => {
    calls.push({ name, args });
    return typeof result === "function" ? result(...args) : result;
  };
  return {
    calls,
    trx: {
      state: {
        serverLat: null,
        serverLon: null,
        authEnabled: false,
        authRole: "control",
        lastActiveRigId: null,
        lastRigIds: [],
        lastRigDisplayNames: {},
        lastFreqHz: null,
        lastSpectrumData: null,
        jogUnit: 1000,
        rxActive: false,
        decoderRegistry: [],
        lastModeName: "",
        currentBandwidthHz: 2400,
        audioChannelOverride: null,
        ...state,
      },
      core: {
        postPath: record("postPath", async () => undefined),
        applyLocalTunedFrequency: record("applyLocalTunedFrequency"),
        armOptimisticFrequency: record("armOptimisticFrequency"),
        escapeMapHtml: (value) => String(value)
          .replaceAll("&", "&amp;").replaceAll("<", "&lt;")
          .replaceAll(">", "&gt;").replaceAll('"', "&quot;"),
        haversineKm: record("haversineKm", () => 0),
        showHint: record("showHint"),
        formatFreqForStep: (hz) => String(hz),
        refreshFreqDisplay: record("refreshFreqDisplay"),
        setJogDivisor: record("setJogDivisor"),
        mwDefaultsForMode: record("mwDefaultsForMode", () => [0, 0, 0, 0]),
        resetRdsDisplay: record("resetRdsDisplay"),
        positionRdsPsOverlay: record("positionRdsPsOverlay"),
        updateWfmControls: record("updateWfmControls"),
        updateSdrSquelchControlVisibility: record("updateSdrSquelchControlVisibility"),
        updateDocumentTitle: record("updateDocumentTitle"),
        activeChannelRds: record("activeChannelRds", () => null),
        startRxAudio: record("startRxAudio"),
        stopRxAudio: record("stopRxAudio"),
        setRigFrequency: record("setRigFrequency"),
        syncBandwidthInput: record("syncBandwidthInput"),
        scheduleSpectrumDraw: record("scheduleSpectrumDraw"),
        syncModePicker: record("syncModePicker"),
        onDecoderRegistryReady: record("onDecoderRegistryReady"),
        ...core,
      },
      modules,
    },
  };
}
