const urlsInput = document.getElementById("urls");
const checkBtn = document.getElementById("checkBtn");
const loadFileBtn = document.getElementById("loadFileBtn");
const urlFile = document.getElementById("urlFile");
const resultsBody = document.getElementById("resultsBody");
const reportBody = document.getElementById("reportBody");
const appsList = document.getElementById("appsList");
const appHistoryBody = document.getElementById("appHistoryBody");
const reportDetails = document.getElementById("reportDetails");
const screenshotsGrid = document.getElementById("screenshotsGrid");
const statusText = document.getElementById("statusText");
const appName = document.getElementById("appName");
const loginEnabled = document.getElementById("loginEnabled");
const loginUrl = document.getElementById("loginUrl");
const username = document.getElementById("username");
const password = document.getElementById("password");
const refreshAppsBtn = document.getElementById("refreshAppsBtn");
const refreshReportsBtn = document.getElementById("refreshReportsBtn");
const autoDiscover = document.getElementById("autoDiscover");
const discoverFrom = document.getElementById("discoverFrom");
const maxDiscoverPages = document.getElementById("maxDiscoverPages");
const exportCsvBtn = document.getElementById("exportCsvBtn");
const exportPdfBtn = document.getElementById("exportPdfBtn");
const refreshScreenshotsBtn = document.getElementById("refreshScreenshotsBtn");
const bulkDeleteAppsBtn = document.getElementById("bulkDeleteAppsBtn");
const bulkDeleteReportsBtn = document.getElementById("bulkDeleteReportsBtn");
const bulkDeleteShotsBtn = document.getElementById("bulkDeleteShotsBtn");
const selectAllAppsBtn = document.getElementById("selectAllAppsBtn");
const clearAppsSelectionBtn = document.getElementById("clearAppsSelectionBtn");
const selectAllReportsBtn = document.getElementById("selectAllReportsBtn");
const clearReportsSelectionBtn = document.getElementById("clearReportsSelectionBtn");
const selectAllShotsBtn = document.getElementById("selectAllShotsBtn");
const clearShotsSelectionBtn = document.getElementById("clearShotsSelectionBtn");
const themeToggle = document.getElementById("themeToggle");
const navButtons = document.querySelectorAll(".nav-btn");
const views = document.querySelectorAll(".view");

let latestReports = [];
let selectedAppSlug = "";
let selectedAppSlugs = new Set();
let selectedRunIds = new Set();
let selectedImageUrls = new Set();

function escapeHtml(value) {
  return String(value)
    .replaceAll("&", "&amp;")
    .replaceAll("<", "&lt;")
    .replaceAll(">", "&gt;")
    .replaceAll('"', "&quot;")
    .replaceAll("'", "&#039;");
}

function renderResults(results) {
  if (!results.length) {
    resultsBody.innerHTML = `<tr><td colspan="8" class="muted">No results found.</td></tr>`;
    return;
  }

  resultsBody.innerHTML = results
    .map((item, index) => {
      const state = item.is_working ? "PASS" : "ISSUE";
      const stateClass = item.is_working ? "good" : "bad";
      const code = item.status_code ?? "-";
      const responseTime = item.response_time_ms != null ? `${item.response_time_ms} ms` : "-";
      const issue = item.issue ? escapeHtml(item.issue) : "-";
      const uiSummary = item.ui_summary ? escapeHtml(item.ui_summary) : "-";
      const screenshot = item.screenshot
        ? `<a href="${item.screenshot}" target="_blank" rel="noopener noreferrer">View</a>`
        : "-";

      return `
        <tr>
          <td>${index + 1}</td>
          <td><a href="${escapeHtml(item.normalized_url)}" target="_blank" rel="noopener noreferrer">${escapeHtml(item.normalized_url)}</a></td>
          <td><span class="pill ${stateClass}">${state}</span></td>
          <td>${code}</td>
          <td>${responseTime}</td>
          <td>${issue}</td>
          <td>${uiSummary}</td>
          <td>${screenshot}</td>
        </tr>
      `;
    })
    .join("");
}

