// UI element hiding for Instagram web.
//
// SCROLL LOCK WARNING:
// MutationObserver callbacks with {childList:true, subtree:true} fire hundreds
// of times/sec on Instagram's infinite scroll feed. Expensive querySelectorAll
// calls inside these callbacks block the main thread = scroll jank.
// The JS hiders below use requestIdleCallback + a 300ms debounce so they run
// only during idle time and never on every single mutation.

// ─── CSS-based (reliable, zero perf cost) ────────────────────────────────────

const String kHideLikeCountsCSS =
    """
  [role="button"][aria-label${r"$"}=" like"],
  [role="button"][aria-label${r"$"}=" likes"],
  [role="button"][aria-label${r"$"}=" view"],
  [role="button"][aria-label${r"$"}=" views"],
  a[href*="/liked_by/"] {
    display: none !important;
  }
""";

const String kHideFollowerCountsCSS = """
  a[href*="/followers/"] span,
  a[href*="/following/"] span {
    opacity: 0 !important;
    pointer-events: none !important;
  }
""";

// Stories bar — broad selector covering multiple Instagram DOM layouts
const String kHideStoriesBarCSS = """
  [aria-label*="Stories"],
  [aria-label*="stories"],
  [role="list"][aria-label*="tories"],
  [role="listbox"][aria-label*="tories"],
  div[style*="overflow"][style*="scroll"]:has(canvas),
  section > div > div[style*="overflow-x"] {
    display: none !important;
  }
""";

// Also do a JS sweep for stories — CSS alone isn't reliable across Instagram versions
const String kHideStoriesBarJS = r'''
(function() {
  function hideStories() {
    try {
      // Target the horizontal scrollable stories container
      document.querySelectorAll('[role="list"], [role="listbox"]').forEach(function(el) {
        try {
          const label = (el.getAttribute('aria-label') || '').toLowerCase();
          if (label.includes('stori')) {
            el.style.setProperty('display', 'none', 'important');
          }
        } catch(_) {}
      });
      // Fallback: find story bubbles (circular avatar containers at top of feed)
      document.querySelectorAll('section > div > div').forEach(function(el) {
        try {
          const style = window.getComputedStyle(el);
          if (style.overflowX === 'scroll' || style.overflowX === 'auto') {
            const circles = el.querySelectorAll('canvas, [style*="border-radius: 50%"]');
            if (circles.length > 2) {
              el.style.setProperty('display', 'none', 'important');
            }
          }
        } catch(_) {}
      });
    } catch(_) {}
  }

  hideStories();

  if (!window.__fgStoriesObserver) {
    let _storiesTimer = null;
    window.__fgStoriesObserver = new MutationObserver(() => {
      // Debounce — only run after mutations settle, not on every single one
      clearTimeout(_storiesTimer);
      _storiesTimer = setTimeout(hideStories, 300);
    });
    window.__fgStoriesObserver.observe(
      document.documentElement,
      { childList: true, subtree: true }
    );
  }
})();
''';

