/* WFW-Aushang PWA
 * - Listet Dateien aus public WebDAV Share
 * - Öffnet PDFs über PDF.js
 * - Kioskiges Install/Update Overlay
 */

const SHARE_TOKEN = "T9e7WESBXxy6rSD";
const SHARE_ROOT = "/"; // im Share
const DAV_BASE = `https://home.x-s.at/public.php/dav/files/${SHARE_TOKEN}`;

const PDFJS_VIEWER = "https://home.x-s.at/pdfjs/web/viewer.html?file=";

// Versioning für Overlay / Update-Erkennung
const APP_VERSION = "2025.12.24.2";
const DISMISS_KEY = "wfw_overlay_dismissed_for";

const VERSION_URL = "./version.json";

function $(id){ return document.getElementById(id); }

function applyTheme(theme){
  document.documentElement.setAttribute("data-theme", theme);
  localStorage.setItem("wfw_theme", theme);
}
function initTheme(){
  const saved = localStorage.getItem("wfw_theme");
  if (saved) return applyTheme(saved);
  const prefersDark = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
  applyTheme(prefersDark ? "dark" : "light");
}

function isInstalledPWA(){
  const m = window.matchMedia ? window.matchMedia("(display-mode: standalone)") : null;
  const m2 = window.matchMedia ? window.matchMedia("(display-mode: fullscreen)") : null;
  const isStandalone = !!(m && m.matches);
  const isFullscreen = !!(m2 && m2.matches);
  const isIOSStandalone = window.navigator.standalone === true;
  return isStandalone || isFullscreen || isIOSStandalone;
}

function showOverlay({title, text, primaryText, hint=""}){
  $("ovTitle").textContent = title;
  $("ovText").textContent = text;
  $("ovPrimaryBtn").textContent = primaryText;
  $("ovHint").textContent = hint;
  $("installOverlay").hidden = false;
}
function hideOverlay(){
  $("installOverlay").hidden = true;
}
function markOverlayDismissed(latestVersion){
  sessionStorage.setItem(DISMISS_KEY, latestVersion || APP_VERSION);
}
function isOverlayDismissed(latestVersion){
  const v = sessionStorage.getItem(DISMISS_KEY);
  return v && v === (latestVersion || APP_VERSION);
}

let deferredPrompt = null;
window.addEventListener("beforeinstallprompt", (e) => {
  e.preventDefault();
  deferredPrompt = e;
});

// --- Service Worker ---
async function registerSW(){
  if (!("serviceWorker" in navigator)) return null;
  try {
    const reg = await navigator.serviceWorker.register("./sw.js");
    // Optional: updaten, falls neue Version
    try { await reg.update(); } catch {}
    return reg;
  } catch {
    return null;
  }
}

// --- Install / Update Overlay ---
async function checkInstallOrUpdateOverlay(reg){
  let latest = APP_VERSION;
  try {
    const r = await fetch(VERSION_URL, { cache: "no-store" });
    if (r.ok) {
      const j = await r.json();
      if (j && typeof j.version === "string") latest = j.version;
    }
  } catch {}

  const installed = isInstalledPWA();
  const outdated = (latest !== APP_VERSION);

  // Wenn installiert UND aktuell -> kein Overlay
  if (installed && !outdated) return;

  // Wenn veraltet -> "Aktualisieren" erzwingen (kioskig)
  if (outdated) {
    showOverlay({
      title: "Update verfügbar",
      text: `Es gibt eine neue Version (${latest}). Bitte aktualisieren.`,
      primaryText: "Aktualisieren",
      hint: "Tipp: Nach dem Update wird die App neu geladen."
    });

    $("ovPrimaryBtn").onclick = async () => {
      try { await reg?.update?.(); } catch {}
      // Cache-bust / reload
      location.reload();
    };

    $("ovContinueBtn").onclick = () => hideOverlay();
    return;
  }

  // Nicht installiert -> "Installieren" (oder Hinweis wenn Prompt fehlt)
  const canInstall = !!deferredPrompt && !installed;

  if (canInstall) {
    showOverlay({
      title: "App installieren",
      text: "Installiert läuft WFW-Aushang schneller und im Kiosk-Modus.",
      primaryText: "Installieren",
      hint: ""
    });

    $("ovPrimaryBtn").onclick = async () => {
      try {
        deferredPrompt.prompt();
        await deferredPrompt.userChoice;
      } catch {}
      deferredPrompt = null;
      hideOverlay();
    };

  } else {
    // Fallback: wenn Chrome (noch) keinen Install-Prompt gibt
    showOverlay({
      title: "App installieren",
      text: "Wenn der Install-Button fehlt: Chrome Menü (⋮) → „App installieren“.",
      primaryText: "OK",
      hint: ""
    });

    $("ovPrimaryBtn").onclick = () => hideOverlay();
  }

  $("ovContinueBtn").onclick = () => hideOverlay();
}

// --- WebDAV Listing via PROPFIND ---
async function propfind(url, depth=1){
  const res = await fetch(url, {
    method: "PROPFIND",
    headers: { "Depth": String(depth) }
  });

  if (!res.ok) {
    const t = await res.text().catch(()=> "");
    throw new Error(`PROPFIND ${res.status} ${res.statusText} ${t.slice(0,200)}`);
  }
  return await res.text();
}

