/* STONK — nối lại lượt nạp từ nguồn ngoài bằng thông tin người dùng lưu cho phiên Chrome hiện tại.
 * Chỉ hoạt động trên trang đăng nhập nguồn ngoài; có thể tắt từ checkpoint của công cụ nạp.
 * Thông tin đăng nhập được lấy từ background, không ghi vào storage.local và không xử lý CAPTCHA.
 */
(function () {
  if (window.top !== window || window.__STONK_EXTERNAL_SOURCE_AUTO_LOGIN__) return;
  window.__STONK_EXTERNAL_SOURCE_AUTO_LOGIN__ = true;
  const EXTERNAL_IMPORT_STATE_KEY = "stonk_external_source_full_import";
  const LEGACY_EXTERNAL_STATE_KEY = ["stonk", "ka" + "lo", "full", "import"].join("_");
  const CREDENTIALS_GET_MESSAGE = "STONK_EXT_LOGIN_CREDENTIALS_GET";

  const visible = element => {
    if (!element) return false;
    const box = element.getBoundingClientRect();
    const style = getComputedStyle(element);
    return box.width > 0 && box.height > 0 && style.display !== "none" && style.visibility !== "hidden";
  };
  const text = element => String(element?.textContent || "").replace(/\s+/g, " ").trim();
  const canClick = element => {
    if (!element || !visible(element) || element.disabled) return false;
    if (element.getAttribute("aria-disabled") === "true") return false;
    if (element.classList && (element.classList.contains("is-loading") || element.classList.contains("ant-btn-loading") || element.classList.contains("arco-btn-loading"))) return false;
    return true;
  };

  const attemptedRecently = (key, cooldownMs = 2000) => {
    const now = Date.now();
    const last = Number(sessionStorage.getItem(key) || 0);
    if (now - last < cooldownMs) return true;
    sessionStorage.setItem(key, String(now));
    return false;
  };

  function isLoginPage() {
    const host = location.hostname.toLowerCase();
    const path = location.pathname.toLowerCase();
    const search = location.search.toLowerCase();
    const externalLoginHostPrefix = ["login", ["ka", "lo"].join("")].join(".");
    if (host.includes(externalLoginHostPrefix) || path.includes("/login") || path.includes("/signin") || search.includes("redirect_url=")) {
      return true;
    }
    const body = text(document.body);
    if (/Chào mừng trở lại|Đăng nhập|Chọn tài khoản/i.test(body)) {
      return true;
    }
    return false;
  }

  function findSavedAccount() {
    // 1. Tìm các phần tử có chứa số điện thoại hoặc định dạng tài khoản
    const allClickable = Array.from(document.querySelectorAll("button, a, [role='button'], div, li, tr, span, p"))
      .filter(canClick)
      .filter(element => {
        const t = text(element);
        if (!t || t.length > 80) return false;
        if (/Sử dụng tài khoản khác|Thêm tài khoản|Đăng ký|Sign up|Register/i.test(t)) return false;
        if (/(?:PHONE|SĐT|Số điện thoại|\+84)\s*[:\s]/i.test(t)) return true;
        if (/\b0[35789]\d{8}\b/.test(t)) return true;
        if (/[\w.-]+@[\w.-]+\.\w+/.test(t)) return true;
        return false;
      });

    if (allClickable.length > 0) {
      return allClickable.sort((a, b) => a.getBoundingClientRect().height - b.getBoundingClientRect().height)[0];
    }

    // 2. Tìm thẻ tài khoản theo class
    const card = Array.from(document.querySelectorAll("[class*='account'], [class*='user-item'], [class*='card']"))
      .filter(canClick)
      .find(el => !/Sử dụng tài khoản khác/i.test(text(el)));
    return card || null;
  }

  function findContinueButton() {
    return Array.from(document.querySelectorAll("button, input[type='submit'], [role='button'], div[class*='button'], a[class*='button']"))
      .filter(canClick)
      .find(element => /^(?:Tiếp\s*tục|Continue|Next)$/i.test(text(element))) || null;
  }

  function findUseAnotherAccountButton() {
    return Array.from(document.querySelectorAll("button, a, [role='button'], div[class*='button']"))
      .filter(canClick)
      .find(element => /Sử dụng tài khoản khác|Thêm tài khoản|Use another account|Add account/i.test(text(element))) || null;
  }

  function findPasswordInput() {
    return Array.from(document.querySelectorAll("input[type='password'], input[name*='password' i], input[placeholder*='mật khẩu' i], input[placeholder*='password' i]"))
      .find(visible) || null;
  }

  function findAccountInput() {
    return Array.from(document.querySelectorAll("input:not([type='password']):not([type='hidden']):not([type='checkbox']):not([type='radio'])"))
      .filter(visible)
      .find(inp => /phone|email|user|tài khoản|số điện thoại/i.test(inp.name || inp.id || inp.placeholder || "")) || null;
  }

  function switchAccountModeIfNeeded(account) {
    const input = findAccountInput();
    if (!input) return false;
    const hint = `${input.type || ""} ${input.name || ""} ${input.id || ""} ${input.placeholder || ""}`;
    const wantsEmail = account.includes("@");
    const currentIsEmail = /email|e-mail/i.test(hint);
    if (wantsEmail === currentIsEmail) return false;
    const labelPattern = wantsEmail ? /^(?:E-mail|Email)$/i : /^(?:Số điện thoại|Phone)$/i;
    const target = Array.from(document.querySelectorAll("button, [role='tab'], [role='button'], div, span"))
      .filter(canClick)
      .filter(element => labelPattern.test(text(element)))
      .sort((a, b) => a.getBoundingClientRect().width - b.getBoundingClientRect().width)[0];
    if (!target) return false;
    target.click();
    return true;
  }

  function findLoginButton() {
    const pwdInput = findPasswordInput();
    const candidates = Array.from(document.querySelectorAll("button, input[type='submit'], [role='button'], div[class*='button'], a[class*='button']"))
      .filter(canClick)
      .filter(el => {
        const t = text(el).trim();
        if (!/Đăng\s*nhập|Log\s*in|Sign\s*in/i.test(t)) return false;
        if (/Đăng\s*ký|Register|Sign\s*up/i.test(t)) return false;
        return true;
      });

    if (candidates.length > 0) {
      if (pwdInput) {
        const afterPwd = candidates.filter(btn => (pwdInput.compareDocumentPosition(btn) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0);
        if (afterPwd.length > 0) return afterPwd[0];
      }
      return candidates[0];
    }

    if (pwdInput) {
      const form = pwdInput.closest("form") || document;
      const submitBtn = Array.from(form.querySelectorAll("button[type='submit'], button[class*='primary'], button[class*='blue'], button[class*='submit']")).find(canClick);
      if (submitBtn) return submitBtn;
    }

    return null;
  }

  function setNativeInputValue(input, value) {
    if (!input || typeof value !== "string") return false;
    const descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value");
    if (!descriptor?.set) return false;
    descriptor.set.call(input, value);
    input.dispatchEvent(new InputEvent("input", { bubbles: true, composed: true, inputType: "insertText" }));
    input.dispatchEvent(new Event("change", { bubbles: true, composed: true }));
    return true;
  }

  async function getSessionCredentials() {
    try {
      const response = await chrome.runtime.sendMessage({ type: CREDENTIALS_GET_MESSAGE });
      const account = typeof response?.credentials?.account === "string" ? response.credentials.account.trim() : "";
      const password = typeof response?.credentials?.password === "string" ? response.credentials.password : "";
      if (!response?.ok || !account || !password) return null;
      return { account, password, savedAt: Number(response.credentials.savedAt) || 0 };
    } catch {
      return null;
    }
  }

  let _lastAttemptTime = 0;
  let _isAttempting = false;
  let _credentialRevision = 0;
  let _credentialAttempts = 0;

  try {
    chrome.storage?.onChanged?.addListener((changes, area) => {
      if (area === "local") {
        if (changes.stonk_auto_login_disabled?.newValue === true || changes.stonk_auto_login_enabled?.newValue === false) {
          _lastAttemptTime = 0;
          _isAttempting = false;
        }
      }
    });
  } catch {}

  async function run() {
    if (_isAttempting) return;

    let data;
    try {
      data = await chrome.storage.local.get([
        "stonk_auto_login_disabled",
        "stonk_auto_login_enabled",
        EXTERNAL_IMPORT_STATE_KEY,
        LEGACY_EXTERNAL_STATE_KEY
      ]);
    } catch { return; }

    // Kiểm tra cờ tắt: Chỉ dừng khi người dùng chủ động tắt
    if (data?.stonk_auto_login_disabled === true || data?.stonk_auto_login_enabled === false) {
      return;
    }

    const state = data?.[EXTERNAL_IMPORT_STATE_KEY] || data?.[LEGACY_EXTERNAL_STATE_KEY];
    if (state?.autoLogin === false) {
      return;
    }

    // Nếu không phải trang đăng nhập -> Thoát
    if (!isLoginPage()) {
      _lastAttemptTime = 0;
      return;
    }

    const bodyText = text(document.body);

    const credentials = await getSessionCredentials();
    const account = findSavedAccount();
    const continueButton = findContinueButton();

    if (/Chọn tài khoản/i.test(bodyText) || (account && !findPasswordInput())) {
      _lastAttemptTime = 0;

      const useAnotherAccount = credentials ? findUseAnotherAccountButton() : null;
      if (useAnotherAccount && !attemptedRecently("stonkExternalUseAnotherAccountClick", 2000)) {
        useAnotherAccount.click();
        return;
      }
      if (continueButton && !attemptedRecently("stonkExternalContinueClick", 2000)) {
        continueButton.click();
        return;
      }
      if (account && !attemptedRecently("stonkExternalSavedAccountClick", 2000)) {
        account.click();
        return;
      }
      return;
    }

    const pwdInput = findPasswordInput();
    const accInput = findAccountInput();
    const login = findLoginButton();

    // Không còn phụ thuộc Chrome Password Manager. Nếu chưa cấu hình thông tin phiên thì đứng yên,
    // không submit form rỗng và không chèn thêm nút vào giao diện nguồn ngoài.
    if (!credentials || !pwdInput || !accInput || !login) return;
    if (switchAccountModeIfNeeded(credentials.account)) return;

    if (_credentialRevision !== credentials.savedAt) {
      _credentialRevision = credentials.savedAt;
      _credentialAttempts = 0;
    }
    if (_credentialAttempts >= 2) return;

    const now = Date.now();
    if (_lastAttemptTime > 0 && now - _lastAttemptTime < 5000) {
      return;
    }

    _isAttempting = true;
    _lastAttemptTime = now;
    _credentialAttempts += 1;

    try {
      const accountUpdated = setNativeInputValue(accInput, credentials.account);
      const passwordUpdated = setNativeInputValue(pwdInput, credentials.password);
      if (!accountUpdated || !passwordUpdated) return;
      await new Promise(resolve => setTimeout(resolve, 150));
      const currentLogin = findLoginButton() || login;
      if (canClick(currentLogin)) currentLogin.click();
    } finally {
      _isAttempting = false;
    }
  }

  const start = () => setTimeout(run, 500);
  if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", start, { once: true });
  else start();

  const observer = new MutationObserver(() => {
    clearTimeout(observer.__timer);
    observer.__timer = setTimeout(run, 300);
  });
  observer.observe(document.documentElement, { childList: true, subtree: true });

  const timer = setInterval(run, 1000);
  setTimeout(() => { clearInterval(timer); observer.disconnect(); }, 15 * 60 * 1000);
})();
