// Tailwind-styled tags input (vanilla JS). Enhance any <input.tw-tags>
(function () {
  class TailwindTagsInput {
    constructor(input, options = {}) {
      this.originalInput = input;
      this.options = {
        separator: options.separator || input.dataset.separator || ",",
        maxTags: parseInt(options.maxTags || input.dataset.maxTags || "50", 10),
        suggestions: options.suggestions || this.parseSuggestions(input.dataset.availableTags),
      };
      this.tags = [];
      this.init();
    }

    parseSuggestions(value) {
      if (!value) return [];
      try {
        const parsed = JSON.parse(value);
        if (Array.isArray(parsed)) {
          return parsed.map((tag) => String(tag).trim()).filter(Boolean);
        }
      } catch (e) {
        return value.split(",").map((tag) => tag.trim()).filter(Boolean);
      }
      return [];
    }

    init() {
      const initial = this.originalInput.value || "";
      if (initial) {
        this.tags = initial
          .split(this.options.separator)
          .map((t) => t.trim())
          .filter(Boolean);
      }
      this.tags = this.uniqueTags(this.tags);
      this.options.suggestions = this.uniqueTags([
        ...this.tags,
        ...this.options.suggestions,
      ]);

      this.wrapper = document.createElement("div");
      this.wrapper.className =
        "tw-tags-wrapper relative flex flex-wrap items-center gap-2 p-2 min-h-[42px] cursor-text rounded-lg border border-slate-300 dark:border-slate-700 bg-white dark:bg-slate-900 focus-within:ring-1 focus-within:ring-slate-300 dark:focus-within:ring-slate-600 focus-within:border-slate-400 dark:focus-within:border-slate-600 transition-all";

      this.input = document.createElement("input");
      this.input.type = "text";
      this.input.className =
        "flex-1 min-w-[120px] bg-transparent outline-none text-sm text-slate-700 dark:text-slate-100 placeholder-slate-400 dark:placeholder-slate-500";
      this.input.placeholder =
        this.originalInput.getAttribute("placeholder") || "Add a tag...";

      this.menu = document.createElement("div");
      this.menu.className =
        "tw-tags-menu absolute left-0 right-0 top-full z-50 mt-1 hidden max-h-56 overflow-auto rounded-lg border border-slate-200 bg-white p-1 shadow-lg dark:border-slate-700 dark:bg-slate-900";

      this.originalInput.style.display = "none";
      this.originalInput.parentNode.insertBefore(
        this.wrapper,
        this.originalInput.nextSibling
      );
      this.wrapper.appendChild(this.input);
      this.wrapper.appendChild(this.menu);

      this.tags.forEach((tag) => this.createTagElement(tag, false));
      this.updateOriginal();
      this.bindEvents();
    }

    uniqueTags(tags) {
      const seen = new Set();
      return tags.reduce((result, value) => {
        const tag = String(value).trim();
        const key = tag.toLowerCase();
        if (tag && !seen.has(key)) {
          seen.add(key);
          result.push(tag);
        }
        return result;
      }, []);
    }

    bindEvents() {
      this.wrapper.addEventListener("click", () => this.input.focus());

      this.input.addEventListener("keydown", (e) => {
        if (e.key === "Enter" || e.key === this.options.separator) {
          e.preventDefault();
          this.addTag(this.input.value);
        } else if (e.key === "Backspace" && this.input.value === "") {
          this.removeLastTag();
        } else if (e.key === "Escape") {
          this.hideSuggestions();
        }
      });

      this.input.addEventListener("input", () => this.renderSuggestions());
      this.input.addEventListener("focus", () => this.renderSuggestions());

      this.input.addEventListener("blur", () => {
        window.setTimeout(() => {
          if (this.input.value) this.addTag(this.input.value);
          this.hideSuggestions();
        }, 120);
      });
    }

    createTagElement(text, animate = true) {
      const tagEl = document.createElement("span");
      tagEl.className =
        "tag-item inline-flex items-center gap-1.5 px-3 py-1 bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 text-sm font-medium rounded-full border border-blue-100 dark:border-blue-800";
      if (!animate) tagEl.style.animation = "none";

      const span = document.createElement("span");
      span.innerText = text;

      const removeBtn = document.createElement("button");
      removeBtn.type = "button";
      removeBtn.className =
        "w-4 h-4 flex items-center justify-center rounded-full hover:bg-blue-200 dark:hover:bg-blue-800 text-blue-400 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-200 transition-colors focus:outline-none";
      removeBtn.innerHTML =
        '<svg class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M6 6l12 12M6 18L18 6" /></svg>';
      removeBtn.onclick = (e) => {
        e.stopPropagation();
        this.removeTagElement(tagEl, text);
      };

      tagEl.append(span, removeBtn);
      this.wrapper.insertBefore(tagEl, this.input);
    }

    addTag(text) {
      const tag = text.trim();
      if (!tag) return;
      if (this.tags.some((existing) => existing.toLowerCase() === tag.toLowerCase())) {
        this.input.value = "";
        this.hideSuggestions();
        return;
      }
      if (this.tags.length >= this.options.maxTags) return;

      this.tags.push(tag);
      this.options.suggestions = this.uniqueTags([...this.options.suggestions, tag]);
      this.createTagElement(tag, true);
      this.input.value = "";
      this.input.placeholder = this.tags.length ? "" : this.originalInput.getAttribute("placeholder") || "Add a tag...";
      this.hideSuggestions();
      this.updateOriginal();
    }

    removeTagElement(el, tagText) {
      el.remove();
      this.tags = this.tags.filter((t) => t !== tagText);
      if (!this.tags.length) this.input.placeholder = this.originalInput.getAttribute("placeholder") || "Add a tag...";
      this.updateOriginal();
      this.input.focus();
      this.renderSuggestions();
    }

    removeLastTag() {
      if (!this.tags.length) return;
      const last = this.tags[this.tags.length - 1];
      const nodes = this.wrapper.querySelectorAll(".tag-item");
      if (nodes.length) {
        this.removeTagElement(nodes[nodes.length - 1], last);
      }
    }

    renderSuggestions() {
      if (!this.menu) return;
      const query = this.input.value.trim().toLowerCase();
      const selected = new Set(this.tags.map((tag) => tag.toLowerCase()));
      const matches = this.options.suggestions
        .filter((tag) => !selected.has(tag.toLowerCase()))
        .filter((tag) => !query || tag.toLowerCase().includes(query))
        .slice(0, 10);

      this.menu.innerHTML = "";
      if (!matches.length) {
        this.hideSuggestions();
        return;
      }

      matches.forEach((tag) => {
        const item = document.createElement("button");
        item.type = "button";
        item.className =
          "flex w-full items-center justify-between rounded-md px-3 py-2 text-left text-sm font-medium text-slate-700 hover:bg-slate-100 dark:text-slate-200 dark:hover:bg-slate-800";
        item.innerText = tag;
        item.addEventListener("mousedown", (e) => {
          e.preventDefault();
          this.addTag(tag);
        });
        this.menu.appendChild(item);
      });
      this.menu.classList.remove("hidden");
    }

    hideSuggestions() {
      if (this.menu) {
        this.menu.classList.add("hidden");
      }
    }

    updateOriginal() {
      this.originalInput.value = this.tags.join(this.options.separator + " ");
      this.originalInput.dispatchEvent(new Event("change"));
    }
  }

  function initTags(root) {
    root = root || document;
    const fields = root.matches && root.matches("input.tw-tags")
      ? [root]
      : root.querySelectorAll("input.tw-tags");
    fields.forEach((el) => {
      if (!el.dataset.enhanced) {
        el.dataset.enhanced = "true";
        new TailwindTagsInput(el);
      }
    });
  }

  window.initTags = initTags;

  if (document.readyState === "interactive" || document.readyState === "complete") {
    initTags();
  } else {
    document.addEventListener("DOMContentLoaded", initTags);
  }
})();
