(function () {
  const dialog = document.getElementById("completeDialog");
  const dialogForm = document.getElementById("completeDialogForm");
  const dialogChoice = document.getElementById("completeDialogChoice");
  const dialogText = document.getElementById("completeDialogText");
  const dialogChoices = document.getElementById("completeDialogChoices");
  const closeButton = document.getElementById("completeDialogClose");
  const quickTaskDialog = document.getElementById("quickTaskDialog");
  const quickTaskOpen = document.getElementById("quickTaskOpen");
  const quickTaskClose = document.getElementById("quickTaskClose");
  const quickWinsSubmit = document.getElementById("quickWinsSubmit");
  const quickWinInputs = document.querySelectorAll("[data-quick-win-input]");
  const quickWinCustomToggle = document.querySelector("[data-quick-win-custom-toggle]");
  const quickWinCustomFields = document.getElementById("quickWinCustomFields");
  const quickWinTitle = document.getElementById("quick-title");
  const quickWinEffort = document.getElementById("quick-effort");
  const currentUserId = document.body.dataset.currentUserId;
  const currentUserName = document.body.dataset.currentUserName;
  const quickWinSortList = document.querySelector("[data-quick-win-sort-list]");
  const quickWinSortIds = document.getElementById("quickWinSortIds");
  const quickWinSortSave = document.getElementById("quickWinSortSave");
  const quickWinToggleButtons = document.querySelectorAll("[data-quick-win-toggle]");
  const celebrationLayer = document.getElementById("celebrationLayer");
  const celebratePoints = Number.parseInt(document.body.dataset.celebratePoints || "", 10);
  const scrollRestoreKey = "putzliga:scroll-restore";
  let draggedQuickWin = null;
  let quickWinSortDirty = false;

  function rememberScrollPosition() {
    try {
      window.sessionStorage.setItem(
        scrollRestoreKey,
        JSON.stringify({
          path: window.location.pathname,
          y: window.scrollY,
        }),
      );
    } catch (_) {
      // Ignore storage errors and continue normally.
    }
  }

  function restoreScrollPosition() {
    try {
      const rawValue = window.sessionStorage.getItem(scrollRestoreKey);
      if (!rawValue) {
        return;
      }

      const saved = JSON.parse(rawValue);
      window.sessionStorage.removeItem(scrollRestoreKey);

      if (!saved || saved.path !== window.location.pathname || typeof saved.y !== "number") {
        return;
      }

      window.requestAnimationFrame(() => {
        window.requestAnimationFrame(() => {
          window.scrollTo({ top: saved.y, behavior: "auto" });
        });
      });
    } catch (_) {
      // Ignore malformed storage data.
    }
  }

  function buildCompletionOptions(button) {
    const options = [];
    const assignedPairs = [
      [button.dataset.assignedPrimaryId, button.dataset.assignedPrimaryName],
      [button.dataset.assignedSecondaryId, button.dataset.assignedSecondaryName],
    ];

    assignedPairs.forEach(([id, label]) => {
      if (id && label && !options.some((option) => option.value === id)) {
        options.push({ value: id, label });
      }
    });

    if (currentUserId && currentUserName && !options.some((option) => option.value === currentUserId)) {
      options.push({ value: currentUserId, label: "Ich" });
    }

    return options;
  }

  document.querySelectorAll("[data-complete-action]").forEach((button) => {
    button.addEventListener("click", () => {
      if (!dialog || !dialogForm || !dialogChoice || !dialogText || !dialogChoices) {
        return;
      }
      dialogForm.action = button.dataset.completeAction;
      dialogText.textContent = `Die Aufgabe "${button.dataset.completeTitle}" war ${button.dataset.completeAssigned} zugewiesen. Wer hat sie erledigt?`;
      dialogChoices.innerHTML = "";

      buildCompletionOptions(button).forEach((option, index) => {
        const choiceButton = document.createElement("button");
        choiceButton.type = "button";
        choiceButton.className = index === 0 ? "button button--secondary" : "button";
        choiceButton.dataset.completeChoice = option.value;
        choiceButton.textContent = option.label;
        choiceButton.addEventListener("click", () => {
          dialogChoice.value = option.value;
          rememberScrollPosition();
          dialog.close();
          dialogForm.submit();
        });
        dialogChoices.appendChild(choiceButton);
      });
      dialog.showModal();
    });
  });

  if (closeButton && dialog) {
    closeButton.addEventListener("click", () => dialog.close());
  }

  if (quickTaskOpen && quickTaskDialog) {
    quickTaskOpen.addEventListener("click", () => {
      if (!quickTaskDialog.open) {
        quickTaskDialog.showModal();
      }
    });
  }

  if (quickTaskClose && quickTaskDialog) {
    quickTaskClose.addEventListener("click", () => {
      if (quickTaskDialog.open) {
        quickTaskDialog.close();
      }
    });
  }

  [dialog, quickTaskDialog].forEach((activeDialog) => {
    if (!activeDialog) {
      return;
    }

    activeDialog.addEventListener("click", (event) => {
      if (event.target === activeDialog && activeDialog.open) {
        activeDialog.close();
      }
    });
  });

  function updateQuickWinsState() {
    const selectedPresetCount = [...quickWinInputs].filter((input) => input.checked).length;
    const customSelected = quickWinCustomToggle?.checked === true;
    const totalCount = selectedPresetCount + (customSelected ? 1 : 0);

    if (quickWinCustomFields) {
      quickWinCustomFields.hidden = !customSelected;
    }

    if (quickWinTitle) {
      quickWinTitle.disabled = !customSelected;
      quickWinTitle.required = customSelected;
    }

    if (quickWinEffort) {
      quickWinEffort.disabled = !customSelected;
      quickWinEffort.required = customSelected;
    }

    if (quickWinsSubmit) {
      quickWinsSubmit.disabled = totalCount === 0;
      quickWinsSubmit.textContent = totalCount <= 1 ? "Quick-Win sichern" : "Quick Wins sichern";
    }
  }

  quickWinInputs.forEach((input) => input.addEventListener("change", updateQuickWinsState));
  if (quickWinCustomToggle) {
    quickWinCustomToggle.addEventListener("change", updateQuickWinsState);
  }
  updateQuickWinsState();

  if (quickTaskDialog) {
    quickTaskDialog.addEventListener("close", () => {
      const quickWinsForm = document.getElementById("quickWinsForm");
      if (!quickWinsForm) {
        return;
      }
      quickWinsForm.reset();
      updateQuickWinsState();
    });
  }

  if (dialogForm) {
    dialogForm.addEventListener("submit", () => {
      rememberScrollPosition();
    });
  }

  document.querySelectorAll('form[action*="/complete"]').forEach((form) => {
    form.addEventListener("submit", () => {
      rememberScrollPosition();
    });
  });

  const quickWinsForm = document.getElementById("quickWinsForm");
  if (quickWinsForm) {
    quickWinsForm.addEventListener("submit", () => {
      rememberScrollPosition();
    });
  }

  function syncQuickWinSortIds() {
    if (!quickWinSortList || !quickWinSortIds) {
      return;
    }
    const ids = [...quickWinSortList.querySelectorAll("[data-quick-win-sort-item]")]
      .map((item) => item.dataset.quickWinSortItem)
      .filter(Boolean);
    quickWinSortIds.value = ids.join(",");
  }

  function setQuickWinSortDirty(isDirty) {
    quickWinSortDirty = isDirty;
    if (quickWinSortSave) {
      quickWinSortSave.disabled = !isDirty;
    }
  }

  function clearCelebrationQuery() {
    if (!window.history.replaceState) {
      return;
    }
    const url = new URL(window.location.href);
    if (!url.searchParams.has("celebrate_points")) {
      return;
    }
    url.searchParams.delete("celebrate_points");
    const nextUrl = `${url.pathname}${url.search}${url.hash}`;
    window.history.replaceState({}, document.title, nextUrl);
  }

  function celebrateCompletion(points) {
    if (!celebrationLayer || !Number.isFinite(points) || points <= 0) {
      return;
    }

    const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    celebrationLayer.hidden = false;
    celebrationLayer.setAttribute("aria-hidden", "false");
    celebrationLayer.innerHTML = "";

    const score = document.createElement("div");
    score.className = "celebration-score";
    score.textContent = points;
    celebrationLayer.appendChild(score);

    const glow = document.createElement("div");
    glow.className = "celebration-glow";
    celebrationLayer.appendChild(glow);

    if (!prefersReducedMotion) {
      const colors = [
        "rgba(94, 168, 255, 0.96)",
        "rgba(52, 211, 153, 0.95)",
        "rgba(250, 204, 21, 0.92)",
        "rgba(191, 219, 254, 0.96)",
      ];

      Array.from({ length: 14 }).forEach((_, index) => {
        const particle = document.createElement("span");
        particle.className = "celebration-particle";
        particle.style.setProperty("--angle", `${Math.round((360 / 14) * index + Math.random() * 18)}deg`);
        particle.style.setProperty("--distance", `${72 + Math.round(Math.random() * 44)}px`);
        particle.style.setProperty("--delay", `${(Math.random() * 0.08).toFixed(2)}s`);
        particle.style.setProperty("--size", `${7 + Math.round(Math.random() * 7)}px`);
        particle.style.background = colors[index % colors.length];
        celebrationLayer.appendChild(particle);
      });
    }

    window.setTimeout(() => {
      celebrationLayer.hidden = true;
      celebrationLayer.setAttribute("aria-hidden", "true");
      celebrationLayer.innerHTML = "";
    }, prefersReducedMotion ? 520 : 1500);
  }

  if (quickWinSortList) {
    syncQuickWinSortIds();
    setQuickWinSortDirty(false);

    quickWinSortList.querySelectorAll("[data-quick-win-sort-item]").forEach((item) => {
      item.addEventListener("dragstart", () => {
        draggedQuickWin = item;
        item.classList.add("is-dragging");
      });

      item.addEventListener("dragend", () => {
        item.classList.remove("is-dragging");
        draggedQuickWin = null;
      });

      item.addEventListener("dragover", (event) => {
        event.preventDefault();
      });

      item.addEventListener("drop", async (event) => {
        event.preventDefault();
        if (!draggedQuickWin || draggedQuickWin === item) {
          return;
        }

        const items = [...quickWinSortList.querySelectorAll("[data-quick-win-sort-item]")];
        const draggedIndex = items.indexOf(draggedQuickWin);
        const targetIndex = items.indexOf(item);
        if (draggedIndex < targetIndex) {
          item.after(draggedQuickWin);
        } else {
          item.before(draggedQuickWin);
        }
        syncQuickWinSortIds();
        setQuickWinSortDirty(true);
      });
    });
  }

  quickWinToggleButtons.forEach((button) => {
    button.addEventListener("click", () => {
      const targetId = button.dataset.target;
      if (!targetId) {
        return;
      }

      const target = document.getElementById(targetId);
      if (!target) {
        return;
      }

      const willOpen = target.hidden;

      document.querySelectorAll("[data-quick-win-edit]").forEach((editForm) => {
        editForm.hidden = true;
      });
      quickWinToggleButtons.forEach((toggle) => {
        toggle.setAttribute("aria-expanded", "false");
        toggle.textContent = "Bearbeiten";
      });

      if (willOpen) {
        target.hidden = false;
        button.setAttribute("aria-expanded", "true");
        button.textContent = "Schließen";
      }
    });
  });

  const pushButton = document.getElementById("pushToggle");
  const pushHint = document.getElementById("pushHint");
  const vapidKey = document.body.dataset.pushKey;
  const isIos = /iphone|ipad|ipod/i.test(window.navigator.userAgent);
  const isStandalone =
    window.matchMedia("(display-mode: standalone)").matches ||
    window.navigator.standalone === true;

  function urlBase64ToUint8Array(base64String) {
    const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
    const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
    const raw = atob(base64);
    return Uint8Array.from([...raw].map((char) => char.charCodeAt(0)));
  }

  async function postJSON(url, payload) {
    const response = await fetch(url, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    });
    return response.json();
  }

  async function togglePush() {
    if (!("serviceWorker" in navigator) || !("PushManager" in window) || !pushButton) {
      return;
    }

    const registration = await navigator.serviceWorker.register("/service-worker.js");
    const existing = await registration.pushManager.getSubscription();

    if (existing) {
      await postJSON("/settings/push/unsubscribe", { endpoint: existing.endpoint });
      await existing.unsubscribe();
      pushButton.dataset.subscribed = "0";
      pushButton.textContent = "Push aktivieren";
      return;
    }

    const permission = await Notification.requestPermission();
    if (permission !== "granted") {
      return;
    }

    const subscription = await registration.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: urlBase64ToUint8Array(vapidKey),
    });
    await postJSON("/settings/push/subscribe", subscription.toJSON());
    pushButton.dataset.subscribed = "1";
    pushButton.textContent = "Push deaktivieren";
  }

  if ("serviceWorker" in navigator) {
    navigator.serviceWorker.register("/service-worker.js").catch(() => {});
  }

  if (pushButton && (!("serviceWorker" in navigator) || !("PushManager" in window))) {
    pushButton.disabled = true;
    if (pushHint) {
      pushHint.textContent = "Dieser Browser unterstützt Web-Push hier aktuell nicht.";
    }
  } else if (pushButton && isIos && !isStandalone) {
    pushButton.disabled = true;
    if (pushHint) {
      pushHint.textContent = "Auf iPhone/iPad funktioniert Web-Push erst nach „Zum Home-Bildschirm“ und Öffnen als Web-App.";
    }
  } else if (pushButton && vapidKey) {
    pushButton.addEventListener("click", () => {
      togglePush().catch((error) => console.error("Push toggle failed", error));
    });
  }

  if (Number.isFinite(celebratePoints) && celebratePoints > 0) {
    celebrateCompletion(celebratePoints);
    clearCelebrationQuery();
  }

  restoreScrollPosition();
})();
