/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
import { useEffect } from 'react';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';

// File extensions to track as downloads
const DOWNLOAD_EXTENSIONS = [
  'pdf', 'zip', 'tar', 'gz', 'tgz', 'bz2',
  'exe', 'dmg', 'pkg', 'deb', 'rpm',
  'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx',
  'csv', 'json', 'yaml', 'yml',
];

// Scroll depth milestones to track
const SCROLL_MILESTONES = [25, 50, 75, 100];

export default function Root({ children }) {
  const { siteConfig } = useDocusaurusContext();
  const { customFields } = siteConfig;

  useEffect(() => {
    const { matomoUrl, matomoSiteId } = customFields;

    if (typeof window !== 'undefined') {
      const devMode = ['localhost', '127.0.0.1', '::1', '0.0.0.0'].includes(window.location.hostname);

      // Initialize the _paq array
      window._paq = window._paq || [];

      // Configure the tracker before loading matomo.js
      window._paq.push(['enableHeartBeatTimer']);
      window._paq.push(['enableLinkTracking']);
      window._paq.push(['setTrackerUrl', `${matomoUrl}/matomo.php`]);
      window._paq.push(['setSiteId', matomoSiteId]);

      // Track downloads with custom extensions
      window._paq.push(['setDownloadExtensions', DOWNLOAD_EXTENSIONS.join('|')]);

      // Now load the matomo.js script
      const script = document.createElement('script');
      script.async = true;
      script.src = `${matomoUrl}/matomo.js`;
      document.head.appendChild(script);

      // Helper to track events
      const trackEvent = (category, action, name, value) => {
        if (devMode) {
          console.log('Matomo trackEvent:', { category, action, name, value });
        }
        window._paq.push(['trackEvent', category, action, name, value]);
      };

      // Helper to track site search
      const trackSiteSearch = (keyword, category, resultsCount) => {
        if (devMode) {
          console.log('Matomo trackSiteSearch:', { keyword, category, resultsCount });
        }
        window._paq.push(['trackSiteSearch', keyword, category, resultsCount]);
      };

      // Helper to track page views
      const trackPageView = (url, title) => {
        if (devMode) {
          console.log('Matomo trackPageView:', { url, title });
        }
        window._paq.push(['trackPageView']);
      };


      // Track external link clicks using domain as category (vendor-agnostic)
      const handleLinkClick = (event) => {
        const link = event.target.closest('a');
        if (!link) return;

        const href = link.getAttribute('href');
        if (!href) return;

        try {
          const url = new URL(href, window.location.origin);

          // Skip internal links
          if (url.hostname === window.location.hostname) return;

          // Use hostname as category for vendor-agnostic tracking
          trackEvent('Outbound Link', url.hostname, href);
        } catch {
          // Invalid URL, skip tracking
        }
      };

      // Track Algolia search queries
      const setupAlgoliaTracking = () => {
        const observer = new MutationObserver((mutations) => {
          mutations.forEach((mutation) => {
            mutation.addedNodes.forEach((node) => {
              if (node.nodeType === Node.ELEMENT_NODE) {
                const searchInput = node.querySelector?.('.DocSearch-Input') ||
                                   (node.classList?.contains('DocSearch-Input') ? node : null);
                if (searchInput) {
                  let debounceTimer;
                  searchInput.addEventListener('input', (e) => {
                    clearTimeout(debounceTimer);
                    debounceTimer = setTimeout(() => {
                      const query = e.target.value.trim();
                      if (query.length >= 3) {
                        const results = document.querySelectorAll('.DocSearch-Hit');
                        trackSiteSearch(query, 'Documentation', results.length);
                      }
                    }, 1000);
                  });
                }
              }
            });
          });
        });

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

      // Track video plays
      const handleVideoPlay = (event) => {
        if (event.target.tagName === 'VIDEO') {
          const videoSrc = event.target.currentSrc || event.target.src || 'unknown';
          trackEvent('Video', 'Play', videoSrc);
        }
      };

      // Track CTA button clicks
      const handleCTAClick = (event) => {
        const button = event.target.closest('.get-started-button, .default-button-theme');
        if (button) {
          const buttonText = button.textContent?.trim() || 'Unknown';
          const clickedLink = event.target.closest?.('a');
          const href =
            clickedLink?.getAttribute('href') || button.getAttribute('href') || '';
          trackEvent('CTA', 'Click', `${buttonText} - ${href}`);
        }
      };

      // Track scroll depth
      let scrollMilestonesReached = new Set();
      const handleScroll = () => {
        const scrollTop = window.scrollY;
        const docHeight = document.documentElement.scrollHeight - window.innerHeight;
        if (docHeight <= 0) return;

        const scrollPercent = Math.round((scrollTop / docHeight) * 100);

        SCROLL_MILESTONES.forEach(milestone => {
          if (scrollPercent >= milestone && !scrollMilestonesReached.has(milestone)) {
            scrollMilestonesReached.add(milestone);
            trackEvent('Scroll Depth', `${milestone}%`, window.location.pathname);
          }
        });
      };

      // Reset scroll tracking on route change
      const resetScrollTracking = () => {
        scrollMilestonesReached = new Set();
      };

      // Track 404 pages
      const track404 = () => {
        const is404 = document.querySelector('.theme-doc-404') ||
                      document.title.toLowerCase().includes('not found') ||
                      document.querySelector('h1')?.textContent?.toLowerCase().includes('not found');
        if (is404) {
          trackEvent('Error', '404', window.location.pathname);
          if (devMode) {
            console.log('Matomo: 404 page detected', window.location.pathname);
          }
        }
      };

      // Track copy-to-clipboard events on code blocks
      const handleCopy = (event) => {
        const codeBlock = event.target.closest('pre, code, .prism-code');
        if (codeBlock) {
          const codeText = window.getSelection()?.toString() || '';
          const codeSnippet = codeText.substring(0, 100) + (codeText.length > 100 ? '...' : '');
          trackEvent('Code', 'Copy', `${window.location.pathname}: ${codeSnippet}`);
        }
      };

      // Track color mode preference (as event, no admin config needed)
      const trackColorMode = () => {
        const colorMode = document.documentElement.getAttribute('data-theme') ||
                         (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
        trackEvent('User Preference', 'Color Mode', colorMode);
      };

      // Track docs version from URL (as event, no admin config needed)
      const trackDocsVersion = () => {
        const pathMatch = window.location.pathname.match(/\/docs\/([\d.]+)\//);
        const version = pathMatch ? pathMatch[1] : 'latest';
        trackEvent('User Preference', 'Docs Version', version);
      };

      // Handle route changes for SPA
      const handleRouteChange = () => {
        if (devMode) {
          console.log('Route changed to:', window.location.pathname);
        }

        // Reset scroll tracking for new page
        resetScrollTracking();

        setTimeout(() => {
          const currentTitle = document.title;
          const currentPath = window.location.pathname;

          // Set custom dimensions before tracking page view
          trackColorMode();
          trackDocsVersion();

          if (devMode) {
            window._paq.push(['setDomains', ['superset.apache.org']]);
            window._paq.push([
              'setCustomUrl',
              'https://superset.apache.org' + currentPath,
            ]);
          } else {
            window._paq.push(['setCustomUrl', currentPath]);
          }

          window._paq.push(['setReferrerUrl', window.location.href]);
          window._paq.push(['setDocumentTitle', currentTitle]);
          trackPageView(currentPath, currentTitle);

          // Check for 404 after page renders
          setTimeout(track404, 500);
        }, 100);
      };

      // Set up Docusaurus route listeners
      const possibleEvents = [
        'docusaurus.routeDidUpdate',
        'docusaurusRouteDidUpdate',
        'routeDidUpdate',
      ];

      if (devMode) {
        console.log('Setting up Matomo tracking with enhanced features');
      }

      // Store handler references for proper cleanup
      const routeHandlers = possibleEvents.map(eventName => {
        const handler = () => {
          if (devMode) {
            console.log(`Docusaurus route update detected via ${eventName}`);
          }
          handleRouteChange();
        };
        document.addEventListener(eventName, handler);
        return { eventName, handler };
      });

      // Manual history tracking as fallback
      const originalPushState = window.history.pushState;
      window.history.pushState = function () {
        originalPushState.apply(this, arguments);
        handleRouteChange();
      };

      window.addEventListener('popstate', handleRouteChange);

      // Set up event listeners
      document.addEventListener('click', handleLinkClick);
      document.addEventListener('click', handleCTAClick);
      document.addEventListener('play', handleVideoPlay, true);
      document.addEventListener('copy', handleCopy);
      window.addEventListener('scroll', handleScroll, { passive: true });

      // Watch for color mode changes
      const colorModeObserver = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
          if (mutation.attributeName === 'data-theme') {
            trackEvent('User Preference', 'Color Mode Change',
              document.documentElement.getAttribute('data-theme'));
          }
        });
      });
      colorModeObserver.observe(document.documentElement, { attributes: true });

      // Set up Algolia tracking
      const algoliaObserver = setupAlgoliaTracking();

      // Initial page tracking
      handleRouteChange();

      // Cleanup
      return () => {
        routeHandlers.forEach(({ eventName, handler }) => {
          document.removeEventListener(eventName, handler);
        });

        if (originalPushState) {
          window.history.pushState = originalPushState;
          window.removeEventListener('popstate', handleRouteChange);
        }

        document.removeEventListener('click', handleLinkClick);
        document.removeEventListener('click', handleCTAClick);
        document.removeEventListener('play', handleVideoPlay, true);
        document.removeEventListener('copy', handleCopy);
        window.removeEventListener('scroll', handleScroll);

        if (algoliaObserver) {
          algoliaObserver.disconnect();
        }
        if (colorModeObserver) {
          colorModeObserver.disconnect();
        }
      };
    }
  }, []);

  return children;
}
