// mic-grant.js — runs inside the tab opened by background.js when the
// user clicks "🎤 Enable mic" in the dialer panel. Calls getUserMedia
// to produce Chrome's mic permission prompt, then reports the outcome
// back to background.js (which caches it + rebroadcasts to panels).
//
// v1.31.13 — Was a popup window; now a tab (more reliable). Also: when
// Chrome silently denies (because the user previously dismissed the
// prompt — Chrome remembers and won't re-prompt without an explicit
// reset), we STOP auto-closing the page and surface a step-by-step
// recovery card with a one-click "Open Chrome mic settings" button.

const pip          = document.getElementById("pip");
const status       = document.getElementById("status");
const retry        = document.getElementById("retry");
const hint         = document.getElementById("hint");
const recovery     = document.getElementById("recovery");
const openSettings = document.getElementById("openSettings");
const closeBtn     = document.getElementById("closeBtn");

function setPending(msg) {
  pip.classList.remove("ok", "err");
  pip.textContent = "🎤";
  status.classList.remove("ok", "err");
  status.textContent = msg;
  retry.style.display = "none";
  recovery.style.display = "none";
}
function setOk(msg) {
  pip.classList.remove("err");
  pip.classList.add("ok");
  pip.textContent = "✓";
  status.classList.remove("err");
  status.classList.add("ok");
  status.textContent = msg;
  retry.style.display = "none";
  recovery.style.display = "none";
}
function setErr(msg, opts = {}) {
  pip.classList.remove("ok");
  pip.classList.add("err");
  pip.textContent = "✕";
  status.classList.remove("ok");
  status.classList.add("err");
  status.textContent = msg;
  retry.style.display = "";
  // When Chrome remembers a prior dismissal/block it WILL NOT show the
  // prompt again until the user explicitly resets the permission in
  // chrome://settings/content/microphone. Surface that path clearly.
  if (opts.showRecovery) {
    recovery.style.display = "";
  }
}

async function requestMic() {
  setPending("Requesting mic access…");
  try {
    // getUserMedia must be called from a user gesture context. Loading
    // this page IS a user gesture (the user clicked Enable mic in the
    // panel, which opened this tab). Chrome treats tab open as a
    // sufficient gesture for the first call on a freshly loaded page.
    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
    // Immediately stop the test stream — we only needed permission.
    stream.getTracks().forEach((t) => t.stop());
    setOk("✓ Microphone enabled");
    hint.textContent = "You can close this tab. The dialer is now ready.";
    chrome.runtime.sendMessage({ type: "pd_mic_granted", granted: true }).catch(() => {});
    // Auto-close after a brief success indicator. Use background.js's
    // tab.remove path because window.close() doesn't always work on
    // tabs opened via chrome.tabs.create.
    setTimeout(() => {
      chrome.runtime.sendMessage({ type: "pd_mic_grant_close_self" }).catch(() => {
        // Fallback if the message fails for any reason
        try { window.close(); } catch (_) {}
      });
    }, 1300);
  } catch (err) {
    const name = (err && err.name) || "";
    let message;
    let showRecovery = false;
    if (name === "NotAllowedError") {
      // Two flavors:
      //  - User just clicked Block → permission is now "denied"
      //  - User previously dismissed (X'd out) → Chrome silently denies
      //    without showing the prompt at all
      // Both require a manual reset via chrome://settings.
      message = "Chrome blocked the mic prompt. Reset the permission below, then click Try again.";
      showRecovery = true;
    } else if (name === "NotFoundError" || name === "OverconstrainedError") {
      message = "No microphone detected. Plug one in or check your audio device.";
    } else if (name === "NotReadableError") {
      message = "Mic is in use by another app. Close Zoom/Teams/Meet and try again.";
    } else {
      message = (err && err.message) || "Permission failed.";
    }
    setErr(message, { showRecovery });
    hint.textContent = showRecovery
      ? "Tip: if you accidentally clicked the X on a previous prompt, Chrome remembers that and won't re-ask without a reset."
      : "If the prompt didn't appear, click the 🔒 icon in the address bar.";
    chrome.runtime.sendMessage({
      type: "pd_mic_granted",
      granted: false,
      error: message,
    }).catch(() => {});
  }
}

retry.addEventListener("click", () => requestMic());

// v1.31.13 — chrome:// URLs can't be opened by window.location.href from
// an extension page (security). Use chrome.tabs.create via the bg worker.
openSettings.addEventListener("click", () => {
  chrome.runtime.sendMessage({
    type: "pd_open_url",
    url: "chrome://settings/content/microphone",
  }).catch(() => {
    // Fallback — paste-friendly URL display
    status.textContent = "Open this in a new tab: chrome://settings/content/microphone";
  });
});

closeBtn.addEventListener("click", () => {
  chrome.runtime.sendMessage({ type: "pd_mic_grant_close_self" }).catch(() => {
    try { window.close(); } catch (_) {}
  });
});

// Kick off automatically on load. The user clicked our panel button to
// open this tab, which counts as a user gesture for getUserMedia on the
// first call from this freshly loaded page.
requestMic();