function parseUrlFile(rawText) {
  return rawText
    .split(/\r?\n|,/g)
    .map((line) => line.trim())
    .filter((line) => line && line.toLowerCase() !== "url");
}

async function loadUrlsFromFile() {
  const file = urlFile.files?.[0];
  if (!file) {
    statusText.textContent = "Select a .txt or .csv file first.";
    return;
  }
  const text = await file.text();
  const urls = parseUrlFile(text);
  urlsInput.value = urls.join("\n");
  statusText.textContent = `Loaded ${urls.length} URL(s) from file.`;
}

function renderApps(apps) {
  if (!apps.length) {
    appsList.innerHTML = `<p class="muted">No applications tested yet.</p>`;
    appHistoryBody.innerHTML = `<tr><td colspan="4" class="muted">No history available.</td></tr>`;
    return;
  }
  appsList.innerHTML = apps
    .map(
      (app) => `
      <article class="mini-card app-card" data-app-slug="${escapeHtml(app.app_slug || "")}">
        <label class="checkbox-row">
          <input type="checkbox" class="app-select-checkbox" data-app-slug="${escapeHtml(app.app_slug || "")}">
          <span>Select</span>
        </label>
        <h4>${escapeHtml(app.app_name)}</h4>
        <p>Runs: <strong>${app.runs}</strong></p>
        <p class="muted">Last run: ${escapeHtml(app.last_run_at || "-")}</p>
        <button class="secondary danger app-delete-btn" data-app-slug="${escapeHtml(app.app_slug || "")}">Delete App Data</button>
      </article>
    `,
    )
    .join("");
  document.querySelectorAll(".app-card").forEach((card) => {
    card.addEventListener("click", async () => {
      selectedAppSlug = card.dataset.appSlug || "";
      await refreshReports(selectedAppSlug);
      await refreshScreenshots(selectedAppSlug);
      renderAppHistory(latestReports);
      setView("appsView");
    });
  });
  document.querySelectorAll(".app-select-checkbox").forEach((input) => {
    input.checked = selectedAppSlugs.has(input.dataset.appSlug || "");
    input.addEventListener("click", (event) => event.stopPropagation());
    input.addEventListener("change", () => {
      const slug = input.dataset.appSlug || "";
      if (!slug) return;
      if (input.checked) selectedAppSlugs.add(slug);
      else selectedAppSlugs.delete(slug);
    });
  });
  document.querySelectorAll(".app-delete-btn").forEach((btn) => {
    btn.addEventListener("click", async (event) => {
      event.stopPropagation();
      const appSlug = btn.dataset.appSlug || "";
      if (!appSlug) return;
      const ok = window.confirm("Delete this application's full history and screenshots?");
      if (!ok) return;
      const response = await fetch(`/api/apps/${encodeURIComponent(appSlug)}`, { method: "DELETE" });
      const payload = await response.json();
      if (!response.ok) {
        statusText.textContent = `Error: ${payload.error || "Failed to delete app history"}`;
        return;
      }
      if (selectedAppSlug === appSlug) {
        selectedAppSlug = "";
      }
      await Promise.all([refreshApps(), refreshReports(selectedAppSlug), refreshScreenshots(selectedAppSlug)]);
      renderAppHistory(selectedAppSlug ? latestReports : []);
      statusText.textContent = "Application history deleted.";
    });
  });
}

function renderAppHistory(reports) {
  if (!reports.length) {
    appHistoryBody.innerHTML = `<tr><td colspan="4" class="muted">No history for selected application.</td></tr>`;
    return;
  }
  appHistoryBody.innerHTML = reports
    .map(
      (row) => `
      <tr>
        <td>${escapeHtml(row.run_at || "-")}</td>
        <td>${row.total_urls ?? "-"}</td>
        <td>${row.working_urls ?? "-"}</td>
        <td>${row.issue_urls ?? "-"}</td>
      </tr>
    `,
    )
    .join("");
}