function parseDavResponse(xmlText){
  const parser = new DOMParser();
  const xml = parser.parseFromString(xmlText, "application/xml");
  const responses = [...xml.getElementsByTagNameNS("*","response")];

  const items = responses.map(r => {
    const hrefEl = r.getElementsByTagNameNS("*","href")[0];
    const href = hrefEl ? hrefEl.textContent : "";

    const propstat = r.getElementsByTagNameNS("*","propstat")[0];
    const prop = propstat ? propstat.getElementsByTagNameNS("*","prop")[0] : null;

    const isCollection = !!(prop && prop.getElementsByTagNameNS("*","collection")[0]);

    const sizeEl = prop ? prop.getElementsByTagNameNS("*","getcontentlength")[0] : null;
    const size = sizeEl ? parseInt(sizeEl.textContent || "0", 10) : 0;

    const modEl = prop ? prop.getElementsByTagNameNS("*","getlastmodified")[0] : null;
    const lastmod = modEl ? modEl.textContent : "";

    return { href, isCollection, size, lastmod };
  });

  return items;
}

function humanSize(bytes){
  if (!bytes || bytes < 1024) return bytes ? `${bytes} B` : "";
  const kb = bytes/1024;
  if (kb < 1024) return `${kb.toFixed(0)} KB`;
  const mb = kb/1024;
  return `${mb.toFixed(1)} MB`;
}

function safeDecode(s){
  try { return decodeURIComponent(s); } catch { return s; }
}

function extractNameFromHref(href){
  const noQuery = href.split("?")[0];
  const parts = noQuery.split("/").filter(Boolean);
  const last = parts[parts.length-1] || "";
  return safeDecode(last);
}

function pdfUrlFromHref(href){
  // href ist serverseitig percent-encoded; wir wollen eine saubere absolute URL für public.php/dav
  // href kommt meist als /public.php/dav/files/<token>/... oder voll
  if (href.startsWith("http")) return href;
  return `https://home.x-s.at${href}`;
}

function openPdfInPdfJs(fileUrl){
  // PDF.js erwartet file=ENCODED_URL
  const full = PDFJS_VIEWER + encodeURIComponent(fileUrl) + "#zoom=page-width";
  window.location.href = full;
}

function renderList(files){
  const list = $("list");
  list.innerHTML = "";

  if (!files.length) {
    $("status").textContent = "Keine PDFs gefunden.";
    return;
  }

  for (const f of files) {
    const row = document.createElement("div");
    row.className = "item";

    const icon = document.createElement("div");
    icon.className = "pdfIcon";
    icon.textContent = "📄";

    const name = document.createElement("div");
    name.className = "name";
    name.textContent = f.name;

    const meta = document.createElement("div");
    meta.className = "meta";
    meta.textContent = humanSize(f.size);

    row.appendChild(icon);
    row.appendChild(name);
    row.appendChild(meta);

    row.onclick = () => openPdfInPdfJs(f.url);

    list.appendChild(row);
  }

  $("status").textContent = `PDFs: ${files.length}`;
}

async function load(){
  $("status").textContent = "Lade Liste…";

  const basePath = SHARE_ROOT.replace(/^\/?/, "/").replace(/\/?$/, "/");
  const url = DAV_BASE + basePath; // z.B. .../TOKEN/

  const xml = await propfind(url, 1);
  const items = parseDavResponse(xml);

  // Erstes Element ist meistens das Verzeichnis selbst -> rausfiltern
  const files = items
    .filter(it => !it.isCollection)
    .map(it => {
      const name = extractNameFromHref(it.href);
      return {
        name,
        size: it.size || 0,
        url: pdfUrlFromHref(it.href)
      };
    })
    .filter(f => f.name.toLowerCase().endsWith(".pdf"));

  // Sortierung: nach Dateiname absteigend (oft Datum im Namen)
  files.sort((a,b) => b.name.localeCompare(a.name, "de"));

  renderList(files);
}

function closeAushang(){
  // kiosk-typisch: zurück oder tab schließen (falls erlaubt)
  try { window.close(); } catch {}
  history.back();
}

// Boot
document.addEventListener("DOMContentLoaded", async () => {
  initTheme();

  $("themeBtn").addEventListener("click", () => {
    const cur = document.documentElement.getAttribute("data-theme") || "light";
    applyTheme(cur === "dark" ? "light" : "dark");
  });

  $("refreshBtn").addEventListener("click", () => load());
  $("closeBtn").addEventListener("click", closeAushang);

  const reg = await registerSW();
  await checkInstallOrUpdateOverlay(reg);

  try {
    await load();
  } catch (e) {
    $("status").textContent = "Fehler beim Laden der Liste.";
    // In kiosk mode: Fehlertext kurz, Details nur im Overlay-Hint
    showOverlay({
      title: "Fehler",
      text: "Die Liste konnte nicht geladen werden.",
      primaryText: "OK",
      hint: String(e).slice(0, 140)
    });
    $("ovPrimaryBtn").onclick = () => hideOverlay();
    $("ovContinueBtn").onclick = () => hideOverlay();
  }
});