const $ = (sel) => document.querySelector(sel);

function apiCall(method, path, body) {
  return new Promise((resolve) => {
    chrome.runtime.sendMessage(
      { type: "API_CALL", method, path, body },
      (response) => resolve(response)
    );
  });
}

function escapeHTML(str) {
  const div = document.createElement("div");
  div.textContent = str;
  return div.innerHTML;
}

function showToast(message, type = "success") {
  const toast = document.createElement("div");
  toast.className = `toast toast-${type}`;
  toast.textContent = message;
  document.body.appendChild(toast);
  requestAnimationFrame(() => toast.classList.add("show"));
  setTimeout(() => {
    toast.classList.remove("show");
    setTimeout(() => toast.remove(), 300);
  }, 3000);
}

function openModal(id) {
  document.getElementById(id).style.display = "flex";
}

function closeModal(id) {
  document.getElementById(id).style.display = "none";
}

let _modalMouseDownTarget = null;
document.addEventListener("mousedown", (e) => {
  _modalMouseDownTarget = e.target;
});
document.addEventListener("click", (e) => {
  if (
    e.target.classList.contains("modal-overlay") &&
    _modalMouseDownTarget === e.target
  ) {
    e.target.style.display = "none";
  }
  _modalMouseDownTarget = null;
});

document.querySelectorAll(".modal-close").forEach((btn) => {
  btn.addEventListener("click", () => {
    closeModal(btn.dataset.close);
  });
});

document.querySelectorAll(".tab").forEach((tab) => {
  tab.addEventListener("click", () => {
    document.querySelectorAll(".tab").forEach((t) => t.classList.remove("active"));
    document.querySelectorAll(".panel").forEach((p) => p.classList.remove("active"));
    tab.classList.add("active");
    const panel = document.getElementById(`panel-${tab.dataset.tab}`);
    if (panel) panel.classList.add("active");
  });
});

function truncatePubkey(pk) {
  return pk.slice(0, 6) + "..." + pk.slice(-4);
}

function renderWalletCard(w) {
  const label = w.label ? escapeHTML(w.label) : "";
  const labelHtml = label ? `<span class="wc-label">${label}</span>` : "";
  const balanceText = w.balanceText || "...";
  const hasNoBalance = balanceText === "0.0000 SOL";
  const hasNonces = w.nonceCount >= 3;
  const isEnabled = w.extensionEnabled !== undefined ? w.extensionEnabled : w.active;
  const statusClass = hasNoBalance ? "badge-no-balance"
    : !hasNonces ? "badge-not-ready"
    : isEnabled ? "badge-ready"
    : "badge-not-ready";
  const statusText = hasNoBalance ? "No Balance"
    : !hasNonces ? "Setup Required"
    : isEnabled ? "Ready to Trade"
    : "Disabled";
  const nonceText = hasNoBalance ? "Deposit SOL to get started" : w.nonceCount > 0 ? `${w.nonceCount} task accounts` : "No task accounts";

  const setupBtn = !hasNonces && !hasNoBalance
    ? `<button class="btn btn-primary btn-xs setup-wallet-btn" data-pubkey="${escapeHTML(w.pubkey)}" data-nonces="${w.nonceCount}">Setup</button>`
    : "";

  const activeToggle = hasNonces && !hasNoBalance
    ? `<div class="wc-active-toggle">
        <span>Active</span>
        <label class="toggle-switch">
          <input type="checkbox" class="wallet-active-toggle" data-pubkey="${escapeHTML(w.pubkey)}" ${isEnabled ? "checked" : ""}>
          <span class="toggle-slider"></span>
        </label>
      </div>`
    : "";

  return `
    <div class="wallet-card" data-pubkey="${escapeHTML(w.pubkey)}" draggable="true">
      <div class="wc-drag-handle" title="Drag to reorder">⠿</div>
      <div class="wc-content">
        <div class="wc-top">
          <div class="wc-left">
            ${labelHtml}
            <span class="wc-pubkey wc-copy" data-copy="${escapeHTML(w.pubkey)}" title="Click to copy">${truncatePubkey(w.pubkey)} <svg class="wc-copy-icon" width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1"/></svg></span>
          </div>
          <div class="wc-balance">${escapeHTML(balanceText)}</div>
        </div>
        <div class="wc-bottom">
          <div class="wc-meta">
            <span class="badge ${statusClass}">${statusText}</span>
            <span class="wc-nonces">${nonceText}</span>
          </div>
          <div class="wc-actions">
            ${setupBtn}
            ${activeToggle}
            <button class="btn-icon wallet-settings-btn" data-pubkey="${escapeHTML(w.pubkey)}" data-label="${escapeHTML(w.label || "")}" data-nonces="${w.nonceCount}" title="Wallet settings">
              <svg width="14" height="14" viewBox="0 0 20 20" fill="currentColor"><path d="M11.078 0l.163 1.186c.274.09.54.196.796.318l.956-.735 1.49 1.49-.735.957c.122.255.228.52.318.795L15.252 4.174V6.15l-1.186.163a5.5 5.5 0 01-.318.796l.735.956-1.49 1.49-.957-.735a5.5 5.5 0 01-.795.318L11.078 10.324H9.102l-.163-1.186a5.5 5.5 0 01-.796-.318l-.956.735-1.49-1.49.735-.957a5.5 5.5 0 01-.318-.795L4.928 6.15V4.174l1.186-.163c.09-.274.196-.54.318-.796l-.735-.956 1.49-1.49.957.735c.255-.122.52-.228.795-.318L9.102 0h1.976zM10.09 3.2a1.962 1.962 0 100 3.924 1.962 1.962 0 000-3.924z" transform="translate(0 4.838)"/></svg>
            </button>
          </div>
        </div>
      </div>
    </div>
  `;
}

function sortWalletsByOrder(wallets, order) {
  if (!order || order.length === 0) return wallets;
  const orderMap = {};
  order.forEach((pk, i) => { orderMap[pk] = i; });
  return [...wallets].sort((a, b) => {
    const ai = orderMap[a.pubkey] ?? 9999;
    const bi = orderMap[b.pubkey] ?? 9999;
    return ai - bi;
  });
}