function renderReports(reports) {
  if (!reports.length) {
    reportBody.innerHTML = `<tr><td colspan="6" class="muted">No reports yet.</td></tr>`;
    reportDetails.innerHTML = `<p class="muted">No report details available.</p>`;
    return;
  }
  reportBody.innerHTML = reports
    .map(
      (row) => `
      <tr>
        <td>${escapeHtml(row.run_at || "-")}</td>
        <td>${escapeHtml(row.app_name || "-")}</td>
        <td>${row.total_urls ?? "-"}</td>
        <td>${row.working_urls ?? "-"}</td>
        <td>${row.issue_urls ?? "-"}</td>
        <td>
          <label class="checkbox-row inline">
            <input type="checkbox" class="report-select-checkbox" data-run-id="${escapeHtml(row.id || "")}">
            <span>Select</span>
          </label>
          <button class="secondary report-view-btn" data-run-id="${escapeHtml(row.id || "")}">View</button>
          <button class="secondary danger report-delete-btn" data-run-id="${escapeHtml(row.id || "")}">Delete</button>
        </td>
      </tr>
    `,
    )
    .join("");
  document.querySelectorAll(".report-view-btn").forEach((btn) => {
    btn.addEventListener("click", async () => {
      const runId = btn.dataset.runId || "";
      if (runId) {
        await viewRunDetails(runId);
      }
    });
  });
  document.querySelectorAll(".report-select-checkbox").forEach((input) => {
    input.checked = selectedRunIds.has(input.dataset.runId || "");
    input.addEventListener("change", () => {
      const runId = input.dataset.runId || "";
      if (!runId) return;
      if (input.checked) selectedRunIds.add(runId);
      else selectedRunIds.delete(runId);
    });
  });
  document.querySelectorAll(".report-delete-btn").forEach((btn) => {
    btn.addEventListener("click", async () => {
      const runId = btn.dataset.runId || "";
      if (!runId) return;
      const ok = window.confirm("Delete this report run and its screenshots?");
      if (!ok) return;
      const response = await fetch(`/api/report/${encodeURIComponent(runId)}`, { method: "DELETE" });
      const payload = await response.json();
      if (!response.ok) {
        statusText.textContent = `Error: ${payload.error || "Failed to delete run"}`;
        return;
      }
      await Promise.all([refreshApps(), refreshReports(selectedAppSlug), refreshScreenshots(selectedAppSlug)]);
      renderAppHistory(selectedAppSlug ? latestReports : []);
      reportDetails.innerHTML = `<p class="muted">Run deleted successfully.</p>`;
    });
  });
  reportDetails.innerHTML = reports
    .slice(0, 10)
    .map((run) => {
      const details = (run.results || [])
        .map(
          (item, idx) => `
          <tr>
            <td>${idx + 1}</td>
            <td><a href="${escapeHtml(item.normalized_url || item.url || "-")}" target="_blank" rel="noopener noreferrer">${escapeHtml(item.normalized_url || item.url || "-")}</a></td>
            <td>${item.is_working ? "PASS" : "ISSUE"}</td>
            <td>${item.status_code ?? "-"}</td>
            <td>${escapeHtml(item.issue || "None")}</td>
            <td>${item.screenshot ? `<a href="${item.screenshot}" target="_blank" rel="noopener noreferrer">Open</a>` : "-"}</td>
          </tr>
        `,
        )
        .join("");
      return `
      <article class="mini-card">
        <h4>${escapeHtml(run.app_name || "-")} - ${escapeHtml(run.run_at || "-")}</h4>
        <p>Total: ${run.total_urls ?? 0}, PASS: ${run.working_urls ?? 0}, ISSUE: ${run.issue_urls ?? 0}</p>
        <div class="table-wrap">
          <table>
            <thead>
              <tr>
                <th>#</th>
                <th>URL</th>
                <th>Status</th>
                <th>HTTP</th>
                <th>Issue</th>
                <th>Screenshot</th>
              </tr>
            </thead>
            <tbody>${details || `<tr><td colspan="6" class="muted">No URL details.</td></tr>`}</tbody>
          </table>
        </div>
      </article>
      `;
    })
    .join("");
}

