import { InferenceQueue } from "../inference/queue";
import { loadSettings, saveSettings, setDefinitionPaused } from "../shared/settings";
import { refreshSubscriptions, subscriptionsAreDue } from "../shared/subscriptions";
import type { InferenceRequest, InferenceResult, RuntimeMessage } from "../shared/types";

export function createRuntime(runBatch: (requests: InferenceRequest[]) => Promise<InferenceResult[]>): void {
  const queue = new InferenceQueue(runBatch);

  const refreshIfDue = async (): Promise<void> => {
    const settings = await loadSettings();
    if (subscriptionsAreDue(settings)) {
      const result = await refreshSubscriptions(settings);
    }
  };
  void chrome.alarms?.create?.("vibeguard-subscriptions-weekly", { periodInMinutes: 7 * 24 * 60 });
  chrome.alarms?.onAlarm?.addListener((alarm) => { if (alarm.name === "vibeguard-subscriptions-weekly") void refreshIfDue(); });
  chrome.runtime.onStartup?.addListener(() => { void refreshIfDue(); });

  chrome.runtime.onMessage.addListener((message: RuntimeMessage, sender, sendResponse) => {
    if (message.type === "INFER") {
      const request: InferenceRequest = { ...message.request, tabId: message.request.tabId ?? sender.tab?.id };
      queue.enqueue(request).then((result) => sendResponse({ type: "INFERENCE_RESULT", result })).catch((error) => sendResponse({ error: String(error) }));
      return true;
    }
    if (message.type === "GET_SETTINGS") { loadSettings().then((settings) => sendResponse({ type: "SETTINGS", settings })); return true; }
    if (message.type === "SET_SETTINGS") { saveSettings(message.settings).then((settings) => sendResponse({ type: "SETTINGS", settings })); return true; }
    if (message.type === "SET_DEFINITION_PAUSED") {
      loadSettings()
        .then((settings) => saveSettings(setDefinitionPaused(settings, message.definitionId, message.paused)))
        .then((settings) => sendResponse({ type: "SETTINGS", settings }))
        .catch((error) => sendResponse({ error: String(error) }));
      return true;
    }
    if (message.type === "REFRESH_SUBSCRIPTIONS") {
      loadSettings().then((settings) => refreshSubscriptions(settings)).then((result) => {
        return result.settings;
      }).then((settings) => sendResponse({ type: "SUBSCRIPTIONS_UPDATED", settings })).catch((error) => sendResponse({ error: String(error) }));
      return true;
    }
    if (message.type === "PING") { sendResponse({ type: "PONG", pending: queue.pendingCount }); }
    return false;
  });

  chrome.tabs?.onRemoved?.addListener((tabId) => queue.invalidate(tabId));
}