async function loadWallets(wallets) {
  const grid = $("#wallet-grid");

  if (!wallets || wallets.length === 0) {
    grid.innerHTML = '<div class="empty-state">No wallets yet. Create or import one above.</div>';
    return;
  }

  const orderData = await chrome.storage.local.get("slotshark.walletOrder");
  const order = orderData["slotshark.walletOrder"] || [];

  const sorted = sortWalletsByOrder(wallets, order);
  grid.innerHTML = sorted.map((w) => renderWalletCard({ ...w, balanceText: "..." })).join("");
  attachCardHandlers();

  const results = await Promise.all(
    sorted.map(async (w) => {
      const resp = await apiCall("GET", `/wallet/${w.pubkey}/balance`);
      const balanceText = resp.data?.success
        ? `${resp.data.balanceSol.toFixed(4)} SOL`
        : "Error";
      return { ...w, balanceText };
    })
  );

  grid.innerHTML = results.map(renderWalletCard).join("");
  attachCardHandlers();
}

function attachCardHandlers() {
  document.querySelectorAll(".setup-wallet-btn").forEach((btn) => {
    btn.addEventListener("click", async () => {
      const pubkey = btn.dataset.pubkey;
      const existingNonces = parseInt(btn.dataset.nonces) || 0;
      const needed = Math.max(0, 3 - existingNonces);
      btn.disabled = true;
      btn.textContent = "Setting up...";

      const resp = await apiCall("POST", `/wallet/${pubkey}/deploy-nonces`, { count: needed });

      if (resp.data?.success) {
        showToast(`${truncatePubkey(pubkey)} is now ready`);
        await refreshWallets();
      } else {
        showToast(resp.data?.error || resp.error || "Setup failed", "error");
        btn.disabled = false;
        btn.textContent = "Setup";
      }
    });
  });

  document.querySelectorAll(".wallet-active-toggle").forEach((toggle) => {
    toggle.addEventListener("change", async () => {
      const pubkey = toggle.dataset.pubkey;
      const enabled = toggle.checked;
      toggle.disabled = true;
      const resp = await apiCall("POST", `/wallet/${pubkey}/enable`, { context: "extension", enabled });
      toggle.disabled = false;
      if (!resp.data?.success) {
        toggle.checked = !enabled;
        showToast(resp.data?.error || resp.error || "Failed to update", "error");
        return;
      }
      if (enabled) {
        if (!_activeWallets.includes(pubkey)) _activeWallets.push(pubkey);
      } else {
        _activeWallets = _activeWallets.filter((p) => p !== pubkey);
      }
      await chrome.storage.local.set({ "slotshark.activeWallets": _activeWallets });
      await refreshWallets();
    });
  });

  document.querySelectorAll(".wc-copy").forEach((el) => {
    el.addEventListener("click", async () => {
      try {
        await navigator.clipboard.writeText(el.dataset.copy);
        showToast("Address copied to clipboard");
      } catch {
        showToast("Copy failed", "error");
      }
    });
  });

  document.querySelectorAll(".wallet-settings-btn").forEach((btn) => {
    btn.addEventListener("click", () => {
      openWalletSettings(btn.dataset.pubkey, btn.dataset.label, parseInt(btn.dataset.nonces) || 0);
    });
  });

  let dragEl = null;
  let scrollInterval = null;
  const grid = $("#wallet-grid");
  const EDGE_ZONE = 40; // px from edge to trigger scroll
  const SCROLL_SPEED = 4; // px per frame

  function startEdgeScroll(e) {
    if (!dragEl || !grid) return;
    const rect = grid.getBoundingClientRect();
    const y = e.clientY;
    clearInterval(scrollInterval);
    scrollInterval = null;
    if (y < rect.top + EDGE_ZONE && grid.scrollTop > 0) {
      scrollInterval = setInterval(() => { grid.scrollTop -= SCROLL_SPEED; }, 16);
    } else if (y > rect.bottom - EDGE_ZONE && grid.scrollTop < grid.scrollHeight - grid.clientHeight) {
      scrollInterval = setInterval(() => { grid.scrollTop += SCROLL_SPEED; }, 16);
    }
  }

  grid.addEventListener("dragover", (e) => { startEdgeScroll(e); });

  document.querySelectorAll(".wallet-card").forEach((card) => {
    card.addEventListener("dragstart", (e) => {
      dragEl = card;
      card.classList.add("wc-dragging");
      e.dataTransfer.effectAllowed = "move";
    });
    card.addEventListener("dragend", () => {
      card.classList.remove("wc-dragging");
      document.querySelectorAll(".wc-drag-over").forEach((el) => el.classList.remove("wc-drag-over"));
      dragEl = null;
      clearInterval(scrollInterval);
      scrollInterval = null;
      const cards = document.querySelectorAll(".wallet-card");
      const order = Array.from(cards).map((c) => c.dataset.pubkey);
      chrome.storage.local.set({ "slotshark.walletOrder": order });
    });
    card.addEventListener("dragover", (e) => {
      e.preventDefault();
      e.dataTransfer.dropEffect = "move";
      if (dragEl && dragEl !== card) {
        card.classList.add("wc-drag-over");
      }
    });
    card.addEventListener("dragleave", () => {
      card.classList.remove("wc-drag-over");
    });
    card.addEventListener("drop", (e) => {
      e.preventDefault();
      card.classList.remove("wc-drag-over");
      if (dragEl && dragEl !== card) {
        const cards = Array.from(grid.children);
        const fromIdx = cards.indexOf(dragEl);
        const toIdx = cards.indexOf(card);
        if (fromIdx < toIdx) {
          grid.insertBefore(dragEl, card.nextSibling);
        } else {
          grid.insertBefore(dragEl, card);
        }
      }
    });
  });
}

let _activeWallets = [];
let cachedWallets = [];
let _pendingSecretKey = null;

$("#refresh-wallets-btn").addEventListener("click", async () => {
  $("#refresh-wallets-btn").disabled = true;
  $("#refresh-wallets-btn").textContent = "...";
  await refreshWallets();
  $("#refresh-wallets-btn").disabled = false;
  $("#refresh-wallets-btn").textContent = "Refresh";
});

$("#create-wallet-btn").addEventListener("click", () => {
  $("#create-phase-form").style.display = "block";
  $("#create-phase-reveal").style.display = "none";
  $("#create-label").value = "";
  $("#create-error").textContent = "";
  $("#create-modal-title").textContent = "Create Wallet";
  openModal("modal-create");
});

