(() => {
  const POLICIES = Object.freeze({
    TARGET_NOT_UNIQUE: policy("waiting_user", false, 0, "request_target"),
    PAGE_CHANGED: policy("observing", true, 2, "reobserve"),
    CONTROL_NOT_FOUND: policy("retryable_failure", true, 2, "reobserve"),
    PLATFORM_CONFIRM_REQUIRED: policy("observing", true, 1, "reobserve_dialog"),
    LOGIN_EXPIRED: policy("waiting_user", false, 0, "request_login"),
    CAPTCHA_BLOCKED: policy("safety_terminated", false, 0, "stop"),
    RISK_VERIFICATION: policy("safety_terminated", false, 0, "stop"),
    VERIFICATION_MISMATCH: policy("retryable_failure", true, 2, "refresh_and_verify"),
    WORKER_OFFLINE: policy("retryable_failure", true, 2, "wait_worker"),
    MODEL_ROUTE_FAILED: policy("retryable_failure", true, 1, "use_configured_fallback"),
    DELIVERY_FAILED: policy("retryable_failure", true, 3, "retry_delivery"),
    LEASE_CONFLICT: policy("retryable_failure", true, 1, "wait_lease"),
    LEASE_EXPIRED: policy("retryable_failure", true, 1, "reacquire_lease"),
    RETRY_EXHAUSTED: policy("blocked", false, 0, "stop"),
    CANCELLED: policy("cancelled", false, 0, "stop"),
    TIMEOUT: policy("retryable_failure", true, 1, "reobserve"),
    SAFETY_BLOCKED: policy("safety_terminated", false, 0, "stop")
  });

  function policy(status, retryable, maxAttempts, action) {
    return Object.freeze({ status, retryable, maxAttempts, action });
  }

  function decide(errorCode, attempts = 0) {
    const code = String(errorCode || "").trim().toUpperCase();
    const selected = POLICIES[code] || POLICIES.SAFETY_BLOCKED;
    if (!selected.retryable) return Object.freeze({ ...selected, errorCode: code || "SAFETY_BLOCKED" });
    if (Number(attempts) >= selected.maxAttempts) {
      return Object.freeze({ ...POLICIES.RETRY_EXHAUSTED, errorCode: "RETRY_EXHAUSTED" });
    }
    return Object.freeze({ ...selected, errorCode: code });
  }

  function recoveryCheckpoint(task = {}, decision = {}) {
    return Object.freeze({
      taskId: String(task.taskId || "").slice(0, 160),
      status: decision.status === "observing" ? "observing" : String(decision.status || "retryable_failure"),
      recoveryRequired: decision.retryable === true,
      recoveryAction: String(decision.action || "stop"),
      invalidated: Object.freeze(["candidateId", "dom", "coordinates"]),
      pageFingerprint: ""
    });
  }

  function safeRecoveryInput(task = {}) {
    return Object.freeze({
      taskId: String(task.taskId || "").slice(0, 160),
      accountKey: String(task.accountKey || "").slice(0, 128),
      scope: String(task.scope || "").slice(0, 40),
      workerInstanceId: String(task.workerInstanceId || "").slice(0, 160),
      planId: String(task.planId || "").slice(0, 64),
      toolName: String(task.toolName || "").slice(0, 64),
      expectedBefore: task.expectedBefore ?? null,
      targetValue: task.targetValue ?? null,
      valueFrozen: task.valueFrozen === true
    });
  }

  const api = Object.freeze({ POLICIES, decide, recoveryCheckpoint, safeRecoveryInput });
  if (typeof window !== "undefined") window.MMWQianchuanRecoveryPolicy = api;
  if (typeof module !== "undefined" && module.exports) module.exports = api;
})();
