import {
  refreshMachineSessionControlPage,
} from "./control-page-refresh-workflow.js";
import {
  loadMachineSessionForControlPageWorkflow,
} from "./control-page-session-workflow.js";
import {
  readMachineSessionReadonlyStatus,
} from "./readonly-status-api.js";

export function createMachineSessionControlPageController({
  panelFrame,
  statusNode,
  viewNode,
  renderControlView,
  pollMs = 200,
  setIntervalFn = globalThis.setInterval,
} = {}) {
  if (!panelFrame) {
    throw new Error("A panel iframe is required.");
  }
  if (!statusNode) {
    throw new Error("A control page status node is required.");
  }
  if (!viewNode) {
    throw new Error("A control page view node is required.");
  }
  if (typeof renderControlView !== "function") {
    throw new Error("A control view renderer is required.");
  }

  let refreshTimer = null;

  function getPanelWindow() {
    return panelFrame.contentWindow ?? null;
  }

  function getPanelApi() {
    return getPanelWindow()?.linuxCncIniPanelApi ?? null;
  }

  function getControlView() {
    return getPanelApi()?.getMachineSessionControlView?.() ?? null;
  }

  function render() {
    return refresh().renderResult;
  }

  function refresh() {
    return refreshMachineSessionControlPage({
      getControlView,
      statusNode,
      viewNode,
      renderControlView,
    });
  }

  function loadSessionState() {
    return loadMachineSessionForControlPageWorkflow({
      getPanelWindow,
      getPanelApi,
      getControlView,
    });
  }

  function readStatus() {
    return readMachineSessionReadonlyStatus({
      getPanelApi,
      getControlView,
    });
  }

  function startPolling() {
    if (!refreshTimer) {
      refreshTimer = setIntervalFn(render, pollMs);
    }
    return refreshTimer;
  }

  function mount({ panelSrc = "./index.html" } = {}) {
    panelFrame.addEventListener("load", () => {
      render();
      startPolling();
    });
    panelFrame.src = panelSrc;
    render();
    startPolling();
    return controller;
  }

  const controller = {
    getControlView,
    getPanelApi,
    getPanelWindow,
    loadSessionState,
    mount,
    readStatus,
    refresh,
    render,
    startPolling,
  };

  return controller;
}