$("#create-submit").addEventListener("click", async () => {
  const label = $("#create-label").value.trim();
  $("#create-error").textContent = "";
  $("#create-submit").disabled = true;
  $("#create-submit").textContent = "Creating...";

  const body = {};
  if (label) body.label = label;

  const resp = await apiCall("POST", "/wallet/create", body);

  $("#create-submit").disabled = false;
  $("#create-submit").textContent = "Create";

  if (resp.data?.success) {
    if (_activeWallets.length === 0) {
      _activeWallets.push(resp.data.pubkey);
      chrome.storage.local.set({ "slotshark.activeWallets": _activeWallets });
    }
    _pendingSecretKey = resp.data.secretKey;
    $("#create-phase-form").style.display = "none";
    $("#create-phase-reveal").style.display = "block";
    $("#create-modal-title").textContent = "Save Your Secret Key";
    $("#create-secret-key").textContent = "Click 'Reveal' to show your secret key";
    $("#create-secret-key").classList.add("secret-hidden");
    $("#create-pubkey").textContent = `Pubkey: ${resp.data.pubkey}`;
  } else {
    $("#create-error").textContent = resp.data?.error || resp.error || "Create failed";
  }
});

$("#create-reveal-btn").addEventListener("click", () => {
  if (!_pendingSecretKey) return;
  $("#create-secret-key").textContent = _pendingSecretKey;
  $("#create-secret-key").classList.remove("secret-hidden");
  $("#create-reveal-btn").style.display = "none";
});

$("#create-copy-btn").addEventListener("click", async () => {
  if (!_pendingSecretKey) return;
  try {
    await navigator.clipboard.writeText(_pendingSecretKey);
    $("#create-copy-btn").textContent = "Copied!";
    setTimeout(() => ($("#create-copy-btn").textContent = "Copy Secret Key"), 2000);
  } catch {
    showToast("Copy failed — select and copy manually", "error");
  }
});

$("#create-dismiss-btn").addEventListener("click", () => {
  _pendingSecretKey = null;
  $("#create-secret-key").textContent = "";
  closeModal("modal-create");
  refreshWallets();
});

$("#import-wallet-btn").addEventListener("click", () => {
  $("#import-key").value = "";
  $("#import-label").value = "";
  $("#import-error").textContent = "";
  openModal("modal-import");
});

$("#import-submit").addEventListener("click", async () => {
  const secretKey = $("#import-key").value.trim();
  const label = $("#import-label").value.trim();

  if (!secretKey) {
    $("#import-error").textContent = "Secret key is required";
    return;
  }

  $("#import-error").textContent = "";
  $("#import-submit").disabled = true;
  $("#import-submit").textContent = "Importing...";

  const body = { secretKey };
  if (label) body.label = label;

  const resp = await apiCall("POST", "/wallet/import", body);

  $("#import-submit").disabled = false;
  $("#import-submit").textContent = "Import";

  if (resp.data?.success) {
    if (_activeWallets.length === 0) {
      _activeWallets.push(resp.data.pubkey);
      chrome.storage.local.set({ "slotshark.activeWallets": _activeWallets });
    }
    showToast(`Imported wallet ${truncatePubkey(resp.data.pubkey)}`);
    closeModal("modal-import");
    refreshWallets();
  } else {
    $("#import-error").textContent = resp.data?.error || resp.error || "Import failed";
  }
});

let settingsTarget = { pubkey: "", label: "", nonceCount: 0 };

function openWalletSettings(pubkey, label, nonceCount) {
  settingsTarget = { pubkey, label: label || "", nonceCount };
  const displayLabel = label || truncatePubkey(pubkey);
  $("#ws-wallet-name").textContent = displayLabel;
  const pubkeyEl = $("#ws-wallet-pubkey");
  pubkeyEl.textContent = truncatePubkey(pubkey);
  pubkeyEl.title = "Click to copy";
  pubkeyEl.style.cursor = "pointer";
  pubkeyEl.onclick = async () => {
    try {
      await navigator.clipboard.writeText(pubkey);
      showToast("Address copied to clipboard");
    } catch {
      showToast("Copy failed", "error");
    }
  };
  $("#ws-task-count").textContent = `Current: ${nonceCount} task account${nonceCount !== 1 ? "s" : ""}`;
  $("#ws-deploy-count").value = "3";
  $("#ws-deploy-error").textContent = "";

  $("#ws-delete-section").style.display = "none";
  $("#ws-delete-confirm-label").value = "";
  $("#ws-delete-confirm-label").placeholder = settingsTarget.label || truncatePubkey(pubkey);
  $("#ws-delete-confirm-check").checked = false;
  $("#ws-delete-submit").disabled = true;
  $("#ws-delete-error").textContent = "";

  $("#ws-withdraw-dest").value = "";
  $("#ws-withdraw-amount").value = "";
  $("#ws-withdraw-error").textContent = "";

  openModal("modal-wallet-settings");
}

$("#ws-withdraw-max")?.addEventListener("click", async () => {
  const resp = await apiCall("GET", `/wallet/${settingsTarget.pubkey}/balance`);
  if (resp.data?.success) {
    const max = Math.max(0, resp.data.balanceSol - 0.00090);
    $("#ws-withdraw-amount").value = max.toFixed(5);
  } else {
    showToast("Failed to fetch balance", "error");
  }
});

$("#ws-withdraw-btn")?.addEventListener("click", async () => {
  const dest = $("#ws-withdraw-dest").value.trim();
  const amount = parseFloat($("#ws-withdraw-amount").value);
  if (!dest) { $("#ws-withdraw-error").textContent = "Enter destination address"; return; }
  if (!amount || amount <= 0) { $("#ws-withdraw-error").textContent = "Enter a valid amount"; return; }

  $("#ws-withdraw-error").textContent = "";
  $("#ws-withdraw-btn").disabled = true;
  $("#ws-withdraw-btn").textContent = "Sending...";

  const initResp = await apiCall("POST", "/wallet/withdraw", {
    wallet: settingsTarget.pubkey,
    destination: dest,
    amountSol: amount,
  });

  if (!initResp.data?.success) {
    $("#ws-withdraw-btn").disabled = false;
    $("#ws-withdraw-btn").textContent = "Withdraw";
    $("#ws-withdraw-error").textContent = initResp.data?.error || initResp.error || "Withdrawal failed";
    return;
  }

  const id = initResp.data.id;
  const confirmResp = await apiCall("POST", `/wallet/withdraw/${id}/confirm`);

  $("#ws-withdraw-btn").disabled = false;
  $("#ws-withdraw-btn").textContent = "Withdraw";

  if (confirmResp.data?.success) {
    showToast(`Sent ${amount} SOL to ${dest.slice(0, 8)}...`);
    closeModal("modal-wallet-settings");
    refreshWallets();
  } else {
    $("#ws-withdraw-error").textContent = confirmResp.data?.error || confirmResp.error || "Confirmation failed";
  }
});

