console.log("[Translator] content script loaded");

// 英文检测正则（包含短句）
const EN_TEXT_REGEX = /[A-Za-z][A-Za-z0-9 ,.'"?!:;()\-\n\r]{3,}/;

// 忽略以下标签中的文本
const SKIP_TAGS = new Set(["SCRIPT", "STYLE", "CODE", "PRE", "TEXTAREA", "INPUT", "BUTTON", "SVG", "CANVAS"]);
const ALLOWED_TAGS = new Set(["P", "H1", "H2", "H3", "H4", "H5", "H6"]);

// 缓存避免重复翻译
const cache = new Map();

// 批处理队列
let pendingNodes = [];
let translateTimer = null;

let translationEnabled = false;

// 收集文本节点
function walkAndCollect(node) {
  const walker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, {
    acceptNode(textNode) {
      const parent = textNode.parentElement;
      if (!parent || SKIP_TAGS.has(parent.tagName) || !ALLOWED_TAGS.has(parent.tagName)) {
        return NodeFilter.FILTER_REJECT;
      }

      const text = textNode.nodeValue.trim();

      // 非英文 / 太短 / 纯数字，跳过
      if (!EN_TEXT_REGEX.test(text)) {
        return NodeFilter.FILTER_REJECT;
      }

      return NodeFilter.FILTER_ACCEPT;
    },
  });

  let current;
  while ((current = walker.nextNode())) {
    pendingNodes.push(current);
  }
}

function restoreTranslations() {
  const wrappers = document.querySelectorAll(".translation-wrapper");

  wrappers.forEach((wrapper) => {
    const original = wrapper.dataset.originalText;
    if (!original) return;

    const textNode = document.createTextNode(original);

    // 用原始文本替换 wrapper
    if (wrapper.parentNode) {
      wrapper.parentNode.replaceChild(textNode, wrapper);
    }
  });
}

// 把翻译写回页面（英文保留 + 模糊，中文显示在下方）
function applyTranslations(resultMap) {
  pendingNodes.forEach((node) => {
    if (!node || !node.parentNode) return;

    const text = node.nodeValue.trim();
    const zh = resultMap[text];

    if (!zh) return;
    if (node.__translated) return;

    const wrapper = document.createElement("span");
    wrapper.className = "translation-wrapper";

    // 保存原始文本，供恢复用
    wrapper.dataset.originalText = text;

    const originalSpan = document.createElement("span");
    originalSpan.className = "original-blur";
    originalSpan.textContent = text;

    const zhSpan = document.createElement("span");
    zhSpan.className = "translated-zh";
    zhSpan.textContent = zh;

    wrapper.appendChild(originalSpan);
    wrapper.appendChild(document.createElement("br"));
    wrapper.appendChild(zhSpan);

    node.parentNode.replaceChild(wrapper, node);

    wrapper.__translated = true; // 标记为已翻译

    requestAnimationFrame(() => {
      void wrapper.offsetHeight;
      wrapper.classList.add("show");
    });
  });

  pendingNodes = [];
}

function toggleTranslation(result) {
  if (translationEnabled) {
    restoreTranslations();
  } else {
    applyTranslations(result);
  }
  translationEnabled = !translationEnabled;
  chrome.runtime.sendMessage({ type: "TRANSLATE_STATE", state: translationEnabled }, () => {
    // Access lastError to prevent "Unchecked runtime.lastError" when no listener is ready.
    void chrome.runtime.lastError;
  });
}

// 触发批量翻译
function flushTranslations() {
  if (pendingNodes.length === 0) return;

  const texts = Array.from(new Set(pendingNodes.map((n) => n.nodeValue.trim()).filter((t) => t.length > 0)));

  const uncached = texts.filter((t) => !cache.has(t));

  if (uncached.length === 0) {
    // 全部来自缓存
    const map = {};
    texts.forEach((t) => (map[t] = cache.get(t)));
    // applyTranslations(map);
    return;
  }

  chrome.runtime.sendMessage({
    url: window.location.href,
    type: "BATCH_TRANSLATE",
    texts: uncached,
    from: "en",
    to: "zh",
  });
}

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === "BATCH_TRANSLATE_FINISHED") {
    const result = message.payload.result;
    Object.entries(result).forEach(([src, zh]) => {
      cache.set(src, zh);
    });

    toggleTranslation(result);
  }
});

chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
  if (message.type === "START_TRANSLATE") {
    walkAndCollect(document.body);
    flushTranslations();
  }
});

window.addEventListener("visibilitychange", () => {
  chrome.runtime.sendMessage({ type: "TRANSLATE_STATE", state: translationEnabled }, () => {
    void chrome.runtime.lastError;
  });
});