/// Robust stories overlay - blocks clicking and applies blur when hide stories is enabled.
/// This is a more aggressive approach that places an overlay with blur on top of stories area.
const String kStoriesOverlayJS = r'''
(function() {
  if (window.__fgStoriesOverlayRunning) return;
  window.__fgStoriesOverlayRunning = true;

  const BLOCKED_ATTR = 'data-fg-stories-blocked';

  function buildOverlay(container) {
    const div = document.createElement('div');
    div.setAttribute(BLOCKED_ATTR, '1');
    div.style.cssText = [
      'position: absolute',
      'inset: 0',
      'z-index: 99998',
      'display: flex',
      'align-items: center',
      'justify-content: center',
      'background: rgba(0, 0, 0, 0.6)',
      'backdrop-filter: blur(10px)',
      '-webkit-backdrop-filter: blur(10px)',
      'border-radius: 8px',
      'pointer-events: all',
      'cursor: not-allowed',
    ].join(';');

    const label = document.createElement('span');
    label.textContent = 'Stories blocked';
    label.style.cssText = [
      'color: rgba(255, 255, 255, 0.8)',
      'font-size: 12px',
      'font-weight: 600',
      'font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
      'text-align: center',
      'padding: 8px 16px',
      'background: rgba(0, 0, 0, 0.5)',
      'border-radius: 20px',
    ].join(';');

    div.appendChild(label);

    // Swallow all interaction
    ['click', 'touchstart', 'touchend', 'touchmove', 'pointerdown', 'mouseenter'].forEach(function(evt) {
      div.addEventListener(evt, function(e) {
        e.preventDefault();
        e.stopImmediatePropagation();
      }, { capture: true });
    });

    return div;
  }

  function overlayStoriesContainer(container) {
    if (!container) return;
    if (container.querySelector('[' + BLOCKED_ATTR + ']')) return;
    
    // Check if this looks like a stories container
    const hasStories = container.querySelector('canvas, [style*="border-radius: 50%"], [aria-label*="story"], [role="list"]');
    if (!hasStories) return;
    
    container.style.position = 'relative';
    container.style.overflow = 'hidden';
    container.appendChild(buildOverlay(container));
  }

  function findAndOverlayStories() {
    try {
      // Method 1: Find by role="list" with story-related aria-label
      document.querySelectorAll('[role="list"], [role="listbox"]').forEach(function(el) {
        try {
          const label = (el.getAttribute('aria-label') || '').toLowerCase();
          if (label.includes('stori')) {
            overlayStoriesContainer(el.parentElement);
          }
        } catch(_) {}
      });

      // Method 2: Find horizontal scroll containers at top of feed
      document.querySelectorAll('header + div > div, main > div > div > div').forEach(function(el) {
        try {
          const style = window.getComputedStyle(el);
          if ((style.overflowX === 'scroll' || style.overflowX === 'auto') && 
              (style.display === 'flex' || style.display === '')) {
            const children = el.children;
            let hasAvatar = false;
            for (let i = 0; i < Math.min(children.length, 10); i++) {
              const child = children[i];
              const childStyle = window.getComputedStyle(child);
              if (childStyle.width === '60px' || childStyle.width === '66px' ||
                  child.querySelector('canvas, [style*="border-radius: 50%"]')) {
                hasAvatar = true;
                break;
              }
            }
            if (hasAvatar) {
              overlayStoriesContainer(el);
            }
          }
        } catch(_) {}
      });

      // Method 3: Find story avatars directly
      document.querySelectorAll('[href*="/stories/"], [aria-label*="Your Story"]').forEach(function(el) {
        try {
          let container = el.parentElement;
          for (let i = 0; i < 5 && container; i++) {
            const style = window.getComputedStyle(container);
            if (style.position !== 'static' && container.children.length < 20) {
              overlayStoriesContainer(container);
              break;
            }
            container = container.parentElement;
          }
        } catch(_) {}
      });
    } catch(_) {}
  }

  // Initial run
  findAndOverlayStories();

  // Watch for dynamic changes
  let _overlayTimer = null;
  new MutationObserver(function() {
    clearTimeout(_overlayTimer);
    _overlayTimer = setTimeout(findAndOverlayStories, 500);
  }).observe(document.documentElement, { childList: true, subtree: true });

  // Also run on scroll
  let _scrollTimer = null;
  window.addEventListener('scroll', function() {
    clearTimeout(_scrollTimer);
    _scrollTimer = setTimeout(findAndOverlayStories, 300);
  }, { passive: true });
})();
''';

const String kHideExploreTabCSS = """
  a[href="/explore/"],
  a[href="/explore"] {
    display: none !important;
  }
""";

const String kHideReelsTabCSS = """
  a[href="/reels/"],
  a[href="/reels"] {
    display: none !important;
  }
""";

const String kHideShopTabCSS = """
  a[href*="/shop"],
  a[href*="/shopping"] {
    display: none !important;
  }
""";

// ─── Complete Section Disabling (CSS-based) ─────────────────────────────────