$("#ws-deploy-btn").addEventListener("click", async () => {
  const count = parseInt($("#ws-deploy-count").value) || 0;
  if (count < 1 || count > 20) {
    $("#ws-deploy-error").textContent = "Enter a number between 1 and 20";
    return;
  }
  $("#ws-deploy-error").textContent = "";
  $("#ws-deploy-btn").disabled = true;
  $("#ws-deploy-btn").textContent = "Deploying...";

  const resp = await apiCall("POST", `/wallet/${settingsTarget.pubkey}/deploy-nonces`, { count });

  $("#ws-deploy-btn").disabled = false;
  $("#ws-deploy-btn").textContent = "Deploy";

  if (resp.data?.success) {
    showToast(`Deployed ${count} task account${count !== 1 ? "s" : ""} for ${truncatePubkey(settingsTarget.pubkey)}`);
    closeModal("modal-wallet-settings");
    refreshWallets();
  } else {
    $("#ws-deploy-error").textContent = resp.data?.error || resp.error || "Deploy failed";
  }
});

$("#ws-show-delete-btn").addEventListener("click", () => {
  const section = $("#ws-delete-section");
  section.style.display = section.style.display === "none" ? "block" : "none";
});

function validateDeleteForm() {
  const typedLabel = $("#ws-delete-confirm-label").value.trim();
  const expected = settingsTarget.label || truncatePubkey(settingsTarget.pubkey);
  const labelMatch = typedLabel === expected;
  const checked = $("#ws-delete-confirm-check").checked;
  $("#ws-delete-submit").disabled = !(labelMatch && checked);
}

$("#ws-delete-confirm-label").addEventListener("input", validateDeleteForm);
$("#ws-delete-confirm-check").addEventListener("change", validateDeleteForm);

$("#ws-delete-submit").addEventListener("click", async () => {
  $("#ws-delete-submit").disabled = true;
  $("#ws-delete-submit").textContent = "Deleting...";
  $("#ws-delete-error").textContent = "";

  const resp = await apiCall("DELETE", `/wallet/${settingsTarget.pubkey}`);

  $("#ws-delete-submit").textContent = "Delete Wallet";

  if (resp.data?.success) {
    _activeWallets = _activeWallets.filter((p) => p !== settingsTarget.pubkey);
    await chrome.storage.local.set({ "slotshark.activeWallets": _activeWallets });
    showToast(`Deleted wallet ${truncatePubkey(settingsTarget.pubkey)}`);
    closeModal("modal-wallet-settings");
    refreshWallets();
  } else {
    $("#ws-delete-error").textContent = resp.data?.error || resp.error || "Delete failed";
    validateDeleteForm();
  }
});

async function refreshWallets() {
  const meResp = await apiCall("GET", "/auth/me");
  if (meResp.data?.success) {
    cachedWallets = meResp.data.wallets || [];
    await loadWallets(cachedWallets);
  }
}

(async () => {
  const migData = await chrome.storage.local.get(["apiKey", "slotshark.apiKey.nyc"]);
  if (migData.apiKey && !migData["slotshark.apiKey.nyc"]) {
    await chrome.storage.local.set({ "slotshark.apiKey.nyc": migData.apiKey, "slotshark.region": "nyc" });
    await chrome.storage.local.remove("apiKey");
  }

  const regionData = await chrome.storage.local.get("slotshark.region");
  const region = regionData["slotshark.region"] || "nyc";
  const keyName = `slotshark.apiKey.${region}`;
  const keyData = await chrome.storage.local.get(keyName);
  if (!keyData[keyName]) {
    $("#no-auth").style.display = "block";
    return;
  }

  const meResp = await apiCall("GET", "/auth/me");
  if (meResp.error || !meResp.data?.success) {
    $("#no-auth").style.display = "block";
    return;
  }

  $("#main").style.display = "block";

  const REGION_LABELS = { nyc: "US", fra: "EU" };
  const badge = $("#settings-region-badge");
  if (badge) badge.textContent = REGION_LABELS[region] || region.toUpperCase();

  const { userId, tgUsername, isAdmin, wallets } = meResp.data;
  const displayName = tgUsername ? `@${tgUsername}` : userId;
  $("#user-info").textContent = isAdmin ? `${displayName} (admin)` : displayName;
  cachedWallets = wallets || [];

  const walletData = await chrome.storage.local.get(["slotshark.activeWallets", "slotshark.buyDistribution"]);
  _activeWallets = walletData["slotshark.activeWallets"] || [];
  // Drop un-set-up wallets from the active set — auto-add on creation can put
  // wallets without nonces in there, but they can't trade and would fan out
  // doomed buy/sell calls from content scripts.
  const readyPks = new Set(cachedWallets.filter((w) => (w.nonceCount || 0) >= 3).map((w) => w.pubkey));
  const cleaned = _activeWallets.filter((pk) => readyPks.has(pk));
  if (cleaned.length !== _activeWallets.length) {
    _activeWallets = cleaned;
    await chrome.storage.local.set({ "slotshark.activeWallets": _activeWallets });
  }
  const dist = walletData["slotshark.buyDistribution"] || "full";
  const distRadio = document.querySelector(`input[name="buy-distribution"][value="${dist}"]`);
  if (distRadio) distRadio.checked = true;

  $("#settings-logout-btn").addEventListener("click", async () => {
    const rData = await chrome.storage.local.get("slotshark.region");
    const r = rData["slotshark.region"] || "nyc";
    await chrome.storage.local.remove([`slotshark.apiKey.${r}`, "userId"]);
    $("#main").style.display = "none";
    $("#no-auth").style.display = "block";
  });

  await loadWallets(cachedWallets);
  loadSitePreferences();
  loadPresets();
  loadDeveloperTab(region, keyData[keyName]);

  const hash = location.hash.replace("#", "");
  if (hash) {
    const tab = document.querySelector(`.tab[data-tab="${hash}"]`);
    if (tab) tab.click();
  }
})();

