let outsideHandlerBound = false;

function bindOutsideHandler($) {
  if (outsideHandlerBound) {
    return;
  }

  outsideHandlerBound = true;

  $(document).on("mousedown.b3wvsCustomSelect", function (event) {
    $(".b3-wvs-legacy-select.is-open").each(function () {
      if (!this.contains(event.target)) {
        closeLegacySelect(this);
      }
    });
  });
}

function closeLegacySelect(container) {
  if (!container) {
    return;
  }

  container.classList.remove("is-open");
  const trigger = container.querySelector(".b3-wvs-legacy-select-trigger");
  if (trigger) {
    trigger.setAttribute("aria-expanded", "false");
  }
}

function openLegacySelect(container) {
  if (!container) {
    return;
  }

  document
    .querySelectorAll(".b3-wvs-legacy-select.is-open")
    .forEach((other) => closeLegacySelect(other));
  container.classList.add("is-open");
  const trigger = container.querySelector(".b3-wvs-legacy-select-trigger");
  if (trigger) {
    trigger.setAttribute("aria-expanded", "true");
  }
}

function notifyLegacySelectChange(select, $) {
  if (!select) {
    return;
  }

  const jq =
    typeof window.jQuery === "function"
      ? window.jQuery
      : typeof $ === "function"
        ? $
        : null;

  if (jq) {
    jq(select).trigger("change");
    return;
  }

  select.dispatchEvent(new Event("change", { bubbles: true }));
}

function renderLegacySelect(select) {
  const container = select.nextElementSibling;
  if (!container || !container.classList.contains("b3-wvs-legacy-select")) {
    return;
  }

  const trigger = container.querySelector(".b3-wvs-legacy-select-trigger");
  const label = container.querySelector(".b3-wvs-legacy-select-label");
  const menu = container.querySelector(".b3-wvs-legacy-select-menu");
  if (!trigger || !label || !menu) {
    return;
  }

  const options = Array.from(select.options).map((option) => ({
    value: String(option.value),
    label: String(option.textContent || "").trim(),
    disabled: option.disabled,
  }));

  const selectedOption =
    options.find((option) => option.value === String(select.value)) ||
    options[0];
  label.textContent = selectedOption?.label || "";

  menu.innerHTML = "";

  options.forEach((option, index) => {
    if (option.disabled) {
      return;
    }

    const item = document.createElement("li");
    const isSelected = option.value === String(select.value);
    item.id = `${select.id || select.name || "b3-wvs-select"}-option-${index}`;
    item.setAttribute("role", "option");
    item.setAttribute("aria-selected", isSelected ? "true" : "false");
    item.className = `b3-wvs-legacy-select-option${isSelected ? " is-selected" : ""}`;
    item.tabIndex = -1;
    item.innerHTML = `
      <span class="b3-wvs-legacy-select-label">${option.label}</span>
      ${
        isSelected
          ? `<svg class="b3-wvs-legacy-select-check" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
               <path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 0 1 .143 1.052l-8 10.5a.75.75 0 0 1-1.127.075l-4.5-4.5a.75.75 0 0 1 1.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 0 1 1.05-.143Z" clip-rule="evenodd" />
             </svg>`
          : ""
      }
    `;

    item.addEventListener("mouseenter", function () {
      menu
        .querySelectorAll(".b3-wvs-legacy-select-option.is-focused")
        .forEach((node) => node.classList.remove("is-focused"));
      item.classList.add("is-focused");
    });

    item.addEventListener("mousedown", function (event) {
      event.preventDefault();
      select.value = option.value;
      notifyLegacySelectChange(select, $);
      renderLegacySelect(select);
      closeLegacySelect(container);
      trigger.focus();
    });

    menu.appendChild(item);
  });
}

function attachLegacySelect(select, $) {
  if (select.dataset.b3WvsLegacySelect === "1") {
    renderLegacySelect(select);
    return;
  }

  select.dataset.b3WvsLegacySelect = "1";
  select.classList.add("b3-wvs-legacy-select-native");

  const container = document.createElement("div");
  container.className = "b3-wvs-legacy-select";

  const trigger = document.createElement("button");
  trigger.type = "button";
  trigger.className = "b3-wvs-legacy-select-trigger";
  trigger.setAttribute("aria-haspopup", "listbox");
  trigger.setAttribute("aria-expanded", "false");
  trigger.innerHTML = `
    <span class="b3-wvs-legacy-select-label"></span>
    <svg class="b3-wvs-legacy-select-chevron" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
      <path fill-rule="evenodd" d="M5.22 8.22a.75.75 0 0 1 1.06 0L10 11.94l3.72-3.72a.75.75 0 1 1 1.06 1.06l-4.25 4.25a.75.75 0 0 1-1.06 0L5.22 9.28a.75.75 0 0 1 0-1.06Z" clip-rule="evenodd" />
    </svg>
  `;

  const menu = document.createElement("ul");
  menu.className = "b3-wvs-legacy-select-menu";
  menu.setAttribute("role", "listbox");

  trigger.addEventListener("click", function () {
    if (container.classList.contains("is-open")) {
      closeLegacySelect(container);
      return;
    }

    openLegacySelect(container);
  });

  trigger.addEventListener("keydown", function (event) {
    const items = Array.from(
      menu.querySelectorAll(".b3-wvs-legacy-select-option"),
    );
    const focusedIndex = items.findIndex((item) =>
      item.classList.contains("is-focused"),
    );

    if (event.key === "ArrowDown") {
      event.preventDefault();
      if (!container.classList.contains("is-open")) {
        openLegacySelect(container);
      }
      const nextIndex =
        focusedIndex >= 0 ? Math.min(focusedIndex + 1, items.length - 1) : 0;
      items.forEach((item) => item.classList.remove("is-focused"));
      if (items[nextIndex]) {
        items[nextIndex].classList.add("is-focused");
        items[nextIndex].scrollIntoView({ block: "nearest" });
      }
      return;
    }

    if (event.key === "ArrowUp") {
      event.preventDefault();
      if (!container.classList.contains("is-open")) {
        openLegacySelect(container);
      }
      const nextIndex =
        focusedIndex >= 0 ? Math.max(focusedIndex - 1, 0) : items.length - 1;
      items.forEach((item) => item.classList.remove("is-focused"));
      if (items[nextIndex]) {
        items[nextIndex].classList.add("is-focused");
        items[nextIndex].scrollIntoView({ block: "nearest" });
      }
      return;
    }

    if (event.key === "Enter" || event.key === " ") {
      event.preventDefault();
      if (!container.classList.contains("is-open")) {
        openLegacySelect(container);
        return;
      }

      const target =
        items[focusedIndex] ||
        menu.querySelector(".b3-wvs-legacy-select-option.is-selected");
      target?.dispatchEvent(new MouseEvent("mousedown", { bubbles: true }));
      return;
    }

    if (event.key === "Escape") {
      closeLegacySelect(container);
    }
  });

  container.appendChild(trigger);
  container.appendChild(menu);
  select.insertAdjacentElement("afterend", container);

  $(select).on("change.b3wvsLegacySelect", function () {
    renderLegacySelect(select);
  });

  renderLegacySelect(select);
}

export function initLegacyCustomSelects($, context, selector) {
  bindOutsideHandler($);

  const $context = context ? $(context) : $(document);
  $context.find(selector).each(function () {
    if ($(this).hasClass("select2-hidden-accessible")) {
      return;
    }

    attachLegacySelect(this, $);
  });
}