async function viewRunDetails(runId) {
  const response = await fetch(`/api/report/${encodeURIComponent(runId)}`);
  const payload = await response.json();
  if (!response.ok) {
    reportDetails.innerHTML = `<p class="muted">Failed to load run details.</p>`;
    return;
  }
  const run = payload.run;
  const items = run.results || [];
  reportDetails.innerHTML = `
    <article class="mini-card">
      <h4>${escapeHtml(run.app_name || "-")} — ${escapeHtml(run.run_at || "-")}</h4>
      <p>Total: ${run.total_urls ?? 0}, PASS: ${run.working_urls ?? 0}, ISSUE: ${run.issue_urls ?? 0}</p>
      <div class="detail-list">
        ${items
          .map((item) => {
            const issue = item.issue ? escapeHtml(item.issue) : "None";
            const ui = item.ui_summary ? escapeHtml(item.ui_summary) : "-";
            const shot = item.screenshot
              ? `<a href="${item.screenshot}" target="_blank" rel="noopener noreferrer">View screenshot</a>`
              : "<span class='muted'>No screenshot</span>";
            return `
              <div class="detail-item">
                <p><strong>${escapeHtml(item.normalized_url || item.url || "-")}</strong></p>
                <p>Status: ${item.is_working ? "PASS" : "ISSUE"} | HTTP: ${item.status_code ?? "-"}</p>
                <p><strong>Exact issue:</strong> ${issue}</p>
                <p class="muted">${ui}</p>
                ${shot}
              </div>
            `;
          })
          .join("")}
      </div>
    </article>
  `;
}

function renderScreenshots(items) {
  if (!items.length) {
    screenshotsGrid.innerHTML = `<p class="muted">No screenshots found.</p>`;
    return;
  }
  const grouped = {};
  items.forEach((shot) => {
    const app = shot.app_slug || "default-app";
    const site = shot.site_slug || "unknown-site";
    if (!grouped[app]) grouped[app] = {};
    if (!grouped[app][site]) grouped[app][site] = [];
    grouped[app][site].push(shot);
  });

  screenshotsGrid.innerHTML = Object.entries(grouped)
    .map(([app, sites]) => {
      const siteBlocks = Object.entries(sites)
        .map(([site, shots]) => {
          const rows = shots
            .map(
              (shot, idx) => `
                <tr>
                  <td>
                    <label class="checkbox-row inline">
                      <input type="checkbox" class="shot-select-checkbox" data-image-url="${escapeHtml(shot.image_url)}">
                      <span>${idx + 1}</span>
                    </label>
                  </td>
                  <td>${shot.url ? `<a href="${escapeHtml(shot.url)}" target="_blank" rel="noopener noreferrer">${escapeHtml(shot.url)}</a>` : "-"}</td>
                  <td>${escapeHtml(shot.issue || "None")}</td>
                  <td>${escapeHtml(shot.modified_at || "-")}</td>
                  <td><a href="${shot.image_url}" target="_blank" rel="noopener noreferrer">Open</a></td>
                  <td><button class="secondary danger shot-delete-btn" data-image-url="${escapeHtml(shot.image_url)}">Delete</button></td>
                </tr>
              `,
            )
            .join("");
          return `
            <article class="mini-card folder-card">
              <h4>Website Folder: ${escapeHtml(site)}</h4>
              <div class="table-wrap">
                <table>
                  <thead>
                    <tr>
                      <th>#</th>
                      <th>URL</th>
                      <th>Issue</th>
                      <th>Time</th>
                      <th>View</th>
                      <th>Action</th>
                    </tr>
                  </thead>
                  <tbody>${rows}</tbody>
                </table>
              </div>
            </article>
          `;
        })
        .join("");

      return `
        <section class="app-folder-block">
          <h3>Application Folder: ${escapeHtml(app)}</h3>
          ${siteBlocks}
        </section>
      `;
    })
    .join("");

  document.querySelectorAll(".shot-delete-btn").forEach((btn) => {
    btn.addEventListener("click", async () => {
      const imageUrl = btn.dataset.imageUrl || "";
      if (!imageUrl) return;
      const ok = window.confirm("Delete this screenshot?");
      if (!ok) return;
      const response = await fetch("/api/screenshots", {
        method: "DELETE",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ image_url: imageUrl }),
      });
      const payload = await response.json();
      if (!response.ok) {
        statusText.textContent = `Error: ${payload.error || "Failed to delete screenshot"}`;
        return;
      }
      await refreshScreenshots(selectedAppSlug);
      statusText.textContent = "Screenshot deleted.";
    });
  });
  document.querySelectorAll(".shot-select-checkbox").forEach((input) => {
    input.checked = selectedImageUrls.has(input.dataset.imageUrl || "");
    input.addEventListener("change", () => {
      const imageUrl = input.dataset.imageUrl || "";
      if (!imageUrl) return;
      if (input.checked) selectedImageUrls.add(imageUrl);
      else selectedImageUrls.delete(imageUrl);
    });
  });
}

