/**
 * RAJ365 — Player App Visual Enhancement Layer
 * ═══════════════════════════════════════════════════════════
 * শুধুমাত্র VISUAL enhancement (ripple click-effect, fade-in,
 * visibility-aware animation)। এই ফাইল কোনো click
 * preventDefault/stopPropagation করে না, কোনো API call করে না,
 * কোনো route/state বদলায় না — তাই existing app-এর কোনো logic-এ
 * প্রভাব পড়ে না। যেকোনো ত্রুটি silently ignore হয় (try/catch),
 * যাতে ভুল করেও কখনো মূল app ভেঙে না যায়।
 * ═══════════════════════════════════════════════════════════
 */
(function () {
  "use strict";

  function safe(fn) {
    try { fn(); } catch (e) { /* silently ignore — কখনো main app-কে প্রভাবিত করবে না */ }
  }

  // SPA-তে নতুন DOM যোগ হলে যেসব ফাংশন আবার চালাতে হবে, তাদের list।
  // প্রতিটা feature নিজেই এখানে নিজেকে register করে।
  const domWatcherCallbacks = [];

  /* ── ১. Ripple click-effect — button/card-এ ── */
  function attachRipple() {
    document.addEventListener("click", function (e) {
      safe(function () {
        const target = e.target.closest(
          ".van-button, .gameItem1, .aloneGame, .all_item, .tab_active, .fun-tab-item"
        );
        if (!target) return;

        const rect = target.getBoundingClientRect();
        const span = document.createElement("span");
        const size = Math.max(rect.width, rect.height);

        span.className = "rg-ripple-span";
        span.style.width = span.style.height = size + "px";
        span.style.left = (e.clientX - rect.left - size / 2) + "px";
        span.style.top = (e.clientY - rect.top - size / 2) + "px";

        const prevPosition = getComputedStyle(target).position;
        if (prevPosition === "static") target.style.position = "relative";
        target.style.overflow = target.style.overflow || "hidden";

        target.appendChild(span);
        setTimeout(function () {
          safe(function () { span.remove(); });
        }, 500);
      });
    }, { passive: true }); // passive: true => কখনো normal click behavior আটকাবে না
  }

  /* ── ২. Scroll-এ Fade-in (game card, banner ইত্যাদি) — একবারই ── */
  function attachFadeIn() {
    if (!("IntersectionObserver" in window)) return; // পুরনো browser হলে চুপচাপ skip

    const observer = new IntersectionObserver(function (entries) {
      entries.forEach(function (entry) {
        if (entry.isIntersecting) {
          safe(function () { entry.target.classList.add("rg-fade-in"); });
          observer.unobserve(entry.target);
        }
      });
    }, { threshold: 0.1 });

    function observeNewCards() {
      safe(function () {
        document
          .querySelectorAll(
            ".gameItem1:not(.rg-observed), .aloneGame:not(.rg-observed), .my-swipe:not(.rg-observed)"
          )
          .forEach(function (el) {
            el.classList.add("rg-observed");
            observer.observe(el);
          });
      });
    }

    observeNewCards();
    domWatcherCallbacks.push(observeNewCards);
  }

  /* ── ৩. শুধু visible card-ই animate হবে (GPU/battery বাঁচাতে) ──
     এটা continuous (বার বার visibility বদলালে toggle করে),
     তাই fade-in থেকে আলাদা observer। */
  function attachVisibilityAnimationToggle() {
    if (!("IntersectionObserver" in window)) return;

    const observer = new IntersectionObserver(function (entries) {
      entries.forEach(function (entry) {
        safe(function () {
          if (entry.isIntersecting) {
            entry.target.classList.add("rg-in-view");
          } else {
            entry.target.classList.remove("rg-in-view");
          }
        });
      });
    }, { threshold: 0.05 });

    function observeCards() {
      safe(function () {
        document
          .querySelectorAll(
            ".gameItem1:not(.rg-vis-observed), .aloneGame:not(.rg-vis-observed), .all_item:not(.rg-vis-observed), .citem:not(.rg-vis-observed)"
          )
          .forEach(function (el) {
            el.classList.add("rg-vis-observed");
            observer.observe(el);
          });
      });
    }

    observeCards();
    domWatcherCallbacks.push(observeCards);
  }

  /* ── ৪. Primary button-এ glow-pulse (visual only) ── */
  function attachGlowPulse() {
    safe(function () {
      document
        .querySelectorAll(".van-button--primary:not(.rg-pulse)")
        .forEach(function (el) { el.classList.add("rg-pulse"); });
    });
  }

  /* ── ৫. Performance-friendly DOM watcher ──
     MutationObserver — শুধু তখনই কাজ করে যখন DOM-এ সত্যিই নতুন
     কিছু যোগ হয় (SPA route পাল্টালে), অকারণে বার বার CPU/battery
     খরচ করে না। domWatcherCallbacks-এ register করা প্রতিটা
     ফাংশনকে debounced ভাবে আবার চালায়। */
  function attachDomWatcher() {
    if (!("MutationObserver" in window)) return;

    let pending = false;
    const runUpdates = function () {
      pending = false;
      domWatcherCallbacks.forEach(function (cb) { safe(cb); });
      safe(attachGlowPulse);
    };

    const observer = new MutationObserver(function () {
      if (!pending) {
        pending = true;
        requestAnimationFrame(runUpdates);
      }
    });

    observer.observe(document.body, { childList: true, subtree: true });
  }

  /* ── শুরু করো, DOM প্রস্তুত হওয়ার পর ── */
  function init() {
    safe(attachRipple);
    safe(attachFadeIn);
    safe(attachVisibilityAnimationToggle);
    safe(attachGlowPulse);
    safe(attachDomWatcher);
  }

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