/* =========================================================
   EDV QR Generator – Complete qr-generator.js
   + Darkmode sync with WordPress theme toggle:
     - observes <html> and <body> class/attributes
     - sets .edvqr--dark on the plugin root
   + vCard with labeled links (Apple/iOS itemX.URL + X-ABLabel)
   Uses local QR engine: window.edvQrLib.generatePngDataUrl(payload, px)
   © edv-future.de
   ========================================================= */

(function () {
  "use strict";

  function q(root, sel) { return root.querySelector(sel); }
  function qa(root, sel) { return Array.from(root.querySelectorAll(sel)); }

  function escVC(s) {
    return (s || "")
      .replace(/\\/g, "\\\\")
      .replace(/\n/g, "\\n")
      .replace(/;/g, "\\;")
      .replace(/,/g, "\\,");
  }

  function uiInput(key, label, ph = "", type = "text") {
    return `
      <div>
        <label class="edvqr__label">${label}</label>
        <input class="edvqr__input" data-f="${key}" type="${type}" placeholder="${ph}">
      </div>`;
  }

  function uiTextarea(key, label, ph = "") {
    return `
      <div>
        <label class="edvqr__label">${label}</label>
        <textarea class="edvqr__textarea" data-f="${key}" placeholder="${ph}"></textarea>
      </div>`;
  }

  function uiRow(a, b) {
    return `<div class="edvqr__row">${a}${b}</div>`;
  }

  function setStatus(statusEl, msg, ok) {
    statusEl.textContent = msg;
    statusEl.className = "edvqr__status " + (ok ? "edvqr__status--ok" : "edvqr__status--warn");
    statusEl.hidden = false;
  }

  function clearStatus(statusEl) {
    statusEl.hidden = true;
    statusEl.textContent = "";
    statusEl.className = "edvqr__status";
  }

  function val(root, key) {
    const el = q(root, `[data-f="${key}"]`);
    return el ? (el.value || "").trim() : "";
  }

  function renderFields(root, type) {
    const box = q(root, `[data-edvqr="fields"]`);
    let html = "";

    if (type === "vcard") {
      html = `
        ${uiRow(
          uiInput("fn", "Name", "Max Mustermann"),
          uiInput("org", "Firma (optional)", "edv-future.de")
        )}

        ${uiRow(
          uiInput("tel", "Telefon (optional)", "+49 30 123456"),
          uiInput("cell", "Mobil (optional)", "+49 170 1234567")
        )}

        ${uiRow(
          uiInput("email", "E-Mail (optional)", "info@edv-future.de", "email"),
          uiInput("title", "Titel (optional)", "IT")
        )}

        ${uiInput("url", "Website (optional)", "https://www.edv-future.de")}
        ${uiInput("photo", "Foto-Link (optional)", "https://domain.de/foto.jpg")}

        ${uiRow(
          uiInput("tw", "Twitter/X Link (optional)", "https://x.com/name"),
          uiInput("fb", "Facebook Link (optional)", "https://facebook.com/name")
        )}

        ${uiRow(
          uiInput("ig", "Instagram Link (optional)", "https://instagram.com/name"),
          uiInput("li", "LinkedIn Link (optional)", "https://linkedin.com/in/name")
        )}

        ${uiTextarea("adr", "Adresse (optional)", "Straße 1\n12345 Stadt\nDeutschland")}
        <small class="edvqr__muted edvqr__small">Social-Links werden als beschriftete URLs gespeichert (iOS/Apple kompatibel).</small>
      `;
    } else if (type === "url") {
      html = uiInput("data", "URL", "https://example.com");
    } else if (type === "text") {
      html = uiTextarea("data", "Text", "Beliebiger Text…");
    } else if (type === "email") {
      html = `
        ${uiRow(
          uiInput("to", "An", "max@domain.de", "email"),
          uiInput("subj", "Betreff (optional)", "Hallo")
        )}
        ${uiTextarea("body", "Nachricht (optional)", "Text der E-Mail…")}
      `;
    } else if (type === "sms") {
      html = uiRow(
        uiInput("to", "Nummer", "+491701234567"),
        uiInput("body", "Text (optional)", "Hi!")
      );
    } else if (type === "wifi") {
      html = `
        ${uiRow(
          uiInput("ssid", "SSID", "WLAN-Name"),
          uiInput("pass", "Passwort", "********")
        )}
        ${uiRow(
          `<div>
             <label class="edvqr__label">Sicherheit</label>
             <select class="edvqr__input" data-f="auth">
               <option value="WPA" selected>WPA/WPA2/WPA3</option>
               <option value="WEP">WEP</option>
               <option value="nopass">Ohne Passwort</option>
             </select>
           </div>`,
          `<div>
             <label class="edvqr__label">Versteckt</label>
             <select class="edvqr__input" data-f="hidden">
               <option value="false" selected>Nein</option>
               <option value="true">Ja</option>
             </select>
           </div>`
        )}
      `;
    } else if (type === "bitcoin") {
      html = `
        ${uiInput("addr", "Bitcoin Adresse", "bc1...")}
        ${uiRow(
          uiInput("amount", "Betrag (optional)", "0.001"),
          uiInput("label", "Label (optional)", "Spende")
        )}
        ${uiInput("message", "Nachricht (optional)", "Danke!")}
      `;
    } else if (type === "twitter") {
      html = uiRow(
        uiInput("user", "Username", "openai (ohne @)"),
        uiInput("text", "Tweet-Text (optional)", "Hallo Welt")
      );
    } else if (type === "facebook") {
      html = uiInput("url", "Facebook URL", "https://www.facebook.com/deineseite");
    } else if (type === "filelink") {
      html = uiInput("url", "Datei-URL (öffentlich)", "https://domain.tld/datei.pdf");
    } else {
      html = uiInput("data", "Inhalt", "https://example.com");
    }

    box.innerHTML = html;
  }

  // Apple/iOS style labeled URL items
  function vcardAddLabeledUrl(lines, idx, url, label) {
    if (!url) return idx;
    lines.push(`item${idx}.URL:${escVC(url)}`);
    lines.push(`item${idx}.X-ABLabel:${escVC(label)}`);
    return idx + 1;
  }

  function buildPayload(root, type) {
    if (type === "vcard") {
      const fn = val(root, "fn");
      if (!fn) throw new Error("Bitte mindestens den Namen (FN) angeben.");

      const lines = [];
      lines.push("BEGIN:VCARD");
      lines.push("VERSION:3.0");
      lines.push(`FN:${escVC(fn)}`);
      lines.push(`N:${escVC(fn)};;;;`);

      const org = val(root, "org");
      const title = val(root, "title");
      const tel = val(root, "tel");
      const cell = val(root, "cell");
      const email = val(root, "email");
      const photo = val(root, "photo");

      if (org) lines.push(`ORG:${escVC(org)}`);
      if (title) lines.push(`TITLE:${escVC(title)}`);
      if (tel) lines.push(`TEL;TYPE=voice,work:${escVC(tel)}`);
      if (cell) lines.push(`TEL;TYPE=cell:${escVC(cell)}`);
      if (email) lines.push(`EMAIL;TYPE=INTERNET:${escVC(email)}`);

      // Labeled links
      let idx = 1;
      idx = vcardAddLabeledUrl(lines, idx, val(root, "url"), "Website");
      idx = vcardAddLabeledUrl(lines, idx, val(root, "tw"), "Twitter/X");
      idx = vcardAddLabeledUrl(lines, idx, val(root, "fb"), "Facebook");
      idx = vcardAddLabeledUrl(lines, idx, val(root, "ig"), "Instagram");
      idx = vcardAddLabeledUrl(lines, idx, val(root, "li"), "LinkedIn");

      if (photo) lines.push(`PHOTO;VALUE=URI:${escVC(photo)}`);

      const adr = val(root, "adr");
      if (adr) {
        const a = adr.split(/\r?\n/).map(s => s.trim());
        lines.push(`ADR:;;${escVC(a[0] || "")};${escVC(a[1] || "")};;;${escVC(a[2] || "")}`);
      }

      lines.push("END:VCARD");
      return lines.join("\n");
    }

    if (type === "url") {
      const u = val(root, "data");
      if (!u) throw new Error("Bitte eine URL eingeben.");
      return u;
    }

    if (type === "text") {
      const t = val(root, "data");
      if (!t) throw new Error("Bitte Text eingeben.");
      return t;
    }

    if (type === "email") {
      const to = val(root, "to");
      if (!to) throw new Error("Bitte E-Mail Empfänger angeben.");
      const subj = val(root, "subj");
      const body = val(root, "body");
      const params = new URLSearchParams();
      if (subj) params.set("subject", subj);
      if (body) params.set("body", body);
      const qs = params.toString();
      return `mailto:${to}${qs ? "?" + qs : ""}`;
    }

    if (type === "sms") {
      const to = val(root, "to");
      if (!to) throw new Error("Bitte Telefonnummer angeben.");
      const body = val(root, "body");
      return `SMSTO:${to}:${body}`;
    }

    if (type === "wifi") {
      const ssid = val(root, "ssid");
      const pass = val(root, "pass");
      const auth = val(root, "auth") || "WPA";
      const hidden = val(root, "hidden") || "false";

      if (!ssid) throw new Error("Bitte SSID angeben.");
      if (auth !== "nopass" && !pass) throw new Error("Bitte WLAN-Passwort angeben oder 'Ohne Passwort' wählen.");

      const esc = (s) => (s || "").replace(/([\\;,:"])/g, "\\$1");
      const P = auth === "nopass" ? "" : esc(pass);
      const H = hidden === "true" ? "true" : "false";
      return `WIFI:S:${esc(ssid)};T:${auth};P:${P};H:${H};;`;
    }

    if (type === "bitcoin") {
      const addr = val(root, "addr");
      if (!addr) throw new Error("Bitte Bitcoin-Adresse angeben.");
      const amount = val(root, "amount");
      const label = val(root, "label");
      const message = val(root, "message");
      const p = new URLSearchParams();
      if (amount) p.set("amount", amount);
      if (label) p.set("label", label);
      if (message) p.set("message", message);
      const qs = p.toString();
      return `bitcoin:${addr}${qs ? "?" + qs : ""}`;
    }

    if (type === "twitter") {
      const user = val(root, "user");
      if (!user) throw new Error("Bitte Username angeben.");
      const text = val(root, "text");
      if (text) return "https://twitter.com/intent/tweet?" + new URLSearchParams({ text }).toString();
      return "https://twitter.com/" + encodeURIComponent(user);
    }

    if (type === "facebook") {
      const u = val(root, "url");
      if (!u) throw new Error("Bitte Facebook-URL angeben.");
      return u;
    }

    if (type === "filelink") {
      const u = val(root, "url");
      if (!u) throw new Error("Bitte Datei-URL angeben.");
      return u;
    }

    const d = val(root, "data");
    if (!d) throw new Error("Bitte Inhalt eingeben.");
    return d;
  }

  // -------- Dark mode detection + live sync --------
  function isDarkNow() {
    const html = document.documentElement;
    const body = document.body;

    const cls = ((html && html.className) ? html.className : "") + " " + ((body && body.className) ? body.className : "");
    const c = cls.toLowerCase();

    // Common class markers
    const classDark =
      c.includes("dark") || c.includes("dark-mode") || c.includes("night") || c.includes("theme-dark");

    // Common data attributes
    const htmlTheme = html ? (html.getAttribute("data-theme") || html.getAttribute("data-color-scheme") || "") : "";
    const bodyTheme = body ? (body.getAttribute("data-theme") || body.getAttribute("data-color-scheme") || "") : "";
    const attr = (htmlTheme + " " + bodyTheme).toLowerCase();
    const attrDark = attr.includes("dark");

    // Fallback: system setting
    const sysDark = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;

    // If theme explicitly sets light, honor it
    const attrLight = attr.includes("light");
    const classLight = c.includes("light-mode") || c.includes("theme-light");

    if (attrLight || classLight) return false;
    return classDark || attrDark || sysDark;
  }

  function syncDark(root) {
    root.classList.toggle("edvqr--dark", isDarkNow());
  }

  function observeThemeChanges(root) {
    // Sync immediately
    syncDark(root);

    // Observe class/attribute changes on html & body
    const targets = [document.documentElement, document.body].filter(Boolean);
    const obs = new MutationObserver(() => syncDark(root));
    for (const t of targets) {
      obs.observe(t, { attributes: true, attributeFilter: ["class", "data-theme", "data-color-scheme"] });
    }

    // Also listen for system changes
    if (window.matchMedia) {
      const mq = window.matchMedia("(prefers-color-scheme: dark)");
      // Safari old
      if (mq.addEventListener) mq.addEventListener("change", () => syncDark(root));
      else if (mq.addListener) mq.addListener(() => syncDark(root));
    }
  }

  function initOne(root) {
    const typeEl = q(root, `[data-edvqr="type"]`);
    const sizeEl = q(root, `[data-edvqr="size"]`);
    const genBtn = q(root, `[data-edvqr="gen"]`);
    const dlBtn = q(root, `[data-edvqr="dl"]`);
    const copyBtn = q(root, `[data-edvqr="copy"]`);

    const imgEl = q(root, `[data-edvqr="img"]`);
    const phEl = q(root, `[data-edvqr="ph"]`);

    const statusEl = q(root, `[data-edvqr="status"]`);
    const payloadBox = q(root, `[data-edvqr="payloadbox"]`);
    const payloadTa = q(root, `[data-edvqr="payload"]`);

    let lastPayload = "";
    let lastDataUrl = "";

    observeThemeChanges(root);

    function render() {
      renderFields(root, typeEl.value);
    }

    function generate() {
      clearStatus(statusEl);
      dlBtn.disabled = true;
      copyBtn.disabled = true;
      payloadBox.hidden = true;

      try {
        const payload = buildPayload(root, typeEl.value);
        const px = parseInt(sizeEl.value, 10);

        if (!window.edvQrLib || typeof window.edvQrLib.generatePngDataUrl !== "function") {
          throw new Error("QR-Library fehlt (edvQrLib.generatePngDataUrl).");
        }

        const dataUrl = window.edvQrLib.generatePngDataUrl(payload, px);

        imgEl.src = dataUrl;
        imgEl.hidden = false;
        phEl.hidden = true;

        lastPayload = payload;
        lastDataUrl = dataUrl;

        payloadTa.value = payload;
        payloadBox.hidden = false;

        dlBtn.disabled = false;
        copyBtn.disabled = false;

        if (payload.length > 900) {
          setStatus(statusEl, `Hinweis: Sehr langer Inhalt (${payload.length} Zeichen). QR kann dichter werden und schlechter scannen.`, false);
        } else {
          setStatus(statusEl, "QR-Code erfolgreich generiert.", true);
        }
      } catch (e) {
        imgEl.hidden = true;
        phEl.hidden = false;
        setStatus(statusEl, e.message || String(e), false);
      }
    }

    function download() {
      if (!lastDataUrl) return;
      const a = document.createElement("a");
      a.download = "qrcode.png";
      a.href = lastDataUrl;
      a.click();
    }

    async function copyPayload() {
      if (!lastPayload) return;
      try {
        await navigator.clipboard.writeText(lastPayload);
        setStatus(statusEl, "Payload kopiert.", true);
      } catch {
        setStatus(statusEl, "Kopieren nicht möglich (Browser-Rechte).", false);
      }
    }

    typeEl.addEventListener("change", () => { render(); generate(); });
    genBtn.addEventListener("click", generate);
    dlBtn.addEventListener("click", download);
    copyBtn.addEventListener("click", copyPayload);

    render();
    generate();
  }

  function initAll() {
    qa(document, `[data-edvqr-root]`).forEach(initOne);
  }

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", initAll);
  } else {
    initAll();
  }
})();
