/**
 * otpDetector.js
 * OTP Testing & Automation Framework — Detector Module
 * 
 * FOR DEV / STAGING / QA / ACCESSIBILITY TESTING ONLY.
 * This module is NEVER active in production environments.
 *
 * Detects OTP input fields using multiple heuristics:
 *   - input[type="tel"], input[inputmode="numeric"]
 *   - autocomplete="one-time-code"
 *   - aria-label / placeholder / name / id keyword matching
 *   - single-field and multi-box OTP UIs
 *   - React / Vue / Angular component compatibility
 */
(function initVisaFlowXOtpDetector(global) {
  "use strict";

  // ── OTP field selectors (ordered by confidence) ─────────────
  const OTP_SELECTORS = [
    "input[autocomplete='one-time-code']",
    "input[inputmode='numeric'][maxlength]",
    "input[type='tel'][maxlength]",
    "input[name*='otp' i]",
    "input[name*='pin' i]",
    "input[name*='code' i]",
    "input[name*='token' i]",
    "input[id*='otp' i]",
    "input[id*='verification' i]",
    "input[id*='code' i]",
    "input[id*='pin' i]",
    "input[placeholder*='otp' i]",
    "input[placeholder*='code' i]",
    "input[placeholder*='pin' i]",
    "input[aria-label*='otp' i]",
    "input[aria-label*='verification' i]",
    "input[aria-label*='one-time' i]",
    "input[data-testid*='otp' i]",
    "input[data-testid*='code' i]"
  ];

  // Keywords in surrounding text that confirm OTP context
  const OTP_CONTEXT_KEYWORDS = [
    "otp", "one-time", "verification code", "auth code",
    "enter code", "sms code", "mobile code", "pin"
  ];

  function log(msg) {
    console.log("[VisaFlowX][OtpDetector]", msg);
  }

  /**
   * Detect OTP field(s) in a document.
   * Returns { present, inputs, isSingleField, isMultiBox, reason }
   */
  function detectOtpFields(doc = document) {
    if (!doc) return { present: false, inputs: [], reason: "no_document" };

    // ── Multi-box detection: multiple single-digit inputs ────────
    const allInputs = Array.from(doc.querySelectorAll("input[type='tel'], input[type='text'], input[inputmode='numeric']"));
    const digitBoxes = allInputs.filter((el) => {
      const max = Number(el.getAttribute("maxlength") || el.getAttribute("size") || 0);
      return max === 1 && el.offsetParent !== null;
    });
    if (digitBoxes.length >= 4 && digitBoxes.length <= 8) {
      log(`Multi-box OTP detected: ${digitBoxes.length} digit inputs`);
      return {
        present:       true,
        inputs:        digitBoxes,
        isSingleField: false,
        isMultiBox:    true,
        reason:        "multi_box_otp"
      };
    }

    // ── Single-field detection ──────────────────────────────────
    for (const selector of OTP_SELECTORS) {
      const el = doc.querySelector(selector);
      if (el && el.offsetParent !== null) {
        log(`OTP field detected via selector: ${selector}`);
        return {
          present:       true,
          inputs:        [el],
          isSingleField: true,
          isMultiBox:    false,
          reason:        `selector_${selector.replace(/[^a-z_]/gi, "_").slice(0, 40)}`
        };
      }
    }

    // ── Context keyword fallback ────────────────────────────────
    const bodyText = (doc.body?.textContent || "").toLowerCase();
    const hasContext = OTP_CONTEXT_KEYWORDS.some((kw) => bodyText.includes(kw));
    if (hasContext) {
      const genericInput = doc.querySelector("input[type='tel'], input[type='number'], input[type='text']");
      if (genericInput && genericInput.offsetParent !== null) {
        log("OTP context detected via page text keywords");
        return {
          present:       true,
          inputs:        [genericInput],
          isSingleField: true,
          isMultiBox:    false,
          reason:        "keyword_context"
        };
      }
    }

    return { present: false, inputs: [], reason: "not_detected" };
  }

  /**
   * Check if a given element is an OTP input.
   */
  function isOtpInput(el) {
    if (!el || el.tagName !== "INPUT") return false;
    if (el.getAttribute("autocomplete") === "one-time-code") return true;
    const attrs = ["name", "id", "placeholder", "aria-label", "data-testid"];
    return attrs.some((a) => /otp|pin|code|token|verification/i.test(el.getAttribute(a) || ""));
  }

  const OtpDetector = Object.freeze({
    detectOtpFields,
    isOtpInput
  });

  global.VisaFlowX = Object.assign(global.VisaFlowX || {}, { OtpDetector });

  if (typeof module !== "undefined" && module.exports) {
    module.exports = OtpDetector;
  }
})(typeof globalThis !== "undefined" ? globalThis : this);