// Minimal mode - disables Reels and Explore entirely
const String kMinimalModeCssScript = r'''
(function() {
  const css = `
    /* Hide Reels tab */
    a[href="/reels/"], a[href="/reels"] { display: none !important; }
    /* Hide Explore tab */
    a[href="/explore/"], a[href="/explore"] { display: none !important; }
    /* Hide Create tab */
    a[href="/create/"], a[href="/create"] { display: none !important; }
    /* Hide Reels in feed */
    article a[href*="/reel/"] { display: none !important; }
    /* Hide Explore entry points */
    svg[aria-label="Explore"], [aria-label="Explore"] { display: none !important; }
  `;
  const style = document.createElement('style');
  style.id = 'fg-minimal-mode';
  style.textContent = css;
  (document.head || document.documentElement).appendChild(style);
})();
''';

// Disable Reels entirely
const String kDisableReelsEntirelyCssScript = r'''
(function() {
  const css = `
    a[href="/reels/"], a[href="/reels"] { display: none !important; }
    article a[href*="/reel/"] { display: none !important; }
  `;
  const style = document.createElement('style');
  style.id = 'fg-disable-reels';
  style.textContent = css;
  (document.head || document.documentElement).appendChild(style);
})();
''';

// Disable Explore entirely
const String kDisableExploreEntirelyCssScript = r'''
(function() {
  const css = `
    a[href="/explore/"], a[href="/explore"] { display: none !important; }
    svg[aria-label="Explore"], [aria-label="Explore"] { display: none !important; }
  `;
  const style = document.createElement('style');
  style.id = 'fg-disable-explore';
  style.textContent = css;
  (document.head || document.documentElement).appendChild(style);
})();
''';

// ─── DM-embedded Reels Scroll Control ────────────────────────────────────────
// Disables vertical scroll on reels opened from DM unless comment box or share modal is open
const String kDmReelScrollLockScript = r'''
(function() {
  // Track scroll lock state
  window.__fgDmReelScrollLocked = true;
  window.__fgDmReelCommentOpen = false;
  window.__fgDmReelShareOpen = false;

  function lockScroll() {
    if (window.__fgDmReelScrollLocked) {
      document.body.style.overflow = 'hidden';
      document.documentElement.style.overflow = 'hidden';
    }
  }

  function unlockScroll() {
    document.body.style.overflow = '';
    document.documentElement.style.overflow = '';
  }

  function updateScrollState() {
    // Only unlock if comment or share modal is open
    if (window.__fgDmReelCommentOpen || window.__fgDmReelShareOpen) {
      unlockScroll();
    } else if (window.__fgDmReelScrollLocked) {
      lockScroll();
    }
  }

  // Listen for comment box opening/closing
  function setupCommentObserver() {
    const commentBox = document.querySelector('div[aria-label="Comment"], section[aria-label*="Comment"]');
    if (commentBox) {
      window.__fgDmReelCommentOpen = true;
      updateScrollState();
    }
  }

  // Listen for share modal
  function setupShareObserver() {
    const shareModal = document.querySelector('div[role="dialog"][aria-label*="Share"], section[aria-label*="Share"]');
    if (shareModal) {
      window.__fgDmReelShareOpen = true;
      updateScrollState();
    }
  }

  // Set up MutationObserver to detect comment/share modals
  const observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      mutation.addedNodes.forEach(function(node) {
        if (node.nodeType === 1) {
          const ariaLabel = node.getAttribute('aria-label') || '';
          const role = node.getAttribute('role') || '';
          
          // Check for comment box
          if (ariaLabel.toLowerCase().includes('comment') || 
              (role === 'dialog' && ariaLabel === '')) {
            // Check if it's a comment dialog
            setTimeout(function() {
              window.__fgDmReelCommentOpen = !!document.querySelector('div[aria-label="Comment"], section[aria-label*="Comment"]');
              updateScrollState();
            }, 100);
          }
          
          // Check for share modal
          if (ariaLabel.toLowerCase().includes('share')) {
            window.__fgDmReelShareOpen = true;
            updateScrollState();
          }
        }
      });
      
      mutation.removedNodes.forEach(function(node) {
        if (node.nodeType === 1) {
          const ariaLabel = node.getAttribute('aria-label') || '';
          if (ariaLabel.toLowerCase().includes('comment')) {
            setTimeout(function() {
              window.__fgDmReelCommentOpen = !!document.querySelector('div[aria-label="Comment"], section[aria-label*="Comment"]');
              updateScrollState();
            }, 100);
          }
          if (ariaLabel.toLowerCase().includes('share')) {
            window.__fgDmReelShareOpen = false;
            updateScrollState();
          }
        }
      });
    });
  });

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

  // Initial lock
  lockScroll();

  // Expose functions for external control
  window.__fgSetDmReelScrollLock = function(locked) {
    window.__fgDmReelScrollLocked = locked;
    updateScrollState();
  };
})();
''';

