(function initVisaFlowXPopup(global) {
  "use strict";

  const { Scheduler, SiteContext } = global.VisaFlowX;
  const UI_STATE_KEY = "vfx.uiState";
  const $ = (id) => document.getElementById(id);

  const elements = {
    autoOtpSolver: $("autoOtpSolver"),
    startOtpSolverBtnAuto: $("startOtpSolverBtnAuto"),
    stopOtpSolverBtnAuto: $("stopOtpSolverBtnAuto"),
    otpSolverStateAuto: $("otpSolverStateAuto"),
    startOtpSolverBtnFiva: $("startOtpSolverBtnFiva"),
    stopOtpSolverBtnFiva: $("stopOtpSolverBtnFiva"),
    otpSolverStateFiva: $("otpSolverStateFiva"),
    clearCredentialsBtn: $("clearCredentialsBtn"),
    clearScheduleBtn: $("clearScheduleBtn"),
    contactNumber: $("contactNumber"),
    credentialState: $("credentialState"),
    currentPage: $("currentPage"),
    hdrStartBtn: $("hdrStartBtn"),
    hdrStopBtn: $("hdrStopBtn"),
    hdrStrip: $("hdrStrip"),
    lastAction: $("lastAction"),
    lastError: $("lastError"),
    muteAlarmBtn: $("muteAlarmBtn"),
    notificationsEnabled: $("notificationsEnabled"),
    openPanelBtn: $("openPanelBtn"),
    otpState: $("otpState"),
    password: $("password"),
    quickSaveBtn: $("quickSaveBtn"),
    refreshMode: $("refreshMode"),
    retryCountdown: $("retryCountdown"),
    saveCredentialsBtn: $("saveCredentialsBtn"),
    saveSettingsBtn: $("saveSettingsBtn"),
    scheduleBtn: $("scheduleBtn"),
    scheduleDate: $("scheduleDate"),
    scheduleEnabled: $("scheduleEnabled"),
    schedulerState: $("schedulerState"),
    schedulePreview: $("schedulePreview"),
    scheduleTime: $("scheduleTime"),
    soundEnabled: $("soundEnabled"),
    startBtn: $("startBtn"),
    stateBadge: $("stateBadge"),
    stateText: $("stateText"),
    stopAlarmBtn: $("stopAlarmBtn"),
    stopBtn: $("stopBtn"),
    tabContextNotice: $("tabContextNotice"),
    testAlarmBtn: $("testAlarmBtn"),
    testNotificationBtn: $("testNotificationBtn"),
    toastViewport: $("toastViewport"),
    updateCredentialsBtn: $("updateCredentialsBtn"),
    verificationState: $("verificationState"),
    volume: $("volume")
  };

  let appState = null;
  let activeContext = contextManager().getContext();
  let fivaRuntimeStore = null;
  let countdownTimer = null;
  let stripTimer = null;
  let settingsSaveTimer = null;

  function log(message) {
    console.log("[VisaFlowX]", message);
  }

  function contextManager() {
    return global.VisaFlowX?.ActiveContextManager || {
      CONTEXTS: { AUTOMATION: "AUTOMATION", FIVA: "FIVA" },
      getContext: () => {
        const state = readUiState();
        return state.activeSection === "fiva" ? "FIVA" : "AUTOMATION";
      },
      isFiva: (context) => context === "FIVA",
      setContext: (context) => context
    };
  }

  function readUiState() {
    try {
      return JSON.parse(localStorage.getItem(UI_STATE_KEY) || "{}");
    } catch (_) {
      return {};
    }
  }

  function saveUiState(patch = {}) {
    const current = readUiState();
    localStorage.setItem(UI_STATE_KEY, JSON.stringify({
      ...current,
      ...patch,
      updatedAt: new Date().toISOString()
    }));
  }

  // ── Header status strip ───────────────────────────────────────
  // Shows a thin animated message line directly under the topbar.
  // kind: 'info' | 'success' | 'error'
  function showStrip(message, kind = "info", durationMs = 3500) {
    const el = elements.hdrStrip;
    if (!el) return;
    el.textContent = message;
    el.className = `hdr-strip is-visible${kind === "error" ? " is-error" : kind === "success" ? " is-success" : ""}`;
    if (stripTimer) clearTimeout(stripTimer);
    if (durationMs > 0) {
      stripTimer = setTimeout(() => {
        el.classList.remove("is-visible", "is-error", "is-success");
      }, durationMs);
    }
  }

  // ── Header Start (auto-open IVAC + run) ───────────────────────
  // The service-worker's startAutomation() already calls getOrOpenIvacTab()
  // which: reuses existing tab → focuses it, or creates a new one.
  // We only add loading feedback here — no duplicate tab logic needed.
  async function hdrStart() {
    if (contextManager().isFiva(activeContext)) return hdrStartFiva();
    const btn = elements.hdrStartBtn;
    btn.classList.add("loading");
    showStrip("⏳ Opening IVAC signin page…", "info", 0); // 0 = persist until next update
    try {
      const response = await requestStart("popup");
      if (response.cancelled || response.blocked || response.passive) {
        showStrip("Passive mode enabled", "info", 3000);
      } else {
        showStrip("✅ Automation started", "success");
      }
    } catch (error) {
      showStrip(friendlyError(error), "error");
      showError(error);
    } finally {
      btn.classList.remove("loading");
    }
  }

  // ── Header Stop ───────────────────────────────────────────────
  async function hdrStop() {
    if (contextManager().isFiva(activeContext)) return hdrStopFiva();
    try {
      await send("STOP_AUTOMATION", { reason: "popup" });
      await loadState();
      showStrip("■ Automation stopped", "error", 3000);
      toast("Automation stopped");
    } catch (error) {
      showError(error);
    }
  }

  async function hdrStartFiva() {
    const btn = elements.hdrStartBtn;
    const syncedStore = await refreshFivaRuntimeStore().catch(() => fivaRuntimeStore);
    if (!isFivaReadyStore()) {
      const state = syncedStore?.runtimeState?.state || "";
      const waiting = state === "UPLOADING" || state === "PARSING" || syncedStore?.parserStatus === "RUNNING";
      showRuntimeToast("UPLOAD_REQUIRED", {
        message: waiting ? "Analyzing document..." : "Document is not ready yet.",
        kind: waiting ? "info" : "error"
      });
      renderContextControls();
      return;
    }
    btn.classList.add("loading");
    showStrip("Starting FIVA autofill...", "info", 0);
    try {
      const controller = global.FIVA?.UiController;
      if (!controller?.start) throw new Error("FIVA is not ready yet.");
      await controller.start();
      showStrip("FIVA autofill started", "success", 3000);
    } catch (error) {
      showRuntimeToast(/document is not ready|upload/i.test(error?.message || String(error || "")) ? "UPLOAD_REQUIRED" : "FIVA_FAILED", {
        message: friendlyError(error),
        kind: "error"
      });
    } finally {
      btn.classList.remove("loading");
      renderContextControls();
    }
  }

  async function hdrStopFiva() {
    try {
      const controller = global.FIVA?.UiController;
      if (!controller?.stop) throw new Error("FIVA is not ready yet.");
      await controller.stop();
      showStrip("FIVA stopped", "error", 3000);
      toast("FIVA stopped");
    } catch (error) {
      showStrip(friendlyError(error), "error");
      toast(friendlyError(error), "error");
    } finally {
      renderContextControls();
    }
  }

  function friendlyError(error) {
    const message = error?.message || String(error || "");
    if (/upload.*document.*first|upload.*analyze|document is not ready|missing document/i.test(message)) return "Document is not ready yet.";
    if (/receiving end|could not establish connection|message port|Extension context invalidated/i.test(message)) return "IVAC page not ready";
    if (/loading|page load/i.test(message)) return "Waiting for page load";
    if (/verification/i.test(message)) return "Verification pending";
    if (/schedule date/i.test(message)) return "Choose a schedule date";
    if (/schedule time/i.test(message)) return "Choose a valid future schedule time";
    return message || "Something went wrong";
  }

  function send(type, payload = {}) {
    return chrome.runtime.sendMessage({ type, ...payload }).then((response) => {
      if (!response?.ok) throw new Error(response?.error || "IVAC page not ready");
      return response;
    });
  }

  async function sendWithUnsupportedConfirmation(type, payload = {}) {
    const response = await send(type, payload);
    if (!response?.needsConfirmation) return response;

    const confirmed = window.confirm(response.message || "Open the supported VisaFlowX page from this tab?");
    if (!confirmed) {
      toast("Passive mode enabled", "error");
      return { ...response, cancelled: true };
    }

    return send(type, { ...payload, confirmedUnsupported: true });
  }

  async function requestStart(source = "popup") {
    const response = await sendWithUnsupportedConfirmation("START_AUTOMATION", { source });
    await loadState();
    if (response.cancelled || response.blocked || response.passive) return response;
    toast("Automation started");
    return response;
  }

  function toast(message, kind = "success") {
    const item = document.createElement("div");
    item.className = `toast ${kind}`;
    item.textContent = message;
    elements.toastViewport.appendChild(item);
    requestAnimationFrame(() => item.classList.add("is-visible"));
    setTimeout(() => {
      item.classList.remove("is-visible");
      setTimeout(() => item.remove(), 240);
    }, 2600);
  }

  function clearRuntimeToasts(type = "") {
    const selector = type ? `.toast[data-runtime-toast="${type}"]` : ".toast[data-runtime-toast]";
    elements.toastViewport?.querySelectorAll(selector).forEach((item) => item.remove());
  }

  function showRuntimeToast(type, source = {}) {
    if (type === "UPLOAD_REQUIRED" && isFivaReadyStore()) {
      clearRuntimeToasts("UPLOAD_REQUIRED");
      return;
    }
    clearRuntimeToasts(type);
    const item = document.createElement("div");
    item.className = `toast ${source.kind || "error"}`;
    item.dataset.runtimeToast = type;
    item.textContent = source.message || "FIVA could not start";
    elements.toastViewport.appendChild(item);
    requestAnimationFrame(() => item.classList.add("is-visible"));
    setTimeout(() => {
      item.classList.remove("is-visible");
      setTimeout(() => item.remove(), 240);
    }, 2600);
  }

  function stateClass(state = "IDLE") {
    if (state === "RUNNING" || state === "RELOADING") return "active";
    if (["WAITING_VERIFICATION", "WAITING_COOLDOWN", "WAITING_RETRY", "SERVER_COOLDOWN", "RETRYING", "SCHEDULED"].includes(state)) return "waiting";
    if (state === "OTP_DETECTED" || state === "OTP_REQUIRED") return "otp";
    if (state === "COMPLETED") return "done";
    if (state === "ERROR" || state === "STOPPED") return "error";
    return "idle";
  }

  function stateLabel(state = "IDLE") {
    const labels = {
      IDLE: "Idle",
      STOPPED: "Stopped",
      RUNNING: "Running",
      RELOADING: "Reloading",
      WAITING_VERIFICATION: "Verification",
      WAITING_COOLDOWN: "Cooldown",
      WAITING_RETRY: "Waiting Retry",
      SERVER_COOLDOWN: "Server Cooldown",
      RETRYING: "Retrying",
      OTP_DETECTED: "OTP Detected",
      OTP_REQUIRED: "OTP Required",
      SCHEDULED: "Scheduled",
      ERROR: "Error",
      COMPLETED: "Completed"
    };
    return labels[state] || "Running";
  }

  function setHeaderControlLabels(startLabel, stopLabel) {
    const startText = elements.hdrStartBtn?.querySelector("span");
    const stopText = elements.hdrStopBtn?.querySelector("span");
    if (startText) startText.textContent = startLabel;
    if (stopText) stopText.textContent = stopLabel;
    if (elements.hdrStartBtn) {
      elements.hdrStartBtn.title = startLabel;
      elements.hdrStartBtn.setAttribute("aria-label", startLabel);
    }
    if (elements.hdrStopBtn) {
      elements.hdrStopBtn.title = stopLabel;
      elements.hdrStopBtn.setAttribute("aria-label", stopLabel);
    }
  }

  function fivaStateClass(state = "IDLE") {
    if (state === "RUNNING") return "active";
    if (state === "PARSING" || state === "UPLOADING" || state === "RETRYING") return "waiting";
    if (state === "READY" || state === "SUCCESS") return "done";
    if (state === "FAILED" || state === "STOPPED") return "error";
    return "idle";
  }

  function fivaHeaderLabel() {
    const store = fivaRuntimeStore || {};
    const runtime = store.runtimeState || {};
    const hasReadyProfile = Boolean(store.parsedProfile?.profile && store.parserStatus === "SUCCESS");
    const state = runtime.state || (hasReadyProfile ? "READY" : "IDLE");
    if (state === "RUNNING") return "FIVA RUNNING";
    if (state === "PARSING") return "FIVA PARSING";
    if (state === "UPLOADING") return "FIVA UPLOADING";
    if (state === "FAILED") return "FIVA FAILED";
    if (state === "STOPPED") return "FIVA STOPPED";
    if (state === "READY" || hasReadyProfile) return "FIVA READY";
    return "FIVA IDLE";
  }

  function isFivaReadyStore(store = fivaRuntimeStore) {
    return Boolean(store?.ready === true && store?.parserStatus === "SUCCESS" && store?.parsedProfile?.profile);
  }

  function renderContextControls() {
    activeContext = contextManager().getContext();
    document.body.dataset.activeContext = activeContext.toLowerCase();

    if (contextManager().isFiva(activeContext)) {
      setHeaderControlLabels("Start FIVA", "Stop FIVA");
      elements.stateBadge.textContent = fivaHeaderLabel();
      elements.stateBadge.className = `state-badge ${fivaStateClass(fivaRuntimeStore?.runtimeState?.state)}`;
      if (elements.hdrStartBtn) elements.hdrStartBtn.disabled = !isFivaReadyStore();
      if (isFivaReadyStore()) {
        clearRuntimeToasts("UPLOAD_REQUIRED");
        if (/upload.*document.*first|document is not ready|parser failed|missing document/i.test(elements.hdrStrip?.textContent || "")) {
          showStrip("", "info", 1);
        }
      }
      showModeNotice("FIVA mode active. Top controls start or stop FIVA only.");
      return;
    }

    setHeaderControlLabels("Start Automation", "Stop Automation");
    if (elements.hdrStartBtn) elements.hdrStartBtn.disabled = false;
    if (appState?.status) {
      const isOtp = appState.status.state === "OTP_REQUIRED" || appState.status.state === "OTP_DETECTED";
      if (isOtp) {
        setHeaderControlLabels("OTP Solver", "Stop Automation");
        if (elements.startBtn) {
          elements.startBtn.innerHTML = `<svg><use href="#i-play"></use></svg>OTP Solver`;
        }
      } else {
        if (elements.startBtn) {
          elements.startBtn.innerHTML = `<svg><use href="#i-play"></use></svg>Start Automation`;
        }
      }
      elements.stateBadge.textContent = stateLabel(appState.status.state);
      elements.stateBadge.className = `state-badge ${stateClass(appState.status.state)}`;
    }
    renderActiveTabContext(appState?.activeTabContext);
  }

  function renderCountdown(endsAt) {
    if (countdownTimer) clearInterval(countdownTimer);
    countdownTimer = null;

    const scheduleEndsAt = appState?.schedule?.enabled ? appState.schedule.nextRunAt : null;
    const targetTime = endsAt || scheduleEndsAt;

    if (!targetTime || targetTime <= Date.now()) {
      elements.retryCountdown.textContent = "Continuous";
      return;
    }

    const update = () => {
      const remaining = targetTime - Date.now();
      if (remaining <= 0) {
        elements.retryCountdown.textContent = "Resuming...";
        if (countdownTimer) clearInterval(countdownTimer);
        countdownTimer = null;
        loadState(); // Refresh to catch the state change
        return;
      }

      const h = Math.floor(remaining / 3600000);
      const m = Math.floor((remaining % 3600000) / 60000);
      const s = Math.floor((remaining % 60000) / 1000);

      const parts = [];
      if (h > 0) parts.push(`${h}h`);
      if (m > 0 || h > 0) parts.push(`${m}m`);
      parts.push(`${s}s`);

      elements.retryCountdown.textContent = parts.join(" ");
    };

    update();
    countdownTimer = setInterval(update, 1000);
  }

  function renderStatus(status = {}) {
    const state = status.state || "IDLE";
    elements.stateBadge.textContent = stateLabel(state);
    elements.stateBadge.className = `state-badge ${stateClass(state)}`;
    elements.stateText.textContent = stateLabel(state);
    elements.currentPage.textContent = status.page ? status.page.replace(/^https?:\/\//, "") : "-";
    elements.verificationState.textContent = status.verificationState || "Idle";
    elements.otpState.textContent = status.otpState || "Idle";
    elements.schedulerState.textContent = status.schedulerState || Scheduler.preview(appState?.schedule);
    elements.lastAction.textContent = status.lastAction || "Ready";
    elements.lastError.textContent = status.lastError || "-";
    renderCountdown(status.retryCountdownEndsAt);
    renderContextControls();
  }

  function showModeNotice(message) {
    if (!elements.tabContextNotice) return;
    elements.tabContextNotice.hidden = false;
    elements.tabContextNotice.className = "tab-context-notice is-active";
    elements.tabContextNotice.textContent = message;
  }

  function renderActiveTabContext(context = {}) {
    if (!elements.tabContextNotice) return;

    const state = appState?.status?.state;
    if (state === "OTP_REQUIRED" || state === "OTP_DETECTED") {
      elements.tabContextNotice.hidden = false;
      elements.tabContextNotice.className = "tab-context-notice is-passive";
      elements.tabContextNotice.style.whiteSpace = "pre-line";
      elements.tabContextNotice.style.lineHeight = "1.6";
      elements.tabContextNotice.innerHTML = `⚠️ <b>OTP verification required</b>\n⏸ <b>Automation paused</b>\n⏳ <b>Waiting for user OTP input</b>\n💡 <i>When user click OTP Solver it must be start work</i>`;
      return;
    } else {
      elements.tabContextNotice.style.whiteSpace = "";
      elements.tabContextNotice.style.lineHeight = "";
    }

    if (contextManager().isFiva(activeContext)) {
      showModeNotice("FIVA mode active. Top controls start or stop FIVA only.");
      return;
    }
    const tabContext = context?.type ? context : SiteContext.classifyUrl("");
    const isPassive = tabContext.type === SiteContext.TYPES.UNSUPPORTED;
    const isSupportedPrimary = tabContext.type === SiteContext.TYPES.IVAC || tabContext.type === SiteContext.TYPES.FIVA;

    elements.tabContextNotice.hidden = false;
    elements.tabContextNotice.className = `tab-context-notice ${isSupportedPrimary ? "is-active" : "is-passive"}`;
    if (isSupportedPrimary) {
      elements.tabContextNotice.textContent = `Active supported tab detected: ${tabContext.label}`;
      return;
    }

    elements.tabContextNotice.textContent = isPassive
      ? `Passive mode enabled on ${tabContext.label}. VisaFlowX will not disturb this tab.`
      : `Verification context detected. VisaFlowX remains scoped to the tracked IVAC tab.`;
  }

  function renderForm(state) {
    elements.contactNumber.value = state.credentials.contactNumber || "";
    elements.password.value = state.credentials.password || "";
    elements.credentialState.textContent = state.credentials.contactNumber && state.credentials.password ? "Saved" : "Not saved";
    elements.scheduleEnabled.checked = state.schedule.enabled === true;
    elements.scheduleDate.value = state.schedule.date || "";
    elements.scheduleTime.value = state.schedule.time || "";
    elements.schedulePreview.textContent = Scheduler.preview(state.schedule);
    elements.notificationsEnabled.checked = state.settings.notifications !== false;
    elements.soundEnabled.checked = state.settings.soundEnabled !== false;
    elements.volume.value = state.settings.volume ?? 1;
    elements.autoOtpSolver.checked = false;
    elements.autoOtpSolver.disabled = true;
    elements.refreshMode.value = ["soft", "hard"].includes(state.retry.refreshMode) ? state.retry.refreshMode : "soft";
  }

  async function loadState() {
    appState = await send("GET_STATE");
    await refreshFivaRuntimeStore().catch(() => null);
    renderForm(appState);
    renderStatus(appState.status);
    renderActiveTabContext(appState.activeTabContext);
  }

  async function refreshFivaRuntimeStore() {
    const response = await send("FIVA_GET_RUNTIME");
    fivaRuntimeStore = response.store || fivaRuntimeStore;
    return fivaRuntimeStore;
  }

  function validateCredentials() {
    const contactNumber = elements.contactNumber.value.trim();
    const password = elements.password.value;
    if (!contactNumber) throw new Error("Enter the IVAC contact number");
    if (!password) throw new Error("Enter the IVAC password");
    return { contactNumber, password };
  }

  async function saveCredentials(label = "Credentials saved") {
    await send("SAVE_CREDENTIALS", { credentials: validateCredentials() });
    await loadState();
    toast(label);
  }

  async function clearCredentials() {
    await send("CLEAR_CREDENTIALS");
    await loadState();
    toast("Credentials cleared");
  }

  async function saveSettings({ quiet = false } = {}) {
    await send("SAVE_SETTINGS", {
      settings: {
        notifications: elements.notificationsEnabled.checked,
        soundEnabled: elements.soundEnabled.checked,
        volume: Number(elements.volume.value),
        autoOtpSolver: false
      }
    });
    await send("SAVE_RETRY", {
      retry: {
        refreshMode: elements.refreshMode.value
      }
    });
    await loadState();
    if (!quiet) toast("Settings saved");
  }

  function saveSettingsDebounced() {
    if (settingsSaveTimer) clearTimeout(settingsSaveTimer);
    settingsSaveTimer = setTimeout(() => {
      settingsSaveTimer = null;
      saveSettings({ quiet: true }).catch(showError);
    }, 300);
  }

  async function saveSchedule() {
    if (!elements.scheduleEnabled.checked) {
      await send("CLEAR_SCHEDULE");
      await loadState();
      toast("Scheduler disabled");
      return;
    }
    await send("SAVE_SCHEDULE", {
      schedule: {
        enabled: true,
        date: elements.scheduleDate.value,
        time: elements.scheduleTime.value
      }
    });
    await loadState();
    toast("Scheduler saved");
  }

  function updateSchedulePreview() {
    if (!elements.scheduleEnabled.checked) {
      elements.schedulePreview.textContent = "Not scheduled";
      return;
    }
    try {
      const nextRunAt = Scheduler.parseLocalRun(elements.scheduleDate.value, elements.scheduleTime.value);
      elements.schedulePreview.textContent = Scheduler.preview({ enabled: true, nextRunAt });
    } catch (error) {
      elements.schedulePreview.textContent = friendlyError(error);
    }
  }

  async function openSidePanel() {
    if (chrome.sidePanel?.open) {
      const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
      const windowId = tabs[0]?.windowId;
      if (windowId) {
        await chrome.sidePanel.open({ windowId });
        toast("Side panel opened");
        return;
      }
    }

    await send("OPEN_SIDE_PANEL");
    toast("Side panel opened");
  }

  async function ensureScriptsInjected(tabId) {
    const scripts = [
      "utils/site-context.js",
      "utils/storage.js",
      "utils/sounds.js",
      "utils/timers.js",
      "utils/parser.js",
      "utils/cooldownManager.js",
      "utils/dom-utils.js",
      "content/notification-handler.js",
      "content/detector.js",
      "otp/otpTestProvider.js",
      "otp/otpInputEngine.js",
      "content/retry-engine.js",
      "content/otp-monitor.js",
      "content/captcha-solver.js",
      "content/automation.js"
    ];
    for (const file of scripts) {
      await chrome.scripting.executeScript({
        target: { tabId, allFrames: true },
        files: [file]
      }).catch((e) => console.warn(`Dynamic injection warning for ${file}:`, e.message));
    }
  }

  async function sendToActiveTab(message) {
    const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
    const tabId = tabs[0]?.id;
    if (!tabId) throw new Error("No active tab detected. Please open the IVAC tab first.");
    try {
      return await chrome.tabs.sendMessage(tabId, message);
    } catch (err) {
      console.warn("[VisaFlowX] Sending message failed, attempting script re-injection:", err.message);
      await ensureScriptsInjected(tabId);
      // Wait a brief moment for script initialization
      await new Promise(r => setTimeout(r, 250));
      return await chrome.tabs.sendMessage(tabId, message);
    }
  }

  function setOtpSolverState(stateText, className) {
    [elements.otpSolverStateAuto, elements.otpSolverStateFiva].forEach((el) => {
      if (el) {
        el.textContent = stateText;
        el.className = `state-badge ${className}`;
      }
    });
  }

  async function startOtpSolver() {
    try {
      setOtpSolverState("Solving...", "waiting");
      toast("Initiating OTP Solver...");
      const reply = await sendToActiveTab({ type: "START_OTP_SOLVER" });
      if (reply && reply.ok) {
        setOtpSolverState("Success", "done");
        toast("OTP Solver successfully completed!");
      } else {
        const errMsg = reply?.error || "No response from page.";
        setOtpSolverState("Failed", "error");
        toast(errMsg, "error");
      }
    } catch (error) {
      setOtpSolverState("Failed", "error");
      toast(error?.message || "No supported active tab found.", "error");
    }
  }

  async function stopOtpSolver() {
    try {
      toast("Stopping OTP Solver...");
      await sendToActiveTab({ type: "STOP_OTP_SOLVER" }).catch(() => {});
      setOtpSolverState("Idle", "idle");
      toast("OTP Solver stopped.");
    } catch (error) {
      setOtpSolverState("Idle", "idle");
      toast("OTP Solver stopped.");
    }
  }

  function bind() {
    // ── Header quick controls (always visible at top) ──
    elements.hdrStartBtn.addEventListener("click", () => hdrStart());
    elements.hdrStopBtn.addEventListener("click",  () => hdrStop());
    elements.openPanelBtn?.addEventListener("click", () => openSidePanel().catch(showError));

    // ── OTP Solver Controls (both Automation and FIVA) ──
    elements.startOtpSolverBtnAuto?.addEventListener("click", () => startOtpSolver().catch(showError));
    elements.stopOtpSolverBtnAuto?.addEventListener("click", () => stopOtpSolver().catch(showError));
    elements.startOtpSolverBtnFiva?.addEventListener("click", () => startOtpSolver().catch(showError));
    elements.stopOtpSolverBtnFiva?.addEventListener("click", () => stopOtpSolver().catch(showError));

    // ── Existing panel buttons (unchanged) ──
    elements.startBtn.addEventListener("click", () => requestStart("popup").catch(showError));
    elements.stopBtn.addEventListener("click", () => send("STOP_AUTOMATION", { reason: "popup" }).then(() => loadState()).then(() => toast("Automation stopped")).catch(showError));
    elements.quickSaveBtn.addEventListener("click", () => saveCredentials().catch(showError));
    elements.saveCredentialsBtn.addEventListener("click", () => saveCredentials("Credentials saved").catch(showError));
    elements.updateCredentialsBtn.addEventListener("click", () => saveCredentials("Credentials updated").catch(showError));
    elements.clearCredentialsBtn.addEventListener("click", () => clearCredentials().catch(showError));
    elements.scheduleBtn.addEventListener("click", () => saveSchedule().catch(showError));
    elements.clearScheduleBtn.addEventListener("click", () => send("CLEAR_SCHEDULE").then(loadState).then(() => toast("Schedule cleared")).catch(showError));
    elements.saveSettingsBtn.addEventListener("click", () => saveSettings().catch(showError));
    elements.testNotificationBtn.addEventListener("click", () => send("TEST_NOTIFICATION").then(() => toast("Notification sent")).catch(showError));
    elements.testAlarmBtn.addEventListener("click", () => send("TEST_ALARM", { volume: Number(elements.volume.value) }).then(() => toast("Alarm started")).catch(showError));
    elements.muteAlarmBtn.addEventListener("click", () => send("MUTE_ALARM").then(() => toast("Alarm muted")).catch(showError));
    elements.stopAlarmBtn.addEventListener("click", () => send("STOP_ALARM").then(() => toast("Alarm stopped")).catch(showError));
    elements.volume.addEventListener("input", () => send("SET_ALARM_VOLUME", { volume: Number(elements.volume.value) }).catch(() => {}));
    [elements.notificationsEnabled, elements.soundEnabled, elements.refreshMode].forEach((element) => {
      element.addEventListener("change", saveSettingsDebounced);
    });
    [elements.scheduleDate, elements.scheduleTime, elements.scheduleEnabled].forEach((element) => {
      element.addEventListener("change", updateSchedulePreview);
    });
    global.addEventListener("VFX_ACTIVE_CONTEXT_CHANGED", (event) => {
      activeContext = contextManager().normalizeContext
        ? contextManager().normalizeContext(event.detail?.activeContext)
        : event.detail?.activeContext;
      renderContextControls();
    });
    global.addEventListener("FIVA_RUNTIME_LOCAL_UPDATE", (event) => {
      fivaRuntimeStore = event.detail?.store || fivaRuntimeStore;
      renderContextControls();
    });

  }

  function showError(error) {
    const message = friendlyError(error);
    elements.stateBadge.textContent = "Error";
    elements.stateBadge.className = "state-badge error";
    elements.stateText.textContent = "Error";
    elements.lastAction.textContent = message;
    elements.lastError.textContent = message;
    toast(message, "error");
  }

  chrome.runtime.onMessage.addListener((message) => {
    if (message?.type === "FIVA_RUNTIME_UPDATE" || message?.type === "FIVA_RUNTIME_UPDATED") {
      fivaRuntimeStore = message.store || fivaRuntimeStore;
      renderContextControls();
      return;
    }
    if (message?.type === "OTP_POPUP_PULSE") {
      document.body.classList.add("otp-pulse-active");
      setTimeout(() => document.body.classList.remove("otp-pulse-active"), 1200);
      toast("🔔 OTP Required! Complete verification.", "error");
      return;
    }
    if (message?.type === "STATUS_UPDATE") {
      appState = appState || {};
      appState.status = message.status;
      renderStatus(message.status);
      if (contextManager().isFiva(activeContext)) return;
      // Mirror state changes in the header strip
      const s = message.status?.state;
      if (s === "OTP_DETECTED" || s === "OTP_REQUIRED") {
        toast("OTP detected. Automation stopped.", "error");
        showStrip("🔔 OTP Required — Alarm sounding", "error", 0);
      } else if (s === "RUNNING") {
        const action = message.status?.lastAction || "";
        const verification = message.status?.verificationState || "";
        if (/signing in/i.test(action)) {
          showStrip("Signing in", "info", 4000);
        } else if (/verification completed/i.test(`${verification} ${action}`)) {
          showStrip("Verification completed", "success", 4000);
        } else {
          showStrip("▶ Running", "success", 4000);
        }
      } else if (s === "WAITING_VERIFICATION") {
        showStrip("🔒 Verification required — complete it manually", "info", 0);
      } else if (s === "WAITING_RETRY") {
        showStrip("⏳ Waiting retry…", "info", 0);
      } else if (s === "SERVER_COOLDOWN") {
        const action = message.status?.lastAction || "";
        const matches = action.match(/retrying in (.*)/i);
        const timer = matches ? matches[1] : "timer active";
        showStrip(`⏳ Server Cooldown — Retrying in ${timer}`, "info", 0);
      } else if (s === "RETRYING") {
        showStrip("Retrying continuously…", "info", 0);
      } else if (s === "RELOADING") {
        showStrip("Reloading IVAC signin page…", "info", 0);
      } else if (s === "ERROR") {
        showStrip(message.status?.lastError || "Error", "error", 5000);
      } else if (s === "COMPLETED") {
        showStrip("✅ Login completed", "success", 5000);
      } else if (s === "IDLE" || s === "STOPPED") {
        showStrip("", "info", 1);
      }
    }
  });

  function persistScroll() {
    saveUiState({ scrollTop: document.scrollingElement?.scrollTop || document.documentElement.scrollTop || 0 });
  }

  function restoreScroll() {
    const state = readUiState();
    const scrollTop = Number(state.scrollTop || 0);
    if (scrollTop > 0) {
      requestAnimationFrame(() => window.scrollTo({ top: scrollTop, behavior: "auto" }));
    }
  }

  function cleanupPopupTimers() {
    if (countdownTimer) clearInterval(countdownTimer);
    if (stripTimer) clearTimeout(stripTimer);
    if (settingsSaveTimer) clearTimeout(settingsSaveTimer);
    countdownTimer = null;
    stripTimer = null;
    settingsSaveTimer = null;
    persistScroll();
  }

  document.addEventListener("DOMContentLoaded", () => {
    log("Popup initialized");
    bind();
    renderContextControls();
    restoreScroll();
    loadState().catch(showError);
  });
  window.addEventListener("beforeunload", cleanupPopupTimers);
})(typeof globalThis !== "undefined" ? globalThis : this);
