(() => {
  if (!window.LumiPage) return;

  window.LumiPage.register("command-policies", {
    selector: "[data-command-policies]",
    mount(root, { signal }) {
      const normalizeSearch = (value) => String(value || "").toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
      const editDistance = (left, right) => {
        const row = Array.from({ length: right.length + 1 }, (_, index) => index);
        for (let i = 1; i <= left.length; i += 1) {
          let diagonal = row[0];
          row[0] = i;
          for (let j = 1; j <= right.length; j += 1) {
            const above = row[j];
            row[j] = Math.min(row[j] + 1, row[j - 1] + 1, diagonal + (left[i - 1] === right[j - 1] ? 0 : 1));
            diagonal = above;
          }
        }
        return row[right.length];
      };
      const searchScore = (query, text) => {
        const desired = normalizeSearch(query);
        const candidate = normalizeSearch(text);
        if (!desired || candidate.includes(desired)) return 1;
        const words = candidate.split(" ").filter(Boolean);
        if (words.some((word) => word.startsWith(desired))) return 0.92;
        return words.reduce((best, word) => Math.max(best, 1 - editDistance(desired, word) / Math.max(desired.length, word.length, 1)), 0);
      };
      const refreshSearchScope = (scope) => {
        const query = scope.querySelector("[data-policy-search]")?.value || "";
        const setting = scope.querySelector("[data-policy-setting-filter]")?.value || "";
        const origin = scope.querySelector("[data-policy-origin-filter]")?.value || "";
        const items = Array.from(scope.querySelectorAll("[data-policy-item]"));
        const ranked = [];
        let shown = 0;
        items.forEach((item) => {
          const score = searchScore(query, item.dataset.search || "");
          const threshold = normalizeSearch(query).length <= 3 ? 0.82 : 0.62;
          const matchesSetting = !setting || (item.dataset.settings || "").split(" ").includes(setting);
          const matchesOrigin = !origin || item.dataset.origin === origin;
          item.hidden = !((!normalizeSearch(query) || score >= threshold) && matchesSetting && matchesOrigin);
          if (!item.hidden) shown += 1;
          if (matchesSetting && matchesOrigin && score >= threshold) ranked.push({ item, score });
        });
        const count = scope.querySelector("[data-policy-result-count]");
        if (count) count.textContent = `Showing ${shown} of ${items.length}`;
        const noResults = scope.querySelector("[data-policy-no-results]");
        if (noResults) noResults.hidden = shown !== 0;
        const suggestions = scope.querySelector("[data-policy-suggestions]");
        if (!suggestions) return;
        suggestions.replaceChildren();
        if (normalizeSearch(query)) {
          ranked.sort((left, right) => right.score - left.score).slice(0, 5).forEach(({ item }) => {
            const button = document.createElement("button");
            button.type = "button";
            button.textContent = item.dataset.searchName || "Match";
            button.dataset.policySuggestion = item.dataset.searchName || "";
            suggestions.append(button);
          });
        }
        suggestions.hidden = !suggestions.children.length;
      };

      const parsePolicyData = (value) => { try { return JSON.parse(value || "{}"); } catch { return {}; } };
      const hasPolicyCategory = (policy, name) => Object.prototype.hasOwnProperty.call(policy || {}, name);
      const roleLabel = (value = {}) => value.role === "subscriber"
        ? (Number(value.subscriberTier) > 1 ? `Tier ${value.subscriberTier}+ subscribers` : "Subscribers / members")
        : ({ follower: "Followers", vip: "VIPs", mod: "Moderators", editor: "Editors", streamer: "Streamer only" })[value.role] || "Everyone";
      const ruleText = (name, value) => {
        if (name === "window") return `${value.uses} use${Number(value.uses) === 1 ? "" : "s"} per ${value.seconds} seconds, ${value.scope === "global" ? "shared by everyone" : "per user"}`;
        if (name === "perStream") return `${value.uses} use${Number(value.uses) === 1 ? "" : "s"} per stream, ${value.scope === "global" ? "shared by everyone" : "per user"}`;
        if (name === "requirement") return roleLabel(value);
        if (name === "cost") return `${value.amount} currency per successful run.`;
        return "";
      };
      const emptyRuleText = (name) => ({ window: "No time-window limit.", perStream: "No per-stream limit.", requirement: "Everyone may use it.", cost: "Free to use." })[name];
      const refreshInheritedSummaries = (editor) => {
        const builtIn = parsePolicyData(editor.dataset.builtInPolicy);
        const globalDefault = parsePolicyData(editor.dataset.defaultGroupPolicy);
        const selected = Array.from(editor.querySelectorAll("input[data-group-policy]:checked")).map((input) => ({
          name: input.dataset.groupName || "Group",
          policy: parsePolicyData(input.dataset.groupPolicy)
        }));
        for (const name of ["window", "perStream", "requirement", "cost"]) {
          const summary = editor.querySelector(`[data-policy-inherited="${name}"] strong`);
          if (!summary) continue;
          const positive = selected.filter((item) => hasPolicyCategory(item.policy, name) && item.policy[name] && item.policy[name] !== false)
            .map((item) => ({ source: item.name, value: item.policy[name] }));
          const defaultHas = hasPolicyCategory(globalDefault, name);
          if (defaultHas && globalDefault[name] && globalDefault[name] !== false) positive.push({ source: "Default group", value: globalDefault[name] });
          if (name === "cost" && positive.length) {
            const highest = positive.reduce((best, item) => Number(item.value.amount) > Number(best.value.amount) ? item : best);
            summary.textContent = `${highest.source}: ${ruleText(name, highest.value)}`;
          } else if (positive.length) summary.textContent = positive.map((item) => `${item.source}: ${ruleText(name, item.value)}`).join(" · ");
          else if (defaultHas && globalDefault[name] === false) summary.textContent = emptyRuleText(name);
          else if (builtIn[name] && builtIn[name] !== false) summary.textContent = `Built-in: ${ruleText(name, builtIn[name])}`;
          else summary.textContent = emptyRuleText(name);
        }
      };
      const updatePolicyCategory = (category) => {
        const mode = category.querySelector("[data-policy-mode]")?.value || "off";
        const values = category.querySelector("[data-policy-values]");
        const inherited = category.querySelector("[data-policy-inherited]");
        if (values) values.hidden = mode !== "custom";
        if (inherited) inherited.hidden = mode !== "inherit";
        const tier = category.querySelector("[data-subscriber-tier]");
        if (tier) tier.hidden = mode !== "custom" || category.querySelector("[data-requirement-role]")?.value !== "subscriber";
      };

      root.querySelectorAll("[data-policy-search-scope]").forEach(refreshSearchScope);
      root.querySelectorAll("[data-command-policy-editor]").forEach(refreshInheritedSummaries);
      root.querySelectorAll("[data-policy-category]").forEach(updatePolicyCategory);

      root.addEventListener("input", (event) => {
        const scope = event.target.closest("[data-policy-search-scope]");
        if (event.target.matches("[data-policy-search]")) refreshSearchScope(scope);
        const batch = event.target.closest("[data-command-policy-batch]");
        const state = batch?.querySelector("[data-command-save-state]");
        if (state) state.textContent = "Unsaved command changes.";
      }, { signal });
      root.addEventListener("change", (event) => {
        const scope = event.target.closest("[data-policy-search-scope]");
        if (scope && event.target.matches("[data-policy-setting-filter], [data-policy-origin-filter]")) refreshSearchScope(scope);
        const category = event.target.closest("[data-policy-category]");
        if (category && event.target.matches("[data-policy-mode], [data-requirement-role]")) updatePolicyCategory(category);
        const editor = event.target.closest("[data-command-policy-editor]");
        if (editor && event.target.matches("input[data-group-policy]")) refreshInheritedSummaries(editor);
        const batch = event.target.closest("[data-command-policy-batch]");
        const state = batch?.querySelector("[data-command-save-state]");
        if (state) state.textContent = "Unsaved command changes.";
      }, { signal });
      root.addEventListener("keydown", (event) => {
        if (event.key === "Escape" && event.target.matches("[data-policy-search]")) {
          const suggestions = event.target.closest("[data-policy-search-scope]")?.querySelector("[data-policy-suggestions]");
          if (suggestions) suggestions.hidden = true;
        }
      }, { signal });
      root.addEventListener("click", (event) => {
        const suggestion = event.target.closest("[data-policy-suggestion]");
        if (!suggestion) return;
        const scope = suggestion.closest("[data-policy-search-scope]");
        const input = scope?.querySelector("[data-policy-search]");
        if (!input) return;
        input.value = suggestion.dataset.policySuggestion;
        suggestion.parentElement.hidden = true;
        refreshSearchScope(scope);
        const item = Array.from(scope.querySelectorAll("[data-policy-item]")).find((candidate) => candidate.dataset.searchName === input.value);
        if (item) {
          item.open = true;
          item.scrollIntoView({ block: "nearest", behavior: "smooth" });
        }
      }, { signal });
      root.addEventListener("lumi:form-saved", (event) => {
        if (event.target.matches("[data-command-policy-batch]")) {
          const state = event.target.querySelector("[data-command-save-state]");
          if (state) state.textContent = event.detail?.message || "All displayed values are saved.";
        }
        if (event.target.matches("[data-command-group-form]") && event.detail?.data?.group) {
          const group = event.detail.data.group;
          const details = event.target.closest("[data-policy-item]");
          const title = details?.querySelector(":scope > summary strong");
          const description = details?.querySelector(":scope > summary .hint");
          if (title) title.textContent = group.name;
          if (description) description.textContent = group.description || "Reusable command rules";
          if (details) {
            details.dataset.searchName = group.name;
            details.dataset.search = `${group.name} ${group.description || ""}`.toLowerCase();
            details.dataset.settings = Object.keys(group.policy || {}).map((name) => ({ window: "rate", perStream: "stream", requirement: "access", cost: "cost" })[name]).filter(Boolean).join(" ");
          }
          if (group.is_default) {
            root.querySelectorAll("[data-command-policy-editor]").forEach((editor) => {
              editor.dataset.defaultGroupPolicy = JSON.stringify(group.policy || {});
              refreshInheritedSummaries(editor);
            });
          } else {
            root.querySelectorAll("input[data-group-policy]").forEach((input) => {
              if (input.value !== group.id) return;
              input.dataset.groupName = group.name;
              input.dataset.groupPolicy = JSON.stringify(group.policy || {});
              refreshInheritedSummaries(input.closest("[data-command-policy-editor]"));
            });
          }
          const scope = details?.closest("[data-policy-search-scope]");
          if (scope) refreshSearchScope(scope);
        }
      }, { signal });
    }
  });
})();