// ─── JS-based (text-content detection, debounced) ─────────────────────────────

// Sponsored posts — scans for "Sponsored" text, debounced so it doesn't
// cause scroll jank on Instagram's constantly-mutating feed DOM.
const String kHideSponsoredPostsJS = r'''
(function() {
  function hideSponsoredPosts() {
    try {
      document.querySelectorAll('article, li[role="listitem"]').forEach(function(el) {
        try {
          if (el.__fgSponsoredChecked) return; // skip already-processed elements
          const spans = el.querySelectorAll('span');
          for (let i = 0; i < spans.length; i++) {
            const text = spans[i].textContent.trim();
            if (text === 'Sponsored' || text === 'Paid partnership') {
              el.style.setProperty('display', 'none', 'important');
              return;
            }
          }
          el.__fgSponsoredChecked = true; // mark as checked (non-sponsored)
        } catch(_) {}
      });
    } catch(_) {}
  }

  hideSponsoredPosts();

  if (!window.__fgSponsoredObserver) {
    let _timer = null;
    window.__fgSponsoredObserver = new MutationObserver(() => {
      clearTimeout(_timer);
      _timer = setTimeout(hideSponsoredPosts, 300);
    });
    window.__fgSponsoredObserver.observe(
      document.documentElement,
      { childList: true, subtree: true }
    );
  }
})();
''';

// Suggested posts — debounced same way.
const String kHideSuggestedPostsJS = r'''
(function() {
  function hideSuggestedPosts() {
    try {
      // Target text patterns that indicate suggested content
      const suggestedPatterns = [
        'Suggested for you',
        'Suggested posts',
        "You're all caught up",
        'Suggested',
        'Recommendations',
        'Discover more',
        'Suggested Accounts',
      ];
      
      // Find and hide all elements with suggested content text
      document.querySelectorAll('span, h3, h4, h2, a').forEach(function(el) {
        try {
          const text = el.textContent.trim();
          const matched = suggestedPatterns.some(pattern => 
            text === pattern || text.includes(pattern)
          );
          
          if (matched) {
            let parent = el.parentElement;
            // Traverse up to find the container section/article
            for (let i = 0; i < 12 && parent; i++) {
              const tag = parent.tagName.toLowerCase();
              const classList = parent.className || '';
              
              // Hide articles, sections, lists, and common suggestion containers
              if (
                tag === 'article' || 
                tag === 'section' || 
                tag === 'li' ||
                classList.includes('xjx87jv0') || // Instagram suggestion container
                classList.includes('x1a8lsjc') // Reel suggestion container
              ) {
                parent.style.setProperty('display', 'none', 'important');
                break;
              }
              parent = parent.parentElement;
            }
          }
        } catch(_) {}
      });
      
      // Also hide by attribute patterns
      document.querySelectorAll('[aria-label*="Suggested"], [data-testid*="suggested"]').forEach(function(el) {
        try {
          let parent = el;
          for (let i = 0; i < 12 && parent; i++) {
            const tag = parent.tagName.toLowerCase();
            if (tag === 'article' || tag === 'section' || tag === 'li') {
              parent.style.setProperty('display', 'none', 'important');
              break;
            }
            parent = parent.parentElement;
          }
        } catch(_) {}
      });
    } catch(_) {}
  }

  hideSuggestedPosts();

  if (!window.__fgSuggestedObserver) {
    let _timer = null;
    window.__fgSuggestedObserver = new MutationObserver(() => {
      clearTimeout(_timer);
      _timer = setTimeout(hideSuggestedPosts, 300);
    });
    window.__fgSuggestedObserver.observe(
      document.documentElement,
      { childList: true, subtree: true }
    );
  }
})();
''';

