let offscreenPromise;
let pendingHeaven = false;

async function ensureOffscreen() {
  if (offscreenPromise) {
    try {
      await offscreenPromise;
      return;
    } catch {
      // reset en probeer opnieuw
      offscreenPromise = null;
    }
  }

  offscreenPromise = (async () => {
    const hasDocument = (await chrome.offscreen.hasDocument?.()) || false;
    if (hasDocument) return;

    await chrome.offscreen.createDocument({
      url: "offscreen.html",
      reasons: [chrome.offscreen.Reason.AUDIO_PLAYBACK],
      justification: "Play sounds"
    });
  })();

  try {
    await offscreenPromise;
  } catch (err) {
    if (err?.message?.includes("Only a single offscreen document")) {
      // Document bestaat al; geen probleem
      return;
    }
    offscreenPromise = null;
    throw err;
  }
}


async function playSound(file) {
  await ensureOffscreen();
  chrome.runtime.sendMessage({ type: "play", file });
  if (file === "mp3/heavensgates.mp3") {
    showHeavenOverlay();
  }
}

function showHeavenOverlay() {
  chrome.tabs.query({}, (tabs) => {
    const eligible = tabs.filter(
      (t) =>
        t.id !== undefined &&
        t.url &&
        (t.url.startsWith("http://") ||
          t.url.startsWith("https://") ||
          t.url.startsWith("file://"))
    );
    if (eligible.length === 0) {
      // Wacht op eerste bruikbare tab
      pendingHeaven = true;
      return;
    }
    eligible.forEach((tab) => {
      if (tab.id !== undefined) {
        chrome.tabs.sendMessage(tab.id, { type: "show-heaven" }).catch(() => {});
      }
    });
    pendingHeaven = false;
  });
}

async function startScrollSound() {
  await ensureOffscreen();
  chrome.runtime.sendMessage({ type: "scroll-sound" });
}

async function stopScrollSound() {
  await ensureOffscreen();
  chrome.runtime.sendMessage({ type: "scroll-stop" });
}

async function startMouseSound() {
  await ensureOffscreen();
  chrome.runtime.sendMessage({ type: "mouse-move" });
}

async function stopMouseSound() {
  await ensureOffscreen();
  chrome.runtime.sendMessage({ type: "mouse-stop" });
}

chrome.runtime.onStartup.addListener(() => playSound("mp3/heavensgates.mp3"));
chrome.runtime.onInstalled.addListener(() => playSound("mp3/heavensgates.mp3"));


chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg?.type === "link-click") {
    playSound("mp3/surprise.mp3");
  } else if (msg?.type === "scroll-sound") {
    startScrollSound();
  } else if (msg?.type === "scroll-stop") {
    stopScrollSound();
  } else if (msg?.type === "mouse-move") {
    startMouseSound();
  } else if (msg?.type === "mouse-stop") {
    stopMouseSound();
  }
});

// Speel bij tab-gebeurtenissen
chrome.tabs.onCreated.addListener(() => {
  playSound("mp3/thud.mp3");
});

chrome.tabs.onRemoved.addListener(() => {
  playSound("mp3/thud.mp3");
});

// Speel error geluid bij tab wissel
chrome.tabs.onActivated.addListener(() => {
  playSound("mp3/error.mp3");
  if (pendingHeaven) {
    showHeavenOverlay();
  }
});

// Speel French geluid bij refresh/navigatie start
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  if (changeInfo.status === "loading") {
    playSound("mp3/french.mp3");
  }
  if (pendingHeaven && tab.url && (tab.url.startsWith("http://") || tab.url.startsWith("https://") || tab.url.startsWith("file://"))) {
    showHeavenOverlay();
  }
});

// Speel sad violin wanneer een venster wordt gemaximaliseerd/fullscreen,
// en "fine" wanneer het teruggaat naar normaal.
const windowStates = new Map();
const BIG_STATES = new Set(["maximized", "fullscreen"]);

async function updateWindowState(windowId) {
  try {
    const win = await chrome.windows.get(windowId);
    const prev = windowStates.get(windowId);
    windowStates.set(windowId, win.state);
    if (BIG_STATES.has(win.state) && win.state !== prev) {
      playSound("mp3/sad violin.mp3");
    } else if (!BIG_STATES.has(win.state) && BIG_STATES.has(prev)) {
      playSound("mp3/fine.mp3");
    }
  } catch (e) {
    // window might be gone; ignore
  }
}

async function initWindowStates() {
  try {
    const wins = await chrome.windows.getAll();
    wins.forEach((w) => windowStates.set(w.id, w.state));
  } catch (e) {
    // ignore init errors
  }
}

chrome.windows.onCreated.addListener((win) => {
  windowStates.set(win.id, win.state);
});

chrome.windows.onRemoved.addListener((windowId) => {
  windowStates.delete(windowId);
});

chrome.windows.onBoundsChanged.addListener((win) => {
  updateWindowState(win.id);
});

chrome.windows.onFocusChanged.addListener((windowId) => {
  if (windowId === chrome.windows.WINDOW_ID_NONE) return;
  updateWindowState(windowId);
});

// initialize current windows
initWindowStates();