const SETTINGS_REGION_BOTS = { nyc: "SlotSharkUS_Bot", fra: "SlotShark_Bot" };
let settingsLoginRegion = "nyc";

document.querySelectorAll("#settings-region-selector .region-btn").forEach((btn) => {
  btn.addEventListener("click", async () => {
    settingsLoginRegion = btn.dataset.region;
    await chrome.storage.local.set({ "slotshark.region": settingsLoginRegion });
    document.querySelectorAll("#settings-region-selector .region-btn").forEach((b) =>
      b.classList.toggle("active", b.dataset.region === settingsLoginRegion)
    );
    const bot = SETTINGS_REGION_BOTS[settingsLoginRegion] || SETTINGS_REGION_BOTS.nyc;
    const codeBtn = $("#settings-get-code-btn");
    if (codeBtn) codeBtn.href = `https://t.me/${bot}?start=login`;
  });
});

(async () => {
  const rd = await chrome.storage.local.get("slotshark.region");
  settingsLoginRegion = rd["slotshark.region"] || "nyc";
  document.querySelectorAll("#settings-region-selector .region-btn").forEach((b) =>
    b.classList.toggle("active", b.dataset.region === settingsLoginRegion)
  );
  const bot = SETTINGS_REGION_BOTS[settingsLoginRegion] || SETTINGS_REGION_BOTS.nyc;
  const codeBtn = $("#settings-get-code-btn");
  if (codeBtn) codeBtn.href = `https://t.me/${bot}?start=login`;
})();

$("#settings-login-btn")?.addEventListener("click", async () => {
  const code = $("#settings-auth-code")?.value?.trim();
  if (!code) {
    $("#settings-login-error").textContent = "Enter the code from Telegram";
    return;
  }

  $("#settings-login-error").textContent = "";
  $("#settings-login-success").textContent = "";
  $("#settings-login-btn").disabled = true;
  $("#settings-login-btn").textContent = "Authenticating...";

  const resp = await apiCall("POST", "/auth/telegram", { code });

  $("#settings-login-btn").disabled = false;
  $("#settings-login-btn").textContent = "Login";

  if (resp.data?.success) {
    const keyName = `slotshark.apiKey.${settingsLoginRegion}`;
    await chrome.storage.local.set({
      [keyName]: resp.data.apiKey,
      userId: resp.data.userId,
      "slotshark.region": settingsLoginRegion,
    });
    $("#settings-login-success").textContent = "Authenticated! Reloading...";
    setTimeout(() => location.reload(), 500);
  } else {
    $("#settings-login-error").textContent = resp.data?.error || resp.error || "Authentication failed";
  }
});

const DEFAULT_SITE_PREFS = {
  axiom: {
    enabled: false,
    features: {
      instantTrade: true,
      pulseQB: true,
      pulsePanel: true,
      watchlist: true,
      walletTracker: true,
    },
  },
};

async function loadSitePreferences() {
  const data = await chrome.storage.local.get([
    "slotshark.sitePreferences", "slotshark.quickBuyAmount",
    "slotshark.quickBuyTip", "slotshark.quickBuyFee", "slotshark.quickBuyAntimev",
  ]);
  const prefs = data["slotshark.sitePreferences"] || DEFAULT_SITE_PREFS;

  const axiomToggle = $("#toggle-axiom");
  if (axiomToggle) {
    axiomToggle.checked = prefs.axiom?.enabled || false;
    const featuresEl = $("#features-axiom");
    if (featuresEl) featuresEl.classList.toggle("open", axiomToggle.checked);
  }

  const features = prefs.axiom?.features || {};
  for (const [key, value] of Object.entries(features)) {
    const el = $(`#feat-axiom-${key}`);
    if (el) el.checked = value;
  }

  const qbaInput = $("#quick-buy-amount-input");
  if (qbaInput) qbaInput.value = data["slotshark.quickBuyAmount"] || 0.5;
  const tipInput = $("#quick-buy-tip-input");
  if (tipInput) tipInput.value = data["slotshark.quickBuyTip"] ?? "";
  const feeInput = $("#quick-buy-fee-input");
  if (feeInput) feeInput.value = data["slotshark.quickBuyFee"] ?? "";
  const amInput = $("#quick-buy-antimev-input");
  if (amInput) amInput.checked = data["slotshark.quickBuyAntimev"] !== false;

}

async function saveSitePreferences() {
  const axiomEnabled = $("#toggle-axiom")?.checked || false;
  const features = {};

  document.querySelectorAll('.feature-check[data-platform="axiom"]').forEach((el) => {
    features[el.dataset.feature] = el.checked;
  });

  const prefs = {
    axiom: {
      enabled: axiomEnabled,
      features,
    },
  };

  await chrome.storage.local.set({ "slotshark.sitePreferences": prefs });
}

document.querySelectorAll(".platform-toggle").forEach((toggle) => {
  toggle.addEventListener("change", () => {
    const platform = toggle.dataset.platform;
    const featuresEl = $(`#features-${platform}`);
    if (featuresEl) featuresEl.classList.toggle("open", toggle.checked);
    saveSitePreferences();
  });
});

document.querySelectorAll(".feature-check").forEach((check) => {
  check.addEventListener("change", () => saveSitePreferences());
});

$("#save-quick-buy-btn")?.addEventListener("click", async () => {
  const amount = parseFloat($("#quick-buy-amount-input")?.value);
  if (!amount || amount <= 0) {
    showToast("Enter a valid SOL amount", "error");
    return;
  }
  const tipVal = $("#quick-buy-tip-input")?.value?.trim();
  const feeVal = $("#quick-buy-fee-input")?.value?.trim();
  const antimev = $("#quick-buy-antimev-input")?.checked ?? true;

  const toSet = {
    "slotshark.quickBuyAmount": amount,
    "slotshark.quickBuyAntimev": antimev,
  };
  if (tipVal && !isNaN(parseFloat(tipVal))) toSet["slotshark.quickBuyTip"] = parseFloat(tipVal);
  else await chrome.storage.local.remove("slotshark.quickBuyTip");
  if (feeVal && !isNaN(parseFloat(feeVal))) toSet["slotshark.quickBuyFee"] = parseFloat(feeVal);
  else await chrome.storage.local.remove("slotshark.quickBuyFee");

  await chrome.storage.local.set(toSet);
  showToast("Quick buy settings saved");
});

