/* =====================================================================
   DOGFATHER UNIVERSE — main.js
   Gemeinsame Navigation, mobiles Menü, Footer, Nebel-Effekt.
   Läuft rein clientseitig (kein Build-Tool, kein Fetch von Partials),
   damit jede Seite auch direkt per Doppelklick (file://) funktioniert.
   ===================================================================== */

(function () {
  "use strict";

  /* ---------- Navigationsstruktur (an einer Stelle pflegen) ---------- */
  const NAV = [
    { label: "Start", href: "index.html" },
    {
      label: "DogFather",
      children: [
        { label: "Die Person", href: "dogfather.html" },
        { label: "Streamer", href: "streamer.html" },
        { label: "Casper", href: "casper.html" },
        { label: "VanVan", href: "vanvan.html" },
        { label: "Zeitreise", href: "zeitreise.html" },
      ],
    },
    {
      label: "HasiDog",
      children: [
        { label: "HasiDog-Welt", href: "hasidog.html" },
        { label: "Modi-Team", href: "team-modis.html" },
        { label: "Community", href: "community.html" },
        { label: "Stimmen", href: "stimmen.html" },
        // Streamplan zurück unter HasiDog — Wunsch Dogi.
        { label: "Streamplan", href: "streamplan.html" },
      ],
    },
    {
      label: "Manager",
      children: [
        { label: "Manager DogFather", href: "manager.html" },
        { label: "Scout-Team", href: "team-scouts.html" },
        { label: "Creator", href: "creator.html" },
        { label: "Werte", href: "werte.html" },
        { label: "Bewerben", href: "bewerben.html" },
      ],
    },
    {
      // Medien ist bewusst nach den 3 Welten aufgeteilt statt nach
      // Foto/Video/Aktionen getrennt zu sein — Wunsch von Dogi: pro Welt
      // (DogFather/HasiDog/Casper) gibt es EINE Seite mit allem
      // kategorisiert (Fotos, Videos, Events), siehe medien-*.html.
      label: "Medien",
      children: [
        { label: "DogFather", href: "medien-dogfather.html" },
        { label: "HasiDog", href: "medien-hasidog.html" },
        { label: "Casper", href: "medien-casper.html" },
      ],
    },
    { label: "Links", href: "links.html" },
  ];

  /* Aktuelle Datei — wird beim nahtlosen Seitenwechsel mit aktualisiert. */
  let currentFile = (location.pathname.split("/").pop() || "index.html");

  function isActive(href) {
    return href === currentFile;
  }

  function renderNavItem(item) {
    if (!item.children) {
      return `<a class="nav-flat${isActive(item.href) ? " active" : ""}" href="${item.href}">${item.label}</a>`;
    }
    const activeChild = item.children.some((c) => isActive(c.href));
    return `
      <div class="nav-group${activeChild ? " open-hint" : ""}">
        <button type="button" aria-expanded="false">${item.label} <span aria-hidden="true">▾</span></button>
        <div class="nav-dropdown">
          ${item.children
            .map(
              (c) =>
                `<a href="${c.href}"${isActive(c.href) ? ' class="active"' : ""}>${c.label}</a>`
            )
            .join("")}
        </div>
      </div>`;
  }

  function renderHeader() {
    const el = document.getElementById("site-header");
    if (!el) return;
    el.innerHTML = `
      <header class="site-header">
        <div class="nav-bar">
          <a class="brand" href="index.html">
            <img class="brand-logo" src="assets/img/logo-dogfather.png" alt="DogFather Logo" />
            <span>DOGFATHER UNIVERSE
              <small>Streamer · Community · HasiDog · Manager</small>
            </span>
          </a>
          <button class="nav-toggle" type="button" aria-label="Menü öffnen" aria-expanded="false">☰</button>
          <nav class="nav-links">
            ${NAV.map(renderNavItem).join("")}
            <a class="nav-cta" href="bewerben.html"><span>Bewerben 🩵</span></a>
          </nav>
        </div>
      </header>`;

    const toggle = el.querySelector(".nav-toggle");
    const links = el.querySelector(".nav-links");
    toggle.addEventListener("click", () => {
      const open = links.classList.toggle("open");
      toggle.setAttribute("aria-expanded", String(open));
    });

    el.querySelectorAll(".nav-group > button").forEach((btn) => {
      btn.addEventListener("click", () => {
        const group = btn.parentElement;
        const wasOpen = group.classList.contains("open");
        el.querySelectorAll(".nav-group.open").forEach((g) => g.classList.remove("open"));
        if (!wasOpen) group.classList.add("open");
        btn.setAttribute("aria-expanded", String(!wasOpen));
      });
    });

  }

  /* Klick außerhalb schließt offene Menüs. Bewusst NUR EINMAL angemeldet —
     renderHeader() läuft bei jedem Seitenwechsel erneut, und ein Zuhörer
     pro Wechsel würde sich sonst endlos aufsummieren. */
  document.addEventListener("click", (e) => {
    const kopf = document.getElementById("site-header");
    if (kopf && !kopf.contains(e.target)) {
      kopf.querySelectorAll(".nav-group.open").forEach((g) => g.classList.remove("open"));
    }
  });

  function renderFooter() {
    const el = document.getElementById("site-footer");
    if (!el) return;
    const year = new Date().getFullYear();
    el.innerHTML = `
      <footer class="site-footer">
        <div class="container footer-grid">
          <div>
            <div class="brand"><span class="heart">🩵</span> DOGFATHER UNIVERSE</div>
            <p class="small" style="margin-top:.8rem;max-width:32ch;">
              Streamer. Community. HasiDog. Manager. Gemeinsam stark.
            </p>
          </div>
          <div>
            <h4>DogFather</h4>
            <ul>
              <li><a href="dogfather.html">Die Person</a></li>
              <li><a href="streamer.html">Streamer</a></li>
              <li><a href="casper.html">Casper</a></li>
              <li><a href="vanvan.html">VanVan</a></li>
              <li><a href="zeitreise.html">Zeitreise</a></li>
            </ul>
          </div>
          <div>
            <h4>HasiDog &amp; Manager</h4>
            <ul>
              <li><a href="hasidog.html">HasiDog-Welt</a></li>
              <li><a href="team-modis.html">Modi-Team</a></li>
              <li><a href="community.html">Community</a></li>
              <li><a href="stimmen.html">Stimmen</a></li>
              <li><a href="streamplan.html">Streamplan</a></li>
              <li><a href="manager.html">Manager DogFather</a></li>
              <li><a href="team-scouts.html">Scouts</a></li>
            </ul>
          </div>
          <div>
            <h4>Mehr</h4>
            <ul>
              <li><a href="links.html">Alle Links</a></li>
              <li><a href="bewerben.html">Bewerben</a></li>
              <li><a href="kontakt.html">Kontakt</a></li>
            </ul>
          </div>
        </div>
        <div class="container footer-bottom">
          <span>© ${year} DogFather Universe. Team Dogi ist Familie 🩵</span>
          <span><a href="kontakt.html">Impressum &amp; Datenschutz</a></span>
        </div>
      </footer>`;
  }

  function renderFog() {
    if (document.querySelector(".fog-layer")) return;
    const layer = document.createElement("div");
    layer.className = "fog-layer";
    layer.setAttribute("aria-hidden", "true");
    const blobs = 6;
    let html = "";
    for (let i = 0; i < blobs; i++) {
      const size = 220 + Math.round(Math.random() * 260);
      const top = Math.round(Math.random() * 100);
      const left = Math.round(Math.random() * 100);
      const delay = (Math.random() * 10).toFixed(1);
      html += `<span style="width:${size}px;height:${size}px;top:${top}%;left:${left}%;animation-delay:${delay}s;"></span>`;
    }
    layer.innerHTML = html;
    document.body.prepend(layer);
  }

  /* ===================================================================
     Musik-Knopf (unten rechts, auf jeder Seite)

     Kleiner schwebender Knopf, der ein Feld mit den Spotify-Playern von
     Hasidog und Van-Van aufklappt. Genauso gelöst wie im Analyse-Tool.

     Zwei bewusste Entscheidungen:
     1. Das Feld hängt direkt am <body>, nicht in einem Abschnitt — so
        kann kein Neuaufbau der Seite den laufenden Player unterbrechen.
     2. Die Player werden ERST beim ersten Öffnen geladen (src wird dann
        gesetzt). Sonst würde jede Seite zwei fremde Einbettungen laden,
        auch wenn niemand Musik hören will.
     =================================================================== */
  const SPOTIFY_ARTISTS = [
    { name: "Hasidog", id: "2INiE1VVJGUQdEURsltuJU" },
    { name: "Van-Van", id: "4J9PcKZBkh6V8dVY3CGliw" },
  ];

  function renderMusicWidget() {
    if (document.getElementById("music-widget")) return;

    const widget = document.createElement("div");
    widget.className = "music-widget";
    widget.id = "music-widget";
    widget.innerHTML = `
      <div class="music-panel" id="music-panel" hidden>
        <div class="music-panel-head">
          <strong>Musik von Team Dogi 🎵</strong>
          <button class="music-close" id="music-close" type="button" aria-label="Musik-Feld schließen">✕</button>
        </div>
        <p class="small muted" style="margin:.2rem 0 .6rem;">Läuft weiter, solange du auf dieser Seite bleibst. 🩵</p>
        ${SPOTIFY_ARTISTS.map(
          (a) => `
        <p class="music-artist-label">${a.name}</p>
        <iframe data-src="https://open.spotify.com/embed/artist/${a.id}?utm_source=generator&amp;theme=0"
                height="152" loading="lazy" title="${a.name} auf Spotify anhören"
                allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"
                allowfullscreen></iframe>`
        ).join("")}
      </div>
      <button class="music-toggle" id="music-toggle" type="button"
              aria-expanded="false" aria-controls="music-panel"
              title="Musik von Hasidog &amp; Van-Van"><span>🎵</span></button>`;
    document.body.appendChild(widget);

    const panel = document.getElementById("music-panel");
    const toggle = document.getElementById("music-toggle");
    let geladen = false;

    function oeffnen(auf) {
      panel.hidden = !auf;
      toggle.setAttribute("aria-expanded", String(auf));
      widget.classList.toggle("open", auf);
      if (auf && !geladen) {
        // Player erst jetzt wirklich laden
        panel.querySelectorAll("iframe[data-src]").forEach((f) => {
          f.src = f.dataset.src;
          f.removeAttribute("data-src");
        });
        geladen = true;
      }
    }

    toggle.addEventListener("click", () => oeffnen(panel.hidden));
    document.getElementById("music-close").addEventListener("click", () => oeffnen(false));
    document.addEventListener("keydown", (e) => {
      if (e.key === "Escape" && !panel.hidden) oeffnen(false);
    });
  }

  /* ===================================================================
     Musik-Knopf: Chamäleon-Farben

     Der Knopf soll nicht nur zwischen 3 festen Weltfarben wechseln,
     sondern sich an das tatsächliche Bild JEDER einzelnen Seite anpassen
     — Durchschnittsfarbe plus die kräftigste (sattste) Farbe darin, als
     kleiner Verlauf. Bildquelle in Prioritätsreihenfolge:
       1. Das scharfe Banner-Bild im Kopfbereich (.hero-banner img)
       2. Das Artwork der Startseite (.hero-artwork, CSS-Hintergrund)
       3. Das Ambiente-Hintergrundbild der Seite (--page-bg am <body>)
     Gibt es nichts davon (reine Text-Hero-Seiten wie Links oder Videos),
     fällt der Knopf sauber auf die normale Weltfarbe zurück (siehe CSS:
     var(--music-c1, var(--accent))).

     Bilder sind alle selbst gehostet (gleiche Domain) — Canvas-Auslesen
     funktioniert dadurch ohne CORS-Probleme.
     =================================================================== */
  function bildquelleErmitteln() {
    const banner = document.querySelector(".hero-banner img");
    if (banner && banner.getAttribute("src")) return banner;

    const artwork = document.querySelector(".hero-artwork");
    if (artwork) {
      const hintergrund = getComputedStyle(artwork, "::before").backgroundImage;
      const ersteEbene = hintergrund && hintergrund.split(",")[0];
      const treffer = ersteEbene && ersteEbene.match(/url\(["']?(.*?)["']?\)/);
      if (treffer && treffer[1]) return treffer[1];
    }

    const seitenBg = getComputedStyle(document.body).getPropertyValue("--page-bg");
    const treffer2 = seitenBg && seitenBg.match(/url\(["']?(.*?)["']?\)/);
    if (treffer2 && treffer2[1]) return treffer2[1];

    return null;
  }

  function rgbNachHsl(r, g, b) {
    r /= 255; g /= 255; b /= 255;
    const max = Math.max(r, g, b), min = Math.min(r, g, b);
    let h = 0, s = 0;
    const l = (max + min) / 2;
    if (max !== min) {
      const d = max - min;
      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
      switch (max) {
        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
        case g: h = (b - r) / d + 2; break;
        default: h = (r - g) / d + 4;
      }
      h *= 60;
    }
    return [h, s * 100, l * 100];
  }

  const begrenzen = (wert, min, max) => Math.min(max, Math.max(min, wert));

  let musikFarbLauf = 0;

  function musikKnopfFarbenAnpassen() {
    const knopf = document.getElementById("music-toggle");
    if (!knopf) return;
    const lauf = ++musikFarbLauf;

    const zuruecksetzen = () => {
      knopf.style.removeProperty("--music-c1");
      knopf.style.removeProperty("--music-c2");
    };

    const quelle = bildquelleErmitteln();
    if (!quelle) {
      zuruecksetzen();
      return;
    }

    const verarbeiten = (bild) => {
      if (lauf !== musikFarbLauf) return; // zwischenzeitlich schon weitergeklickt
      try {
        const groesse = 28;
        const canvas = document.createElement("canvas");
        canvas.width = groesse;
        canvas.height = groesse;
        const ctx = canvas.getContext("2d");
        ctx.drawImage(bild, 0, 0, groesse, groesse);
        const daten = ctx.getImageData(0, 0, groesse, groesse).data;

        let rSumme = 0, gSumme = 0, bSumme = 0, n = 0;
        let besteSaettigung = -1, satR = 0, satG = 0, satB = 0;
        for (let i = 0; i < daten.length; i += 4) {
          const r = daten[i], g = daten[i + 1], b = daten[i + 2];
          rSumme += r; gSumme += g; bSumme += b; n++;
          const hsl = rgbNachHsl(r, g, b);
          if (hsl[2] > 15 && hsl[2] < 88 && hsl[1] > besteSaettigung) {
            besteSaettigung = hsl[1]; satR = r; satG = g; satB = b;
          }
        }
        const r = Math.round(rSumme / n), g = Math.round(gSumme / n), b = Math.round(bSumme / n);

        const [h1, s1, l1] = rgbNachHsl(r, g, b);
        const farbe1 = `hsl(${Math.round(h1)}deg ${Math.round(begrenzen(s1, 42, 92))}% ${Math.round(begrenzen(l1, 40, 62))}%)`;

        let farbe2;
        if (besteSaettigung > 18) {
          const [h2, s2, l2] = rgbNachHsl(satR, satG, satB);
          farbe2 = `hsl(${Math.round(h2)}deg ${Math.round(begrenzen(s2, 50, 95))}% ${Math.round(begrenzen(l2, 42, 66))}%)`;
        } else {
          farbe2 = `hsl(${Math.round((h1 + 45) % 360)}deg ${Math.round(begrenzen(s1, 45, 90))}% ${Math.round(begrenzen(l1 + 8, 42, 68))}%)`;
        }

        knopf.style.setProperty("--music-c1", farbe1);
        knopf.style.setProperty("--music-c2", farbe2);
      } catch {
        zuruecksetzen(); // z.B. wenn das Bild aus irgendeinem Grund nicht lesbar ist
      }
    };

    if (typeof quelle === "string") {
      const bild = new Image();
      bild.addEventListener("load", () => verarbeiten(bild));
      bild.addEventListener("error", zuruecksetzen);
      bild.src = quelle;
    } else if (quelle.complete && quelle.naturalWidth > 0) {
      verarbeiten(quelle);
    } else {
      quelle.addEventListener("load", () => verarbeiten(quelle), { once: true });
      quelle.addEventListener("error", zuruecksetzen, { once: true });
    }
  }

  /* ===================================================================
     Nahtloser Seitenwechsel — damit die Musik nicht abreißt

     Normalerweise lädt der Browser bei jedem Klick die ganze Seite neu,
     wodurch der Spotify-Player jedes Mal von vorn startet. Stattdessen
     holen wir die Zielseite im Hintergrund und tauschen nur den
     Inhaltsbereich <main> aus. Kopfzeile, Fußzeile und der Musik-Knopf
     bleiben stehen — die Musik läuft einfach weiter.

     Die Liste unten kann bei Bedarf wieder Seiten aufnehmen, die bewusst
     NICHT nahtlos geladen werden sollen (z.B. künftige interne Bereiche
     mit eigenem Login) — aktuell gibt es keine solche Seite mehr.

     Absicherung: Geht beim Holen irgendetwas schief, wird ganz normal
     zur Zielseite navigiert. Schlimmstenfalls ist es also wie vorher.
     =================================================================== */
  const KEIN_NAHTLOSER_WECHSEL = [];

  /* Seiteneigene Skripte melden sich fast alle über "DOMContentLoaded" an.
     Nach dem ersten Laden ist dieses Ereignis längst vorbei — ein später
     nachgeladenes Skript würde also nie starten. Deshalb: Anmeldungen, die
     NACH dem Laden eintreffen, sofort ausführen. Während des normalen
     Erstaufbaus (readyState === "loading") bleibt alles wie gehabt. */
  const anmeldenOriginal = document.addEventListener.bind(document);
  document.addEventListener = function (typ, fn, optionen) {
    if (typ === "DOMContentLoaded" && document.readyState !== "loading" && typeof fn === "function") {
      setTimeout(() => fn(new Event("DOMContentLoaded")), 0);
      return;
    }
    return anmeldenOriginal(typ, fn, optionen);
  };

  /** Skripte der neuen Seite der Reihe nach ausführen. */
  async function skripteUebernehmen(neuesDokument) {
    const schonGeladen = new Set(
      [...document.querySelectorAll("script[src]")].map((s) => s.getAttribute("src"))
    );

    for (const alt of [...neuesDokument.querySelectorAll("script")]) {
      const src = alt.getAttribute("src");

      if (src) {
        // Schon vorhanden (z.B. main.js oder eine bereits geladene Datendatei):
        // nicht erneut ausführen — sonst gäbe es doppelte Deklarationen.
        if (schonGeladen.has(src)) continue;
        schonGeladen.add(src);
        await new Promise((fertig) => {
          const neu = document.createElement("script");
          neu.src = src;
          neu.async = false;
          neu.onload = neu.onerror = fertig; // auch bei Fehler weitermachen
          document.body.appendChild(neu);
        });
      } else {
        // Seiteneigenes Skript (z.B. Team-Vorschau der Startseite).
        // Läuft erst, wenn die Datendateien davor fertig geladen sind.
        const neu = document.createElement("script");
        neu.textContent = alt.textContent;
        document.body.appendChild(neu);
      }
    }
  }

  let ladeVorgang = 0;

  async function seiteLaden(url, mitVerlauf) {
    const lauf = ++ladeVorgang;
    document.body.classList.add("seite-laedt");

    let dok;
    try {
      const antwort = await fetch(url, { credentials: "same-origin" });
      if (!antwort.ok) throw new Error("HTTP " + antwort.status);
      dok = new DOMParser().parseFromString(await antwort.text(), "text/html");
    } catch {
      location.href = url; // Rückfall: ganz normal navigieren
      return;
    }
    if (lauf !== ladeVorgang) return; // zwischenzeitlich woanders hingeklickt

    const neuerInhalt = dok.querySelector("main");
    const alterInhalt = document.querySelector("main");
    if (!neuerInhalt || !alterInhalt) {
      location.href = url;
      return;
    }

    alterInhalt.replaceWith(neuerInhalt);

    // Seitenmotiv + Sonderklassen mitnehmen: Die Bildvariablen hängen am
    // <body>, damit das Motiv die ganze Seite trägt — beim Wechsel also mit
    // übernehmen. Bewusst die GANZE Klassenliste kopieren (nicht nur
    // "mit-hintergrund" einzeln pflegen), sonst bleiben Sonderklassen wie
    // "bewerben-seite" oder "start-seite" nach einem Klick-Wechsel fälschlich
    // stehen bzw. fehlen auf der neuen Seite.
    const bodyNeu = dok.body;
    document.body.className = bodyNeu.className;
    ["--page-bg", "--page-bg-mobile"].forEach((v) => {
      const wert = bodyNeu.style.getPropertyValue(v);
      if (wert) document.body.style.setProperty(v, wert);
      else document.body.style.removeProperty(v);
    });

    // Kopf der Seite mitziehen: Titel, Farbwelt, Beschreibung
    document.title = dok.title;
    const themaNeu = dok.documentElement.getAttribute("data-theme");
    if (themaNeu) document.documentElement.setAttribute("data-theme", themaNeu);
    const beschreibungNeu = dok.querySelector('meta[name="description"]');
    const beschreibungAlt = document.querySelector('meta[name="description"]');
    if (beschreibungNeu && beschreibungAlt) {
      beschreibungAlt.setAttribute("content", beschreibungNeu.getAttribute("content"));
    }

    if (mitVerlauf) history.pushState({ nahtlos: true }, "", url);
    currentFile = (new URL(url, location.href).pathname.split("/").pop() || "index.html");

    renderHeader(); // markiert den richtigen Menüpunkt als aktiv
    window.scrollTo(0, 0);
    document.body.classList.remove("seite-laedt");
    musikKnopfFarbenAnpassen(); // Chamäleon-Knopf an die neue Seite anpassen

    await skripteUebernehmen(dok);
  }

  function nahtloseNavigationAktivieren() {
    // Ohne History-API oder auf file:// lieber gar nicht erst versuchen
    if (!window.history || !window.history.pushState || location.protocol === "file:") return;
    if (KEIN_NAHTLOSER_WECHSEL.includes(currentFile)) return;

    document.addEventListener("click", (e) => {
      if (e.defaultPrevented || e.button !== 0) return;
      if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return; // neuer Tab o.ä.

      const link = e.target.closest("a");
      if (!link) return;

      const href = link.getAttribute("href");
      if (!href || href.startsWith("#") || href.startsWith("mailto:") || href.startsWith("tel:")) return;
      if (link.target && link.target !== "_self") return;
      if (link.hasAttribute("download")) return;

      const ziel = new URL(href, location.href);
      if (ziel.origin !== location.origin) return;                 // fremde Seite
      if (!ziel.pathname.endsWith(".html")) return;                // z.B. Bilddatei
      const datei = ziel.pathname.split("/").pop();
      if (KEIN_NAHTLOSER_WECHSEL.includes(datei)) return;          // interner Bereich
      if (ziel.pathname === location.pathname && ziel.search === location.search) return;

      e.preventDefault();
      seiteLaden(ziel.href, true);
    });

    window.addEventListener("popstate", () => {
      // Zurück-/Vorwärts-Knopf im Browser
      const datei = location.pathname.split("/").pop() || "index.html";
      if (KEIN_NAHTLOSER_WECHSEL.includes(datei)) {
        location.reload();
        return;
      }
      seiteLaden(location.href, false);
    });
  }

  document.addEventListener("DOMContentLoaded", () => {
    renderHeader();
    renderFooter();
    renderFog();
    renderMusicWidget();
    musikKnopfFarbenAnpassen();
    nahtloseNavigationAktivieren();
  });
})();