function selectAllApps() {
  document.querySelectorAll(".app-select-checkbox").forEach((input) => {
    const slug = input.dataset.appSlug || "";
    if (!slug) return;
    input.checked = true;
    selectedAppSlugs.add(slug);
  });
}

function clearAppsSelection() {
  document.querySelectorAll(".app-select-checkbox").forEach((input) => {
    input.checked = false;
  });
  selectedAppSlugs.clear();
}

function selectAllReports() {
  document.querySelectorAll(".report-select-checkbox").forEach((input) => {
    const runId = input.dataset.runId || "";
    if (!runId) return;
    input.checked = true;
    selectedRunIds.add(runId);
  });
}

function clearReportsSelection() {
  document.querySelectorAll(".report-select-checkbox").forEach((input) => {
    input.checked = false;
  });
  selectedRunIds.clear();
}

function selectAllShots() {
  document.querySelectorAll(".shot-select-checkbox").forEach((input) => {
    const imageUrl = input.dataset.imageUrl || "";
    if (!imageUrl) return;
    input.checked = true;
    selectedImageUrls.add(imageUrl);
  });
}

function clearShotsSelection() {
  document.querySelectorAll(".shot-select-checkbox").forEach((input) => {
    input.checked = false;
  });
  selectedImageUrls.clear();
}

async function bulkDeleteApps() {
  if (!selectedAppSlugs.size) {
    statusText.textContent = "Select at least one app.";
    return;
  }
  if (!window.confirm(`Delete ${selectedAppSlugs.size} selected app(s) with all history/screenshots?`)) return;
  const response = await fetch("/api/apps/bulk-delete", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ app_slugs: Array.from(selectedAppSlugs) }),
  });
  const payload = await response.json();
  if (!response.ok) {
    statusText.textContent = `Error: ${payload.error || "Bulk delete failed"}`;
    return;
  }
  selectedAppSlugs.clear();
  selectedAppSlug = "";
  await Promise.all([refreshApps(), refreshReports(), refreshScreenshots()]);
  renderAppHistory([]);
  statusText.textContent = "Selected applications deleted.";
}