// ─── DM Reel Blocker ─────────────────────────────────────────────────────────

/// Overlays a "Reels are disabled" card on reel preview cards inside DMs.
///
/// DM reel previews use pushState (SPA) not <a href> navigation, so the CSS
/// display:none in kDisableReelsEntirelyCssScript doesn't remove the preview
/// card from the thread. This script finds them structurally and covers them
/// with a blocking overlay that also swallows all touch/click events.
///
/// Inject when disableReelsEntirely OR minimalMode is on.
const String kDmReelBlockerJS = r'''
(function() {
  if (window.__fgDmReelBlockerRunning) return;
  window.__fgDmReelBlockerRunning = true;

  const BLOCKED_ATTR = 'data-fg-blocked';

  function buildOverlay() {
    const div = document.createElement('div');
    div.setAttribute(BLOCKED_ATTR, '1');
    div.style.cssText = [
      'position:absolute',
      'inset:0',
      'z-index:99999',
      'display:flex',
      'flex-direction:column',
      'align-items:center',
      'justify-content:center',
      'background:rgba(0,0,0,0.85)',
      'border-radius:inherit',
      'pointer-events:all',
      'gap:8px',
      'cursor:default',
    ].join(';');

    const icon = document.createElement('span');
    icon.textContent = '🚫';
    icon.style.cssText = 'font-size:28px;line-height:1';

    const label = document.createElement('span');
    label.textContent = 'Reels are disabled';
    label.style.cssText = [
      'color:#fff',
      'font-size:13px',
      'font-weight:600',
      'font-family:-apple-system,sans-serif',
      'text-align:center',
      'padding:0 12px',
    ].join(';');

    const sub = document.createElement('span');
    sub.textContent = 'Disable "Block Reels" in FocusGram settings';
    sub.style.cssText = [
      'color:rgba(255,255,255,0.5)',
      'font-size:11px',
      'font-family:-apple-system,sans-serif',
      'text-align:center',
      'padding:0 16px',
    ].join(';');

    div.appendChild(icon);
    div.appendChild(label);
    div.appendChild(sub);

    // Swallow all interaction so the reel beneath cannot be triggered
    ['click','touchstart','touchend','touchmove','pointerdown'].forEach(function(evt) {
      div.addEventListener(evt, function(e) {
        e.preventDefault();
        e.stopImmediatePropagation();
      }, { capture: true });
    });

    return div;
  }

  function overlayContainer(container) {
    if (!container) return;
    if (container.querySelector('[' + BLOCKED_ATTR + ']')) return; // already overlaid
    container.style.position = 'relative';
    container.style.overflow = 'hidden';
    container.appendChild(buildOverlay());
  }

  function blockDmReels() {
    try {
      // Strategy 1: <a href*="/reel/"> links inside the DM thread
      document.querySelectorAll('a[href*="/reel/"]').forEach(function(link) {
        try {
          link.style.setProperty('pointer-events', 'none', 'important');
          overlayContainer(link.closest('div') || link.parentElement);
        } catch(_) {}
      });

      // Strategy 2: <video> inside DMs (reel cards without <a> wrapper)
      // Only targets videos inside the Direct thread or on /direct/ path
      document.querySelectorAll('video').forEach(function(video) {
        try {
          const inDm = !!video.closest('[aria-label="Direct"], [aria-label*="Direct"]');
          const isDmPath = window.location.pathname.includes('/direct/');
          if (!inDm && !isDmPath) return;

          const container = video.closest('div[class]') || video.parentElement;
          if (!container) return;
          video.style.setProperty('pointer-events', 'none', 'important');
          overlayContainer(container);
        } catch(_) {}
      });
    } catch(_) {}
  }

  blockDmReels();

  let _t = null;
  new MutationObserver(function() {
    clearTimeout(_t);
    _t = setTimeout(blockDmReels, 200);
  }).observe(document.documentElement, { childList: true, subtree: true });
})();
''';
