import { resolveButtonSemantics } from "./buttonSemantics";
import { ICON_PATHS } from "./iconMap";

const LEGACY_ICON_CLASSES = [
  "icon-add",
  "icon-edit",
  "icon-delete",
  "icon-close",
  "icon-refresh",
  "icon-reset",
  "icon-save",
  "icon-pass",
  "icon-reject",
  "icon-records",
  "icon-dispose",
  "icon-cost",
  "icon-upload",
  "icon-download",
  "icon-prev",
  "icon-next",
  "icon-open",
  "icon-generate"
];

const ACTION_BUTTON_SELECTOR = [
  "button.primary-button",
  "button.ghost-button",
  "button.link-button",
  "button.workflow-close-button",
  "button.small-button",
  "button.contract-header-button",
  "button.purchase-contract-button"
].join(",");

const SKIP_CONTAINER_SELECTOR = [
  ".pagination-bar",
  ".tags-view-container",
  ".tags-context-menu",
  ".user-menu-dropdown",
  ".global-select-layer",
  ".table-view-mode-switch",
  ".nav-list"
].join(",");

function buttonText(button) {
  const label = button.querySelector(".semantic-action-label");
  return String(label?.textContent || button.textContent || "").replace(/\s+/g, " ").trim();
}

function isTransientLabel(text) {
  return /中(\.{1,3}|…)?$/.test(text) || text.includes("提交中") || text.includes("上传中") || text.includes("导入中");
}

function shouldSkipButton(button) {
  return (
    button.classList.contains("no-auto-icon") ||
    button.classList.contains("icon-button") ||
    button.classList.contains("table-view-mode-button") ||
    button.classList.contains("sortable-th-button") ||
    button.classList.contains("hamburger-container") ||
    button.classList.contains("assistant-bot-button") ||
    button.classList.contains("user-avatar-button") ||
    button.classList.contains("tags-view-open") ||
    button.classList.contains("tags-view-close") ||
    button.classList.contains("pagination-arrow") ||
    button.classList.contains("pagination-page") ||
    button.classList.contains("tag-remove") ||
    button.closest(SKIP_CONTAINER_SELECTOR)
  );
}

function createSemanticIcon(iconName) {
  const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  svg.classList.add("semantic-action-svg");
  svg.setAttribute("viewBox", "0 0 24 24");
  svg.setAttribute("aria-hidden", "true");
  svg.setAttribute("focusable", "false");

  (ICON_PATHS[iconName] || ICON_PATHS.cursorClick || ICON_PATHS.dashboard).forEach((pathValue) => {
    const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
    path.setAttribute("d", pathValue);
    path.setAttribute("fill", "none");
    path.setAttribute("stroke", "currentColor");
    path.setAttribute("stroke-linecap", "round");
    path.setAttribute("stroke-linejoin", "round");
    path.setAttribute("stroke-width", "1.85");
    svg.appendChild(path);
  });

  const icon = document.createElement("span");
  icon.className = "semantic-action-icon";
  icon.appendChild(svg);
  return icon;
}

function setButtonContent(button, semantics) {
  let icon = button.querySelector(".semantic-action-icon");
  let label = button.querySelector(".semantic-action-label");

  if (button.dataset.semanticActionIcon !== semantics.icon || !icon || !label) {
    button.textContent = "";
    icon = createSemanticIcon(semantics.icon);
    label = document.createElement("span");
    label.className = "semantic-action-label";
    button.append(icon, label);
  }

  label.textContent = semantics.label;
}

function clearSemanticButton(button) {
  if (button.dataset.autoSemanticButton !== "true") {
    return;
  }

  const label = button.querySelector(".semantic-action-label")?.textContent || button.textContent;
  button.querySelector(".semantic-action-icon")?.remove();
  button.querySelector(".semantic-action-label")?.replaceWith(document.createTextNode(label));
  button.classList.remove("semantic-action-button");
  delete button.dataset.autoSemanticButton;
  delete button.dataset.buttonKind;
  delete button.dataset.buttonTone;
  delete button.dataset.semanticActionIcon;
}

function enhanceButton(button) {
  LEGACY_ICON_CLASSES.forEach((className) => button.classList.remove(className));

  if (shouldSkipButton(button)) {
    clearSemanticButton(button);
    return;
  }

  const text = buttonText(button);
  if (!text || isTransientLabel(text)) {
    return;
  }

  const semantics = resolveButtonSemantics(text, button.className);
  if (!semantics) {
    clearSemanticButton(button);
    return;
  }

  button.classList.add("semantic-action-button");
  button.dataset.autoSemanticButton = "true";
  button.dataset.buttonKind = semantics.kind;
  button.dataset.buttonTone = semantics.tone;
  button.dataset.semanticActionIcon = semantics.icon;
  setButtonContent(button, semantics);
  button.setAttribute("aria-label", semantics.label);
  if (!button.title || button.dataset.autoIconTitle === "true") {
    button.title = semantics.label;
    button.dataset.autoIconTitle = "true";
  }
}

function scanActionButtons(root = document) {
  if (root instanceof HTMLButtonElement && root.matches(ACTION_BUTTON_SELECTOR)) {
    enhanceButton(root);
  }
  root.querySelectorAll?.(ACTION_BUTTON_SELECTOR).forEach(enhanceButton);
}

export function setupActionIconButtons() {
  scanActionButtons();

  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      if (mutation.type === "characterData") {
        const parent = mutation.target.parentElement;
        if (parent) {
          scanActionButtons(parent);
        }
        return;
      }

      if (mutation.target instanceof Element) {
        scanActionButtons(mutation.target);
      }
      mutation.addedNodes.forEach((node) => {
        if (node instanceof Element) {
          scanActionButtons(node);
        }
      });
    });
  });

  observer.observe(document.body, {
    childList: true,
    subtree: true,
    characterData: true
  });

  return () => observer.disconnect();
}