async function bulkDeleteReports() {
  if (!selectedRunIds.size) {
    statusText.textContent = "Select at least one report run.";
    return;
  }
  if (!window.confirm(`Delete ${selectedRunIds.size} selected run(s)?`)) return;
  const response = await fetch("/api/report/bulk-delete", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ run_ids: Array.from(selectedRunIds) }),
  });
  const payload = await response.json();
  if (!response.ok) {
    statusText.textContent = `Error: ${payload.error || "Bulk delete failed"}`;
    return;
  }
  selectedRunIds.clear();
  await Promise.all([refreshApps(), refreshReports(selectedAppSlug), refreshScreenshots(selectedAppSlug)]);
  renderAppHistory(selectedAppSlug ? latestReports : []);
  reportDetails.innerHTML = `<p class="muted">Selected runs deleted.</p>`;
}

async function bulkDeleteScreenshots() {
  if (!selectedImageUrls.size) {
    statusText.textContent = "Select at least one screenshot.";
    return;
  }
  if (!window.confirm(`Delete ${selectedImageUrls.size} selected screenshot(s)?`)) return;
  const response = await fetch("/api/screenshots/bulk-delete", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ image_urls: Array.from(selectedImageUrls) }),
  });
  const payload = await response.json();
  if (!response.ok) {
    statusText.textContent = `Error: ${payload.error || "Bulk delete failed"}`;
    return;
  }
  selectedImageUrls.clear();
  await refreshScreenshots(selectedAppSlug);
  statusText.textContent = `Deleted ${payload.deleted || 0} screenshots.`;
}

async function refreshApps() {
  const response = await fetch("/api/apps");
  const payload = await response.json();
  renderApps(payload.apps || []);
}

async function refreshReports(appSlug = "") {
  const query = appSlug ? `?app_slug=${encodeURIComponent(appSlug)}` : "";
  const response = await fetch(`/api/report${query}`);
  const payload = await response.json();
  latestReports = payload.reports || [];
  renderReports(latestReports);
}

async function refreshScreenshots(appSlug = "") {
  const query = appSlug ? `?app_slug=${encodeURIComponent(appSlug)}` : "";
  const response = await fetch(`/api/screenshots${query}`);
  const payload = await response.json();
  renderScreenshots(payload.screenshots || []);
}

function setView(viewId) {
  views.forEach((view) => view.classList.toggle("active", view.id === viewId));
  navButtons.forEach((btn) => btn.classList.toggle("active", btn.dataset.view === viewId));
}

function exportCsv() {
  if (!latestReports.length) {
    statusText.textContent = "No report data to export.";
    return;
  }
  const rows = [["Run Time", "Application", "Total", "PASS", "ISSUE"]];
  latestReports.forEach((run) => {
    rows.push([run.run_at || "", run.app_name || "", run.total_urls || 0, run.working_urls || 0, run.issue_urls || 0]);
  });
  const csv = rows.map((r) => r.map((v) => `"${String(v).replaceAll('"', '""')}"`).join(",")).join("\n");
  const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
  const link = document.createElement("a");
  link.href = URL.createObjectURL(blob);
  link.download = "gventuretest-report.csv";
  link.click();
  URL.revokeObjectURL(link.href);
}

function exportPdf() {
  if (!latestReports.length) {
    statusText.textContent = "No report data to export.";
    return;
  }
  const { jsPDF } = window.jspdf;
  const doc = new jsPDF();
  let y = 15;
  doc.setFontSize(14);
  doc.text("gventuretest Report", 14, y);
  y += 8;
  doc.setFontSize(10);
  latestReports.forEach((run, index) => {
    const line = `${index + 1}. ${run.run_at || "-"} | ${run.app_name || "-"} | total=${run.total_urls || 0}, pass=${run.working_urls || 0}, issue=${run.issue_urls || 0}`;
    doc.text(line, 14, y);
    y += 6;
    if (y > 280) {
      doc.addPage();
      y = 15;
    }
  });
  doc.save("gventuretest-report.pdf");
}