$("#save-distribution-btn")?.addEventListener("click", async () => {
  const selected = document.querySelector('input[name="buy-distribution"]:checked');
  const dist = selected?.value || "full";
  await chrome.storage.local.set({ "slotshark.buyDistribution": dist });
  showToast("Buy distribution saved");
});

const PRESET_DEFAULTS = {
  emoji: "\u26A1\uFE0F",
  label: "Preset 1",
  values: {
    "buy-amounts": [0.5, 1, 2, 5],
    "buy-slippage": 20,
    "buy-fee": null,
    "buy-tip": null,
    "buy-anti-mev": true,
    "sell-percents": [10, 25, 50, 100],
    "sell-slippage": 20,
    "sell-fee": null,
    "sell-tip": null,
    "sell-anti-mev": true,
  },
};

const EMOJIS = [
  "\u26A1\uFE0F","\uD83D\uDD25","\uD83C\uDFAF","\uD83D\uDE80","\uD83D\uDC8E","\uD83E\uDD88","\uD83D\uDC0B","\uD83D\uDCB0",
  "\u2B50","\uD83C\uDFB2","\uD83C\uDFC6","\uD83D\uDD2E","\uD83C\uDF0A","\uD83D\uDCA5","\uD83E\uDDCA","\u2744\uFE0F",
  "\u2620\uFE0F","\uD83E\uDD16","\uD83D\uDC51","\uD83D\uDDE1\uFE0F","\uD83D\uDEE1\uFE0F","\uD83D\uDCA3","\uD83C\uDFB0","\uD83E\uDDE0",
];

function generateId() {
  return Array.from(crypto.getRandomValues(new Uint8Array(4)))
    .map((b) => b.toString(16).padStart(2, "0"))
    .join("");
}

let _presets = [];
let _editingPresetId = null;
let _deletingPresetId = null;

async function loadPresets() {
  const data = await chrome.storage.local.get(["slotshark.presets", "slotshark.buyPresets"]);
  let presets = data["slotshark.presets"];

  if (!presets && data["slotshark.buyPresets"]) {
    const oldAmounts = data["slotshark.buyPresets"];
    const migrated = {
      id: generateId(),
      emoji: "\u26A1\uFE0F",
      label: "My Preset",
      values: {
        ...PRESET_DEFAULTS.values,
        "buy-amounts": Array.isArray(oldAmounts) ? oldAmounts : [0.1, 0.25, 0.5, 1.0],
      },
    };
    presets = [migrated];
    await chrome.storage.local.set({
      "slotshark.presets": presets,
      "slotshark.activePreset": migrated.id,
    });
    await chrome.storage.local.remove("slotshark.buyPresets");
  }

  _presets = Array.isArray(presets) ? presets : [];
  renderPresets();
}

async function savePresets() {
  await chrome.storage.local.set({ "slotshark.presets": _presets });
  const data = await chrome.storage.local.get(["slotshark.activePreset"]);
  if (data["slotshark.activePreset"] && !_presets.find((p) => p.id === data["slotshark.activePreset"])) {
    if (_presets.length > 0) {
      await chrome.storage.local.set({ "slotshark.activePreset": _presets[0].id });
    } else {
      await chrome.storage.local.remove("slotshark.activePreset");
    }
  }
  if (!data["slotshark.activePreset"] && _presets.length > 0) {
    await chrome.storage.local.set({ "slotshark.activePreset": _presets[0].id });
  }
}

function renderPresets() {
  const grid = $("#presets-grid");
  const cta = $("#preset-cta");
  const listSection = $("#presets-list-section");
  const emptyState = $("#presets-empty");

  if (_presets.length === 0) {
    cta.style.display = "block";
    listSection.style.display = "none";
    emptyState.style.display = "none";
    return;
  }

  cta.style.display = "none";
  listSection.style.display = "block";
  emptyState.style.display = "none";

  grid.innerHTML = _presets
    .map((p) => {
      const buyPills = (p.values["buy-amounts"] || [])
        .slice(0, 4)
        .map((a) => `<span class="preset-pill"><img class="pill-icon-sol" src="icons/solana.svg" alt="SOL">${a}</span>`)
        .join("");
      const buyMore = (p.values["buy-amounts"] || []).length > 4
        ? `<span class="preset-pill preset-pill-more">+${(p.values["buy-amounts"] || []).length - 4}</span>`
        : "";
      const sellPills = (p.values["sell-percents"] || [])
        .slice(0, 4)
        .map((a) => `<span class="preset-pill">${a}<span class="pill-icon">%</span></span>`)
        .join("");
      const sellMore = (p.values["sell-percents"] || []).length > 4
        ? `<span class="preset-pill preset-pill-more">+${(p.values["sell-percents"] || []).length - 4}</span>`
        : "";

      const tags = [];
      if (p.values["buy-anti-mev"] !== false) tags.push('<span class="preset-tag preset-tag-on">MEV Buy</span>');
      else tags.push('<span class="preset-tag preset-tag-off">MEV Buy</span>');
      if (p.values["sell-anti-mev"] !== false) tags.push('<span class="preset-tag preset-tag-on">MEV Sell</span>');
      else tags.push('<span class="preset-tag preset-tag-off">MEV Sell</span>');

      return `<div class="preset-card" data-preset-id="${escapeHTML(p.id)}">
        <div class="preset-card-header">
          <div class="preset-card-title">
            <div class="preset-card-emoji">${escapeHTML(p.emoji)}</div>
            <div class="preset-card-label">${escapeHTML(p.label)}</div>
          </div>
          <div class="preset-card-actions">
            <button class="edit-btn" data-id="${escapeHTML(p.id)}" title="Edit">\u270F\uFE0F</button>
            <button class="delete-btn" data-id="${escapeHTML(p.id)}" title="Delete">\uD83D\uDDD1\uFE0F</button>
          </div>
        </div>
        <div class="preset-pills">${buyPills}${buyMore}</div>
        <div class="preset-pills">${sellPills}${sellMore}</div>
        <div class="preset-tags">${tags.join("")}</div>
      </div>`;
    })
    .join("");

  grid.querySelectorAll(".edit-btn").forEach((btn) => {
    btn.addEventListener("click", () => openPresetModal(btn.dataset.id));
  });
  grid.querySelectorAll(".delete-btn").forEach((btn) => {
    btn.addEventListener("click", () => openDeletePreset(btn.dataset.id));
  });
}

