(function () {
  const settings = window.RPCAAgeGate || {};

  if (!settings.showGate) {
    return;
  }

  const text = (value, fallback) => {
    if (value === null || typeof value === "undefined" || String(value).trim() === "") {
      return fallback;
    }
    return String(value);
  };

  const escapeHtml = (value) =>
    text(value, "")
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#039;");

  const canUseDob = settings.method === "dob" || settings.method === "both";
  const canUseSelf = settings.method === "self" || settings.method === "both";
  let busy = false;

  const numberBetween = (value, fallback, min, max) => {
    const parsed = Number(value);
    if (!Number.isFinite(parsed)) {
      return fallback;
    }
    return Math.max(min, Math.min(max, parsed));
  };

  const safeRedirectUrl = (value) => {
    const raw = text(value, "").trim();
    if (!raw || /[\u0000-\u001F\u007F]/.test(raw)) {
      return "";
    }
    try {
      const parsed = new URL(raw, window.location.origin);
      if ((parsed.protocol === "http:" || parsed.protocol === "https:") && parsed.origin === window.location.origin) {
        return parsed.href;
      }
    } catch (error) {
      return "";
    }
    return "";
  };

  const safeAssetUrl = (value) => {
    const raw = text(value, "").trim();
    if (!raw || /[\u0000-\u001F\u007F]/.test(raw)) {
      return "";
    }
    try {
      const parsed = new URL(raw, window.location.origin);
      if (parsed.protocol === "http:" || parsed.protocol === "https:") {
        return parsed.href;
      }
    } catch (error) {
      return "";
    }
    return "";
  };

  const safeCssColor = (value, fallback) => {
    const raw = text(value, "").trim();
    return /^#[0-9a-f]{3}(?:[0-9a-f]{3})?$/i.test(raw) ? raw : fallback;
  };

  const safeFontName = (value) =>
    text(value, "")
      .replace(/[^A-Za-z0-9 _.-]/g, "")
      .trim()
      .slice(0, 80);

  function postVerification(method, dob) {
    if (busy) {
      return;
    }
    busy = true;
    setMessage("Checking...");
    setButtons(true);

    const body = new URLSearchParams();
    body.set("action", "rpca_age_verify");
    body.set("nonce", settings.nonce || "");
    body.set("method", method);
    body.set("pageUrl", settings.pageUrl || window.location.href);
    if (dob) {
      body.set("dob", dob);
    }

    fetch(settings.ajaxUrl, {
      method: "POST",
      credentials: "same-origin",
      headers: {
        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
      },
      body: body.toString(),
    })
      .then((response) => response.json())
      .then((json) => {
        if (!json || !json.success) {
          throw new Error(
            json && json.data && json.data.message
              ? json.data.message
              : "Age verification could not be completed."
          );
        }
        if (json.data && json.data.verified) {
          removeGate();
          return;
        }
        handleFailure(json.data || {});
      })
      .catch((error) => {
        setMessage(error.message || "Age verification could not be completed.");
        setButtons(false);
      })
      .finally(() => {
        busy = false;
      });
  }

  function handleFailure(data) {
    const message = data.message || settings.failureText || "You do not meet the age requirement for this site.";
    setMessage(message);
    const redirectUrl = safeRedirectUrl(data.redirect || settings.failureRedirect);
    if (redirectUrl) {
      window.setTimeout(() => {
        window.location.assign(redirectUrl);
      }, 900);
      return;
    }
    setButtons(false);
  }

  function setButtons(disabled) {
    document.querySelectorAll(".rpca-age-gate button, .rpca-age-gate input").forEach((control) => {
      control.disabled = disabled;
    });
  }

  function setMessage(message) {
    const messageNode = document.querySelector(".rpca-age-gate-status");
    if (messageNode) {
      messageNode.textContent = message || "";
    }
  }

  function removeGate() {
    const gate = document.querySelector(".rpca-age-gate");
    if (gate) {
      gate.remove();
    }
    document.documentElement.classList.remove("rpca-age-gate-lock");
    document.body.classList.remove("rpca-age-gate-active");
  }

  function maxDobValue(minAge) {
    const date = new Date();
    date.setFullYear(date.getFullYear() - Number(minAge || 21));
    return date.toISOString().slice(0, 10);
  }

  function renderGate() {
    const mode = settings.mode === "popup" ? "popup" : "fullscreen";
    const styles = ["classic", "lab", "minimal", "glass", "split", "bold", "soft", "high_contrast"];
    const gateStyle = styles.includes(settings.style) ? settings.style : "classic";
    const minAge = Number(settings.minAge || 21);
    const mediaUrl = safeAssetUrl(settings.mediaUrl);
    const fontName = safeFontName(settings.fontName);
    const root = document.createElement("div");
    root.className =
      "rpca-age-gate is-" +
      mode +
      " style-" +
      gateStyle +
      (settings.gradientEnabled ? " has-gradient" : "") +
      (mediaUrl ? " has-media" : "");
    root.setAttribute("role", "dialog");
    root.setAttribute("aria-modal", "true");
    root.setAttribute("aria-labelledby", "rpca-age-gate-title");
    root.style.setProperty("--rpca-age-bg", safeCssColor(settings.background, "#0f172a"));
    root.style.setProperty("--rpca-age-accent", safeCssColor(settings.accent, "#7a3b2e"));
    root.style.setProperty("--rpca-age-card-width", numberBetween(settings.boxWidth, 560, 320, 960) + "px");
    root.style.setProperty("--rpca-age-card-padding", numberBetween(settings.boxPadding, 28, 12, 80) + "px");
    root.style.setProperty("--rpca-age-card-radius", numberBetween(settings.boxRadius, 8, 0, 40) + "px");
    root.style.setProperty("--rpca-age-media-width", numberBetween(settings.mediaMaxWidth, 180, 64, 420) + "px");
    root.style.setProperty("--rpca-age-media-height", numberBetween(settings.mediaMaxHeight, 120, 40, 320) + "px");
    root.style.setProperty(
      "--rpca-age-gradient-bg",
      `linear-gradient(${numberBetween(settings.gradientAngle, 135, 0, 360)}deg, ${safeCssColor(settings.gradientStart, "#0f172a")}, ${safeCssColor(settings.gradientEnd, "#7a3b2e")})`
    );
    if (settings.fontMode === "custom" && fontName) {
      root.style.setProperty("--rpca-age-font", `"${fontName}", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`);
    }

    const media = mediaUrl
      ? `<div class="rpca-age-gate-media"><img src="${escapeHtml(mediaUrl)}" alt="${escapeHtml(settings.mediaAlt || "")}" loading="eager" /></div>`
      : "";

    root.innerHTML = `
      <div class="rpca-age-gate-card">
        ${media}
        <div class="rpca-age-gate-header">
          <span>${escapeHtml(minAge)}+</span>
          <h2 id="rpca-age-gate-title">${escapeHtml(text(settings.title, "Age Verification Required"))}</h2>
        </div>
        <p>${escapeHtml(text(settings.message, "Confirm that you meet the minimum age requirement before continuing."))}</p>
        <div class="rpca-age-gate-actions">
          ${
            canUseSelf
              ? `<button type="button" class="rpca-age-accept">${escapeHtml(text(settings.acceptText, "I am old enough to enter"))}</button>`
              : ""
          }
          ${
            canUseDob
              ? `<form class="rpca-age-dob-form">
                  <label>
                    <span>${escapeHtml(text(settings.dobText, "Verify with date of birth"))}</span>
                    <input type="date" name="rpca_dob" max="${escapeHtml(maxDobValue(minAge))}" required />
                  </label>
                  <button type="submit">${escapeHtml(text(settings.dobText, "Verify with date of birth"))}</button>
                </form>`
              : ""
          }
          <button type="button" class="rpca-age-decline">${escapeHtml(text(settings.declineText, "I am not old enough"))}</button>
        </div>
        <p class="rpca-age-gate-status" aria-live="polite"></p>
      </div>
    `;

    document.body.appendChild(root);
    document.documentElement.classList.add("rpca-age-gate-lock");
    document.body.classList.add("rpca-age-gate-active");

    const firstControl = root.querySelector("button, input");
    if (firstControl) {
      firstControl.focus({ preventScroll: true });
    }

    root.addEventListener("click", (event) => {
      const accept = event.target.closest(".rpca-age-accept");
      const decline = event.target.closest(".rpca-age-decline");
      if (accept) {
        postVerification("self");
      }
      if (decline) {
        handleFailure({ message: settings.failureText, redirect: settings.failureRedirect });
      }
    });

    root.addEventListener("submit", (event) => {
      if (!event.target.matches(".rpca-age-dob-form")) {
        return;
      }
      event.preventDefault();
      const input = event.target.querySelector('input[name="rpca_dob"]');
      if (!input || !input.value) {
        setMessage("Enter your date of birth to continue.");
        return;
      }
      postVerification("dob", input.value);
    });

    root.addEventListener("keydown", (event) => {
      if (event.key !== "Tab") {
        return;
      }
      const controls = Array.from(root.querySelectorAll("button:not([disabled]), input:not([disabled])"));
      if (!controls.length) {
        return;
      }
      const first = controls[0];
      const last = controls[controls.length - 1];
      if (event.shiftKey && document.activeElement === first) {
        event.preventDefault();
        last.focus();
      } else if (!event.shiftKey && document.activeElement === last) {
        event.preventDefault();
        first.focus();
      }
    });
  }

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", renderGate);
  } else {
    renderGate();
  }
})();