function initTheme() {
  const saved = localStorage.getItem("gventuretest-theme") || "light";
  document.body.classList.toggle("soft-dark", saved === "dark");
  themeToggle.textContent = saved === "dark" ? "Soft Light" : "Soft Dark";
}

function toggleTheme() {
  const isDark = document.body.classList.toggle("soft-dark");
  localStorage.setItem("gventuretest-theme", isDark ? "dark" : "light");
  themeToggle.textContent = isDark ? "Soft Light" : "Soft Dark";
}

async function checkUrls() {
  let urls = urlsInput.value
    .split("\n")
    .map((u) => u.trim())
    .filter(Boolean);

  const isAutoDiscover = autoDiscover.checked;
  if (!urls.length && !isAutoDiscover) {
    statusText.textContent = "Enter URLs, upload file, or enable auto discover.";
    return;
  }
  if (isAutoDiscover) {
    urls = [];
  }

  checkBtn.disabled = true;
  statusText.textContent = isAutoDiscover
    ? "Discovering URLs and running checks..."
    : `Checking ${urls.length} URL(s)...`;
  resultsBody.innerHTML = `<tr><td colspan="8" class="muted">Running checks, please wait...</td></tr>`;

  try {
    const login = {
      enabled: loginEnabled.checked,
      login_url: loginUrl.value.trim(),
      username: username.value.trim(),
      password: password.value,
    };

    const response = await fetch("/api/check", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        app_name: appName.value.trim() || "Unnamed App",
        urls,
        login,
        auto_discover: autoDiscover.checked,
        discover_from: discoverFrom.value.trim(),
        max_discover_pages: Number(maxDiscoverPages.value || 25),
      }),
    });

    const payload = await response.json();
    if (!response.ok) {
      throw new Error(payload.error || "Failed to check URLs");
    }

    renderResults(payload.results || []);
    const goodCount = (payload.results || []).filter((r) => r.is_working).length;
    const totalChecked = (payload.results || []).length;
    statusText.textContent = `Completed. ${goodCount}/${totalChecked} URLs are working.`;
    await Promise.all([refreshApps(), refreshReports(selectedAppSlug), refreshScreenshots(selectedAppSlug)]);
    renderAppHistory(selectedAppSlug ? latestReports : []);
  } catch (error) {
    statusText.textContent = `Error: ${error.message}`;
    resultsBody.innerHTML = `<tr><td colspan="8" class="muted">No results due to error.</td></tr>`;
  } finally {
    checkBtn.disabled = false;
  }
}

navButtons.forEach((btn) =>
  btn.addEventListener("click", () => {
    setView(btn.dataset.view);
  }),
);

loadFileBtn.addEventListener("click", loadUrlsFromFile);
checkBtn.addEventListener("click", checkUrls);
refreshAppsBtn.addEventListener("click", refreshApps);
refreshReportsBtn.addEventListener("click", () => refreshReports(selectedAppSlug));
refreshScreenshotsBtn.addEventListener("click", () => refreshScreenshots(selectedAppSlug));
exportCsvBtn.addEventListener("click", exportCsv);
exportPdfBtn.addEventListener("click", exportPdf);
themeToggle.addEventListener("click", toggleTheme);
bulkDeleteAppsBtn.addEventListener("click", bulkDeleteApps);
bulkDeleteReportsBtn.addEventListener("click", bulkDeleteReports);
bulkDeleteShotsBtn.addEventListener("click", bulkDeleteScreenshots);
selectAllAppsBtn.addEventListener("click", selectAllApps);
clearAppsSelectionBtn.addEventListener("click", clearAppsSelection);
selectAllReportsBtn.addEventListener("click", selectAllReports);
clearReportsSelectionBtn.addEventListener("click", clearReportsSelection);
selectAllShotsBtn.addEventListener("click", selectAllShots);
clearShotsSelectionBtn.addEventListener("click", clearShotsSelection);

initTheme();
Promise.all([refreshApps(), refreshReports(), refreshScreenshots()]);