function openPresetModal(editId) {
  _editingPresetId = editId || null;
  const preset = editId ? _presets.find((p) => p.id === editId) : null;
  const title = preset ? `Edit ${escapeHTML(preset.label)}` : "Create new preset";
  $("#preset-modal-title").textContent = title;

  const v = preset ? preset.values : PRESET_DEFAULTS.values;
  $("#preset-emoji-btn").textContent = preset ? preset.emoji : PRESET_DEFAULTS.emoji;
  $("#preset-label").value = preset ? preset.label : "";

  const buyInputs = document.querySelectorAll(".buy-amount");
  const buyAmounts = v["buy-amounts"] || [];
  buyInputs.forEach((inp, i) => { inp.value = buyAmounts[i] != null && buyAmounts[i] !== 0 ? buyAmounts[i] : ""; });
  const showBuyExtra = buyAmounts.length > 4;
  $("#buy-amounts-extra").style.display = showBuyExtra ? "block" : "none";
  $("#toggle-buy-extra").textContent = showBuyExtra ? "- Show fewer" : "+ Show more amounts";

  const sellInputs = document.querySelectorAll(".sell-amount");
  const sellAmounts = v["sell-percents"] || [];
  sellInputs.forEach((inp, i) => { inp.value = sellAmounts[i] != null && sellAmounts[i] !== 0 ? sellAmounts[i] : ""; });
  const showSellExtra = sellAmounts.length > 4;
  $("#sell-amounts-extra").style.display = showSellExtra ? "block" : "none";
  $("#toggle-sell-extra").textContent = showSellExtra ? "- Show fewer" : "+ Show more amounts";

  $("#preset-buy-slippage").value = v["buy-slippage"] ?? "";
  $("#preset-buy-fee").value = v["buy-fee"] ?? "";
  $("#preset-buy-tip").value = v["buy-tip"] ?? "";
  $("#preset-buy-antimev").checked = v["buy-anti-mev"] !== false;
  $("#preset-sell-slippage").value = v["sell-slippage"] ?? "";
  $("#preset-sell-fee").value = v["sell-fee"] ?? "";
  $("#preset-sell-tip").value = v["sell-tip"] ?? "";
  $("#preset-sell-antimev").checked = v["sell-anti-mev"] !== false;

  updateSaveBtnText();
  checkHighValues();

  openModal("modal-preset");
}

function updateSaveBtnText() {
  const label = $("#preset-label").value.trim();
  $("#preset-save-btn").textContent = label ? `Save "${label}"` : "Save Preset";
}

function collectPresetFromForm() {
  const buyInputs = document.querySelectorAll(".buy-amount");
  const sellInputs = document.querySelectorAll(".sell-amount");

  const buyAmounts = Array.from(buyInputs)
    .map((inp) => parseFloat(inp.value))
    .filter((n) => !isNaN(n) && n > 0);
  const sellPercents = Array.from(sellInputs)
    .map((inp) => parseFloat(inp.value))
    .filter((n) => !isNaN(n) && n > 0 && n <= 100);

  return {
    emoji: $("#preset-emoji-btn").textContent,
    label: $("#preset-label").value.trim(),
    values: {
      "buy-amounts": buyAmounts,
      "buy-slippage": parseFloat($("#preset-buy-slippage").value) || 20,
      "buy-fee": $("#preset-buy-fee").value.trim() ? parseFloat($("#preset-buy-fee").value) : null,
      "buy-tip": $("#preset-buy-tip").value.trim() ? parseFloat($("#preset-buy-tip").value) : null,
      "buy-anti-mev": $("#preset-buy-antimev").checked,
      "sell-percents": sellPercents,
      "sell-slippage": parseFloat($("#preset-sell-slippage").value) || 20,
      "sell-fee": $("#preset-sell-fee").value.trim() ? parseFloat($("#preset-sell-fee").value) : null,
      "sell-tip": $("#preset-sell-tip").value.trim() ? parseFloat($("#preset-sell-tip").value) : null,
      "sell-anti-mev": $("#preset-sell-antimev").checked,
    },
  };
}

async function savePresetFromForm() {
  const data = collectPresetFromForm();

  if (!data.label) { showToast("Preset name is required", "error"); return; }
  if (data.values["buy-amounts"].length === 0) { showToast("At least 1 buy amount required", "error"); return; }
  if (data.values["sell-percents"].length === 0) { showToast("At least 1 sell percent required", "error"); return; }

  const btn = $("#preset-save-btn");
  btn.disabled = true;
  btn.textContent = "Saving...";

  if (_editingPresetId) {
    const idx = _presets.findIndex((p) => p.id === _editingPresetId);
    if (idx !== -1) {
      _presets[idx] = { ..._presets[idx], ...data };
    }
  } else {
    _presets.push({ id: generateId(), ...data });
  }

  await savePresets();
  renderPresets();
  closeModal("modal-preset");
  showToast(_editingPresetId ? "Preset updated!" : "Preset created!", "success");
  btn.disabled = false;
  updateSaveBtnText();
}

function openDeletePreset(id) {
  _deletingPresetId = id;
  const preset = _presets.find((p) => p.id === id);
  if (!preset) return;
  $("#delete-preset-name").textContent = preset.label;
  openModal("modal-delete-preset");
}

async function confirmDeletePreset() {
  if (!_deletingPresetId) return;
  _presets = _presets.filter((p) => p.id !== _deletingPresetId);
  await savePresets();
  renderPresets();
  closeModal("modal-delete-preset");
  showToast("Preset deleted", "success");
  _deletingPresetId = null;
}

