/**
 * QuikerLink extension popup — requires config.js (EXTENSION_CONFIG).
 */
document.addEventListener("DOMContentLoaded", async () => {
  const apiBase = EXTENSION_CONFIG.apiBase.replace(/\/$/, "");
  const systemDefault = EXTENSION_CONFIG.systemDefault;

  const loginScreen = document.getElementById("login-screen");
  const mainDashboard = document.getElementById("main-dashboard");
  const statusBar = document.getElementById("status-bar");
  const userDisplay = document.getElementById("user-display");
  const targetUrlInput = document.getElementById("target-url");
  const domainListMain = document.getElementById("domain-list-main");
  const mainDomainLabel = document.getElementById("main-domain-label");
  const brandedOptionsWrap = document.getElementById("branded-options-wrap");
  const defaultDomainSelect = document.getElementById("default-domain-select");
  const resultBox = document.getElementById("result-box");
  const resultLink = document.getElementById("result-link");

  let state = await loadState();
  let currentEditingId = null;
  let statusTimer = null;
  /** @type {{ domain: string, name?: string }[]} */
  let cachedBrandedDomains = [];

  function loadState() {
    return chrome.storage.local.get([
      "apiKey",
      "link1",
      "link2",
      "defaultEditLink",
      "defaultDomain",
      "domainMode",
    ]);
  }

  function normalizeUrl(raw) {
    const trimmed = String(raw || "").trim();
    if (!trimmed) return "";
    if (/^https?:\/\//i.test(trimmed)) return trimmed;
    return `https://${trimmed}`;
  }

  function escapeHtml(str) {
    return String(str)
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;");
  }

  function domainLabel(domain) {
    return String(domain).replace(/^https?:\/\//, "").replace(/\/+$/, "");
  }

  function showStatus(message, type = "info") {
    if (!statusBar) return;
    clearTimeout(statusTimer);
    statusBar.textContent = message;
    statusBar.className = `status-bar visible ${type}`;
    statusTimer = setTimeout(() => {
      statusBar.className = "status-bar";
      statusBar.textContent = "";
    }, type === "error" ? 5000 : 3500);
  }

  async function apiFetch(path, options = {}) {
    state = await loadState();
    if (!state.apiKey) {
      throw new Error("Not signed in");
    }

    const res = await fetch(`${apiBase}${path}`, {
      ...options,
      headers: {
        Authorization: `Bearer ${state.apiKey}`,
        ...(options.body ? { "Content-Type": "application/json" } : {}),
        ...options.headers,
      },
    });

    let data = {};
    try {
      data = await res.json();
    } catch {
      data = { error: 1, message: "Invalid server response" };
    }

    if (!res.ok || Number(data.error) !== 0) {
      throw new Error(data.message || `Request failed (${res.status})`);
    }

    return data;
  }

  async function copyToClipboard(text) {
    try {
      await navigator.clipboard.writeText(text);
      return true;
    } catch {
      const ta = document.createElement("textarea");
      ta.value = text;
      document.body.appendChild(ta);
      ta.select();
      try {
        document.execCommand("copy");
        return true;
      } catch {
        return false;
      } finally {
        document.body.removeChild(ta);
      }
    }
  }

  function flashButton(btn, color, text, originalText, duration = 1500) {
    const originalBg = btn.style.background;
    const originalColor = btn.style.color;
    btn.textContent = text;
    btn.style.background = color;
    if (color === "var(--success)" || String(color).includes("059669")) {
      btn.style.color = "#fff";
    }
    setTimeout(() => {
      btn.textContent = originalText;
      btn.style.background = originalBg;
      btn.style.color = originalColor;
    }, duration);
  }

  function getDomainMode() {
    return state.domainMode === "branded" ? "branded" : "default";
  }

  function getActiveDomain() {
    const mode = getDomainMode();
    if (mode === "branded") {
      const fromSelect = domainListMain?.value;
      if (fromSelect) return fromSelect;
      if (state.defaultDomain) return state.defaultDomain;
      if (cachedBrandedDomains[0]) return cachedBrandedDomains[0].domain;
    }
    return systemDefault;
  }

  /** Always show active domain — never hide (fixes flash-then-vanish). */
  function syncMainUI() {
    if (!mainDomainLabel || !domainListMain) return;

    mainDomainLabel.style.display = "block";
    domainListMain.style.display = "block";

    const mode = getDomainMode();

    if (mode === "branded" && cachedBrandedDomains.length > 0) {
      domainListMain.disabled = false;
      domainListMain.classList.remove("domain-readonly");
      domainListMain.innerHTML = cachedBrandedDomains
        .map(
          (d) =>
            `<option value="${escapeHtml(d.domain)}">${escapeHtml(domainLabel(d.domain))}</option>`
        )
        .join("");

      const preferred = state.defaultDomain || cachedBrandedDomains[0].domain;
      domainListMain.value = cachedBrandedDomains.some((d) => d.domain === preferred)
        ? preferred
        : cachedBrandedDomains[0].domain;
    } else if (mode === "branded") {
      domainListMain.disabled = true;
      domainListMain.classList.add("domain-readonly");
      domainListMain.innerHTML =
        '<option value="">No branded domains — use Settings or system default</option>';
    } else {
      domainListMain.disabled = true;
      domainListMain.classList.add("domain-readonly");
      domainListMain.innerHTML = `<option value="${escapeHtml(systemDefault)}">${escapeHtml(domainLabel(systemDefault))} (system default)</option>`;
    }
  }

  function syncSettingsDomainSelect() {
    if (cachedBrandedDomains.length === 0) {
      defaultDomainSelect.innerHTML = '<option value="">No branded domains available</option>';
      return;
    }
    defaultDomainSelect.innerHTML = cachedBrandedDomains
      .map(
        (d) =>
          `<option value="${escapeHtml(d.domain)}">${escapeHtml(domainLabel(d.domain))}</option>`
      )
      .join("");
    if (state.defaultDomain && cachedBrandedDomains.some((d) => d.domain === state.defaultDomain)) {
      defaultDomainSelect.value = state.defaultDomain;
    }
  }

  async function fetchAccountDetails() {
    try {
      const json = await apiFetch("/account");
      userDisplay.textContent = json.data.email;
    } catch (e) {
      userDisplay.textContent = "Offline";
      showStatus(e.message || "Could not load account", "error");
    }
  }

  function initSettingsUI() {
    if (state.link1) document.getElementById("link1-url").value = state.link1;
    if (state.link2) document.getElementById("link2-url").value = state.link2;
    if (state.defaultEditLink) document.getElementById("global-edit-link").value = state.defaultEditLink;

    const mode = getDomainMode();
    const radio = document.querySelector(`input[name="d-mode"][value="${mode}"]`);
    if (radio) radio.checked = true;
    brandedOptionsWrap.style.display = mode === "branded" ? "block" : "none";
    syncSettingsDomainSelect();
    syncMainUI();
  }

  async function fetchBrandedDomains() {
    try {
      const json = await apiFetch("/domains");
      const systemHost = domainLabel(systemDefault);
      cachedBrandedDomains = (json.data?.domains || []).filter(
        (d) => !String(d.domain).includes(systemHost)
      );

      if (!state.defaultDomain && cachedBrandedDomains[0]) {
        state.defaultDomain = cachedBrandedDomains[0].domain;
        await chrome.storage.local.set({ defaultDomain: state.defaultDomain });
      }

      syncSettingsDomainSelect();
      syncMainUI();
    } catch (e) {
      showStatus(e.message || "Could not load domains", "error");
      syncMainUI();
    }
  }

  async function fetchLinks() {
    const container = document.getElementById("links-container");
    container.innerHTML = `<p class="empty-state">Loading…</p>`;
    try {
      const json = await apiFetch("/urls?limit=30&order=date");
      const urls = json.data?.urls || [];

      if (urls.length === 0) {
        container.innerHTML = `<p class="empty-state">No links yet. Create one on the Shorten tab.</p>`;
        return;
      }

      container.innerHTML = urls
        .map((u) => {
          const dMatch = u.shorturl.match(/^https?:\/\/[^/]+/);
          const currentDom = dMatch ? dMatch[0] : systemDefault;
          return `
            <article class="link-item">
              <div class="link-short">${escapeHtml(u.shorturl)}</div>
              <div class="link-long">${escapeHtml(u.longurl)}</div>
              <div class="action-group">
                <button type="button" class="btn-sm btn-auto" data-id="${escapeHtml(u.id)}" data-domain="${escapeHtml(currentDom)}">Auto fix</button>
                <button type="button" class="btn-sm btn-edit btn-edit-url" data-id="${escapeHtml(u.id)}" data-url="${escapeHtml(u.longurl)}" data-domain="${escapeHtml(currentDom)}">Edit</button>
                <button type="button" class="btn-sm btn-copy" data-short="${escapeHtml(u.shorturl)}">Copy</button>
                <button type="button" class="btn-sm btn-delete" data-id="${escapeHtml(u.id)}">Del</button>
              </div>
            </article>`;
        })
        .join("");
    } catch (e) {
      container.innerHTML = `<p class="empty-state">${escapeHtml(e.message || "Sync error")}</p>`;
    }
  }

  document.querySelectorAll('input[name="d-mode"]').forEach((radio) => {
    radio.addEventListener("change", async (e) => {
      const mode = e.target.value;
      brandedOptionsWrap.style.display = mode === "branded" ? "block" : "none";
      state.domainMode = mode;
      await chrome.storage.local.set({ domainMode: mode });
      syncMainUI();
    });
  });

  domainListMain.addEventListener("change", async () => {
    if (getDomainMode() !== "branded" || domainListMain.disabled) return;
    state.defaultDomain = domainListMain.value;
    await chrome.storage.local.set({ defaultDomain: state.defaultDomain });
    if (defaultDomainSelect) {
      defaultDomainSelect.value = state.defaultDomain;
    }
  });

  document.querySelectorAll(".tab").forEach((tab) => {
    tab.addEventListener("click", () => {
      document.querySelectorAll(".tab").forEach((t) => t.classList.remove("active"));
      tab.classList.add("active");
      const targetId = tab.getAttribute("data-target");
      ["create-sec", "links-sec", "settings-sec"].forEach((id) => {
        document.getElementById(id).style.display = id === targetId ? "block" : "none";
      });
      if (targetId === "links-sec") fetchLinks();
      if (targetId === "settings-sec") fetchBrandedDomains();
    });
  });

  document.getElementById("shorten-btn").addEventListener("click", async function () {
    const raw = targetUrlInput.value.trim();
    if (!raw) {
      showStatus("Enter a URL to shorten", "error");
      return;
    }

    const url = normalizeUrl(raw);
    const btn = this;
    const originalText = btn.textContent;
    btn.disabled = true;
    btn.textContent = "Creating…";
    resultBox.classList.remove("visible");

    const useDomain = getActiveDomain();
    if (getDomainMode() === "branded" && !useDomain) {
      showStatus("Choose a branded domain in Settings", "error");
      btn.disabled = false;
      btn.textContent = originalText;
      return;
    }

    try {
      const data = await apiFetch("/url/add", {
        method: "POST",
        body: JSON.stringify({ url, domain: useDomain, rand: 1 }),
      });

      const shorturl = data.shorturl || data.data?.shorturl;
      if (!shorturl) {
        throw new Error("No short URL returned");
      }

      resultLink.href = shorturl;
      resultLink.textContent = shorturl;
      resultBox.classList.add("visible");

      const copied = await copyToClipboard(shorturl);
      showStatus(copied ? "Short link created and copied!" : "Short link created!", "success");
      targetUrlInput.value = "";
    } catch (e) {
      showStatus(e.message || "Failed to shorten URL", "error");
    } finally {
      btn.disabled = false;
      btn.textContent = originalText;
    }
  });

  document.getElementById("save-settings").addEventListener("click", async function () {
    const mode = document.querySelector('input[name="d-mode"]:checked').value;
    const defDom =
      mode === "branded"
        ? defaultDomainSelect.value || cachedBrandedDomains[0]?.domain || ""
        : systemDefault;
    const l1 = document.getElementById("link1-url").value.trim();
    const l2 = document.getElementById("link2-url").value.trim();
    const fix = document.getElementById("global-edit-link").value.trim();

    await chrome.storage.local.set({
      domainMode: mode,
      defaultDomain: defDom,
      link1: l1,
      link2: l2,
      defaultEditLink: fix,
    });

    state = await loadState();
    brandedOptionsWrap.style.display = mode === "branded" ? "block" : "none";
    syncMainUI();
    showStatus("Settings saved", "success");
    flashButton(this, "var(--success)", "Saved!", "Save settings");
  });

  document.getElementById("links-container").addEventListener("click", async (e) => {
    const t = e.target.closest("button");
    if (!t) return;

    if (t.classList.contains("btn-copy")) {
      await copyToClipboard(t.dataset.short);
      flashButton(t, "var(--success)", "Done", "Copy");
      showStatus("Copied to clipboard", "success");
      return;
    }

    if (t.classList.contains("btn-delete")) {
      try {
        await apiFetch(`/url/${t.dataset.id}/delete`, { method: "DELETE" });
        showStatus("Link deleted", "success");
        fetchLinks();
      } catch (err) {
        showStatus(err.message, "error");
      }
      return;
    }

    if (t.classList.contains("btn-auto")) {
      state = await loadState();
      if (!state.defaultEditLink) {
        showStatus("Set auto-fix URL in Settings first", "error");
        return;
      }
      t.textContent = "…";
      try {
        await apiFetch(`/url/${t.dataset.id}/update`, {
          method: "PUT",
          body: JSON.stringify({
            url: normalizeUrl(state.defaultEditLink),
            domain: t.dataset.domain,
          }),
        });
        showStatus("Link updated", "success");
        fetchLinks();
      } catch (err) {
        showStatus(err.message, "error");
        t.textContent = "Auto fix";
      }
      return;
    }

    if (t.classList.contains("btn-edit-url")) {
      currentEditingId = t.dataset.id;
      document.getElementById("edit-url-input").value = t.dataset.url;
      document.getElementById("edit-url-input").dataset.domain = t.dataset.domain;
      document.getElementById("edit-overlay").style.display = "flex";
    }
  });

  document.getElementById("confirm-edit-btn").addEventListener("click", async () => {
    const input = document.getElementById("edit-url-input");
    const url = normalizeUrl(input.value);
    if (!url) {
      showStatus("Enter a valid URL", "error");
      return;
    }
    try {
      await apiFetch(`/url/${currentEditingId}/update`, {
        method: "PUT",
        body: JSON.stringify({ url, domain: input.dataset.domain }),
      });
      document.getElementById("edit-overlay").style.display = "none";
      showStatus("Link updated", "success");
      fetchLinks();
    } catch (e) {
      showStatus(e.message, "error");
    }
  });

  document.getElementById("bulk-delete-btn").addEventListener("click", async function () {
    if (!confirm("Delete all your short links?")) return;
    const btn = this;
    btn.disabled = true;
    btn.textContent = "Cleaning…";
    try {
      const json = await apiFetch("/urls?limit=50");
      const urls = json.data?.urls || [];
      for (const u of urls) {
        await apiFetch(`/url/${u.id}/delete`, { method: "DELETE" });
      }
      showStatus("All links cleared", "success");
      fetchLinks();
    } catch (e) {
      showStatus(e.message, "error");
    } finally {
      btn.disabled = false;
      btn.textContent = "Clear all links";
    }
  });

  document.getElementById("cancel-edit-btn").addEventListener("click", () => {
    document.getElementById("edit-overlay").style.display = "none";
  });

  document.getElementById("use-link1").addEventListener("click", async () => {
    state = await loadState();
    if (state.link1) targetUrlInput.value = state.link1;
    else showStatus("Set Preset 1 in Settings", "error");
  });

  document.getElementById("use-link2").addEventListener("click", async () => {
    state = await loadState();
    if (state.link2) targetUrlInput.value = state.link2;
    else showStatus("Set Preset 2 in Settings", "error");
  });

  document.getElementById("logout-btn").addEventListener("click", async () => {
    await chrome.storage.local.clear();
    location.reload();
  });

  function showLoginStatus(message, type = "error") {
    const el = document.getElementById("login-status");
    if (!el) return;
    el.textContent = message;
    el.className = `status-bar visible ${type}`;
  }

  document.getElementById("login-submit-btn").addEventListener("click", async () => {
    const key = document.getElementById("api-key-input").value.trim();
    if (!key) {
      showLoginStatus("Enter your API key", "error");
      return;
    }
    if (!key.startsWith("ls_")) {
      showLoginStatus("API key should start with ls_", "error");
      return;
    }
    await chrome.storage.local.set({ apiKey: key });
    location.reload();
  });

  if (!state.apiKey) {
    loginScreen.style.display = "flex";
    mainDashboard.style.display = "none";
  } else {
    loginScreen.style.display = "none";
    mainDashboard.style.display = "flex";
    syncMainUI();
    await Promise.all([fetchAccountDetails(), fetchBrandedDomains()]);
    initSettingsUI();
  }
});
