/**
 * otpCooldownManager.js
 * OTP Testing & Automation Framework — Cooldown Engine
 *
 * FOR DEV / STAGING / QA / ACCESSIBILITY TESTING ONLY.
 *
 * Detects server-side cooldown/retry messages after failed OTP attempts.
 * Pauses automation safely. Resumes ONLY after cooldown expires.
 */
(function initVisaFlowXOtpCooldownManager(global) {
  "use strict";

  // Re-uses the core CooldownManager's parser if available
  const getCore = () => global.VisaFlowX?.CooldownManager || null;

  const COOLDOWN_PATTERNS = [
    /try\s+again\s+after\s+(\d+)\s*second[s]?/i,
    /please\s+wait\s+(\d+)\s*second[s]?/i,
    /wait\s+(\d+)\s*second[s]?/i,
    /too\s+many\s+(attempts|requests)/i,
    /please\s+wait/i,
    /temporarily\s+(blocked|unavailable)/i
  ];

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

  function parseCooldown(text) {
    const core = getCore();
    if (core?.parseCooldownMessage) {
      return core.parseCooldownMessage(text);
    }
    // Fallback minimal parser
    const raw = String(text || "").toLowerCase();
    for (const re of COOLDOWN_PATTERNS) {
      const m = raw.match(re);
      if (m) {
        const seconds = Number(m[1]) || 30;
        return {
          minutes: Math.floor(seconds / 60),
          seconds: seconds % 60,
          totalMs: seconds * 1000,
          source:  text.slice(0, 120)
        };
      }
    }
    if (/too many|please wait|temporarily/i.test(raw)) {
      return { minutes: 0, seconds: 30, totalMs: 30000, source: text.slice(0, 120) };
    }
    return null;
  }

  class OtpCooldownManager {
    constructor() {
      this._active     = false;
      this._endsAt     = 0;
      this._timer      = null;
      this._onResume   = null;
      this._onTick     = null;
    }

    isActive() { return this._active && this._endsAt > Date.now(); }

    remainingMs() { return Math.max(0, this._endsAt - Date.now()); }

    formatRemaining() {
      const ms = this.remainingMs();
      const m  = Math.floor(ms / 60000);
      const s  = Math.floor((ms % 60000) / 1000);
      return m > 0 ? `${m}m ${s}s` : `${s}s`;
    }

    /**
     * Detect and start cooldown from page text.
     * @param {string}   text       Error text to parse.
     * @param {object}   options    { onTick, onResume }
     * @returns {object|null} parsed cooldown or null
     */
    async detectAndStart(text, options = {}) {
      const parsed = parseCooldown(text);
      if (!parsed) return null;

      this._active   = true;
      this._endsAt   = Date.now() + parsed.totalMs;
      this._onTick   = options.onTick   || null;
      this._onResume = options.onResume || null;

      log(`Cooldown detected. Retrying in ${parsed.minutes}m ${parsed.seconds}s`);
      log(`OTP automation paused for ${Math.round(parsed.totalMs / 1000)} seconds`);

      this._startTimer();
      return parsed;
    }

    cancel() {
      if (this._timer) clearTimeout(this._timer);
      this._timer  = null;
      this._active = false;
      this._endsAt = 0;
      log("OTP cooldown cancelled");
    }

    _startTimer() {
      if (this._timer) clearTimeout(this._timer);
      const tick = () => {
        const remaining = this._endsAt - Date.now();
        if (this._onTick) {
          try { this._onTick(remaining, this.formatRemaining()); } catch (_) {}
        }
        if (remaining <= 0) {
          this._active = false;
          log("OTP cooldown finished. Resuming...");
          if (this._onResume) {
            try { this._onResume(); } catch (_) {}
          }
          return;
        }
        this._timer = setTimeout(tick, 1000);
      };
      tick();
    }
  }

  const OtpCooldownManagerModule = Object.freeze({ OtpCooldownManager, parseCooldown });

  global.VisaFlowX = Object.assign(global.VisaFlowX || {}, { OtpCooldownManager: OtpCooldownManagerModule });

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