function checkHighValues() {
  const buyTip = parseFloat($("#preset-buy-tip").value) || 0;
  const sellTip = parseFloat($("#preset-sell-tip").value) || 0;
  const buyFee = parseFloat($("#preset-buy-fee").value) || 0;
  const sellFee = parseFloat($("#preset-sell-fee").value) || 0;
  $("#buy-tip-warn").style.display = buyTip >= 1 ? "block" : "none";
  $("#sell-tip-warn").style.display = sellTip >= 1 ? "block" : "none";
  $("#buy-fee-warn").style.display = buyFee >= 1 ? "block" : "none";
  $("#sell-fee-warn").style.display = sellFee >= 1 ? "block" : "none";
}

function openEmojiPicker() {
  const popup = $("#emoji-picker-popup");
  const btn = $("#preset-emoji-btn");
  const rect = btn.getBoundingClientRect();

  popup.innerHTML = EMOJIS.map((e) => `<button type="button">${e}</button>`).join("");
  popup.style.display = "grid";
  popup.style.top = rect.bottom + 4 + "px";
  popup.style.left = rect.left + "px";

  popup.querySelectorAll("button").forEach((b) => {
    b.addEventListener("click", () => {
      btn.textContent = b.textContent;
      popup.style.display = "none";
    });
  });

  const close = (e) => {
    if (!popup.contains(e.target) && e.target !== btn) {
      popup.style.display = "none";
      document.removeEventListener("click", close);
    }
  };
  setTimeout(() => document.addEventListener("click", close), 0);
}

["create-preset-btn", "create-preset-btn-2", "create-preset-btn-empty"].forEach((id) => {
  const el = document.getElementById(id);
  if (el) el.addEventListener("click", () => openPresetModal(null));
});

$("#preset-save-btn").addEventListener("click", savePresetFromForm);

$("#delete-preset-confirm").addEventListener("click", confirmDeletePreset);
$("#delete-preset-cancel").addEventListener("click", () => closeModal("modal-delete-preset"));

$("#preset-load-defaults").addEventListener("click", () => {
  const v = PRESET_DEFAULTS.values;
  const buyInputs = document.querySelectorAll(".buy-amount");
  [0.5, 1, 2, 5, 0, 0, 0, 0].forEach((val, i) => { if (buyInputs[i]) buyInputs[i].value = val || ""; });
  const sellInputs = document.querySelectorAll(".sell-amount");
  [10, 25, 50, 100, 0, 0, 0, 0].forEach((val, i) => { if (sellInputs[i]) sellInputs[i].value = val || ""; });
  $("#preset-buy-slippage").value = v["buy-slippage"];
  $("#preset-buy-fee").value = v["buy-fee"] ?? "";
  $("#preset-buy-tip").value = v["buy-tip"] ?? "";
  $("#preset-buy-antimev").checked = v["buy-anti-mev"];
  $("#preset-sell-slippage").value = v["sell-slippage"];
  $("#preset-sell-fee").value = v["sell-fee"] ?? "";
  $("#preset-sell-tip").value = v["sell-tip"] ?? "";
  $("#preset-sell-antimev").checked = v["sell-anti-mev"];
  $("#preset-emoji-btn").textContent = PRESET_DEFAULTS.emoji;
  $("#preset-label").value = PRESET_DEFAULTS.label;
  updateSaveBtnText();
  checkHighValues();
  showToast("Default values loaded", "success");
});

$("#preset-emoji-btn").addEventListener("click", openEmojiPicker);

$("#toggle-buy-extra").addEventListener("click", () => {
  const extra = $("#buy-amounts-extra");
  const show = extra.style.display === "none";
  extra.style.display = show ? "block" : "none";
  if (!show) extra.querySelectorAll("input").forEach((inp) => { inp.value = ""; });
  $("#toggle-buy-extra").textContent = show ? "- Show fewer" : "+ Show more amounts";
});

$("#toggle-sell-extra").addEventListener("click", () => {
  const extra = $("#sell-amounts-extra");
  const show = extra.style.display === "none";
  extra.style.display = show ? "block" : "none";
  if (!show) extra.querySelectorAll("input").forEach((inp) => { inp.value = ""; });
  $("#toggle-sell-extra").textContent = show ? "- Show fewer" : "+ Show more amounts";
});

$("#preset-label").addEventListener("input", updateSaveBtnText);

["preset-buy-tip", "preset-sell-tip", "preset-buy-fee", "preset-sell-fee"].forEach((id) => {
  document.getElementById(id).addEventListener("input", checkHighValues);
});

const DEV_REGIONS = {
  nyc: { url: "https://us.slotshark.xyz", label: "US" },
  fra: { url: "https://eu.slotshark.xyz", label: "EU" },
};

function loadDeveloperTab(region, apiKey) {
  const regionInfo = DEV_REGIONS[region] || DEV_REGIONS.nyc;
  const regionLabel = regionInfo.label;
  const serverUrl = regionInfo.url;

  const devRegionBadge = $("#dev-region-badge");
  if (devRegionBadge) devRegionBadge.textContent = regionLabel;
  const devEndpointRegion = $("#dev-endpoint-region");
  if (devEndpointRegion) devEndpointRegion.textContent = regionLabel;

  const endpointEl = $("#dev-endpoint-url");
  if (endpointEl) endpointEl.textContent = serverUrl;

  const curlUrl = $("#dev-curl-url");
  if (curlUrl) curlUrl.textContent = serverUrl;

  let tokenRevealed = false;

  $("#dev-reveal-btn")?.addEventListener("click", () => {
    if (!apiKey) {
      showToast("No API token found — try re-logging in", "error");
      return;
    }
    $("#dev-token-hidden").style.display = "none";
    $("#dev-token-visible").style.display = "block";
    $("#dev-token-value").textContent = apiKey;
    tokenRevealed = true;
  });

  $("#dev-hide-btn")?.addEventListener("click", () => {
    $("#dev-token-visible").style.display = "none";
    $("#dev-token-hidden").style.display = "block";
    $("#dev-token-value").textContent = "••••••••";
    tokenRevealed = false;
  });

  $("#dev-copy-token-btn")?.addEventListener("click", async () => {
    if (!tokenRevealed || !apiKey) return;
    try {
      await navigator.clipboard.writeText(apiKey);
      showToast("Token copied to clipboard");
    } catch {
      showToast("Copy failed", "error");
    }
  });

  $("#dev-copy-endpoint-btn")?.addEventListener("click", async () => {
    try {
      await navigator.clipboard.writeText(serverUrl);
      showToast("Endpoint copied to clipboard");
    } catch {
      showToast("Copy failed", "error");
    }
  });
}
