/**
 * Kleap Next.js Error Detector
 *
 * Detects and reports Next.js build/runtime errors to parent window via postMessage
 * Works with Next.js 15 error overlay system
 *
 * Version: 1.0.0
 */
(function () {
  console.debug('[Kleap] Next.js error detector loaded v1.0.0');

  // Only run inside iframe
  const isInsideIframe = window.parent !== window;
  if (!isInsideIframe) {
    console.debug('[Kleap] Not inside iframe, skipping error detection');
    return;
  }

  const PARENT_TARGET_ORIGIN = '*';

  // Track reported errors to avoid duplicates
  const reportedErrors = new Set();
  const ERROR_COOLDOWN_MS = 5000;

  /**
   * Send error report to parent window
   */
  function reportError(errorData) {
    const errorKey = `${errorData.type}-${errorData.message}`;

    // Check if already reported recently
    if (reportedErrors.has(errorKey)) {
      console.debug('[Kleap] Error already reported, skipping:', errorKey);
      return;
    }

    // Mark as reported
    reportedErrors.add(errorKey);
    setTimeout(() => reportedErrors.delete(errorKey), ERROR_COOLDOWN_MS);

    console.log('[Kleap] Reporting error to parent:', errorData);

    window.parent.postMessage(
      {
        type: 'nextjs-build-error',
        payload: errorData,
      },
      PARENT_TARGET_ORIGIN
    );
  }

  /**
   * Extract error details from Next.js error overlay
   */
  function extractNextJsError(container) {
    try {
      // Next.js 15 error overlay structure
      // Look for common error patterns

      // Method 1: Check for Next.js error container
      const errorTitle = container.querySelector('[data-nextjs-dialog-header]');
      const errorBody = container.querySelector('[data-nextjs-dialog-body]');

      if (errorTitle || errorBody) {
        const title = errorTitle?.textContent?.trim() || '';
        const body = errorBody?.textContent?.trim() || '';

        return {
          type: 'build-error',
          message: title || 'Build error detected',
          details: body,
          fullText: `${title}\n\n${body}`.trim(),
        };
      }

      // Method 2: Look for error message in generic containers
      const h4 = container.querySelector('h4');
      const pre = container.querySelector('pre');

      if (h4 || pre) {
        return {
          type: 'build-error',
          message: h4?.textContent?.trim() || 'Build error',
          details: pre?.textContent?.trim() || '',
          fullText: container.textContent?.trim() || 'Unknown error',
        };
      }

      // Method 3: Generic text extraction
      const text = container.textContent?.trim();
      if (text && text.length > 10) {
        // Check for common Next.js error patterns
        if (text.includes('Module not found') ||
            text.includes("Can't resolve") ||
            text.includes('Build Error') ||
            text.includes('Compile Error') ||
            text.includes('Runtime Error')) {

          // Extract first meaningful line as message
          const lines = text.split('\n').map(l => l.trim()).filter(Boolean);
          const message = lines[0] || 'Build error detected';

          return {
            type: 'build-error',
            message: message.substring(0, 200), // Limit length
            details: text.substring(0, 1000), // Limit details
            fullText: text.substring(0, 2000), // Full context
          };
        }
      }

      return null;
    } catch (error) {
      console.error('[Kleap] Error extracting Next.js error:', error);
      return null;
    }
  }

  /**
   * Watch for Next.js error overlay in DOM
   */
  function watchForNextJsErrors() {
    console.debug('[Kleap] Setting up Next.js error detection');

    // Configuration for MutationObserver
    const config = {
      childList: true,
      subtree: true, // Watch all descendants (Next.js uses portals)
      attributes: false,
    };

    // Callback when DOM changes
    const observerCallback = function (mutationsList) {
      for (const mutation of mutationsList) {
        if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
          for (const node of mutation.addedNodes) {
            if (node.nodeType !== Node.ELEMENT_NODE) continue;

            // Check for Next.js error overlay elements
            // Next.js 15 uses various IDs and attributes
            const isErrorOverlay =
              node.id?.includes('nextjs') ||
              node.id?.includes('error') ||
              node.getAttribute?.('data-nextjs-dialog') !== null ||
              node.getAttribute?.('data-nextjs-toast') !== null ||
              node.className?.includes?.('nextjs') ||
              node.className?.includes?.('error-overlay');

            if (isErrorOverlay) {
              console.log('[Kleap] Detected Next.js error overlay:', node);

              // Wait a bit for content to populate
              setTimeout(() => {
                const errorData = extractNextJsError(node);
                if (errorData) {
                  reportError(errorData);
                }
              }, 100);
            }

            // Also check children recursively
            if (node.querySelector) {
              const errorChildren = node.querySelectorAll('[data-nextjs-dialog], [data-nextjs-toast], [id*="nextjs"], [id*="error"]');
              errorChildren.forEach(child => {
                setTimeout(() => {
                  const errorData = extractNextJsError(child);
                  if (errorData) {
                    reportError(errorData);
                  }
                }, 100);
              });
            }
          }
        }
      }
    };

    // Start observing when DOM is ready
    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', () => {
        console.debug('[Kleap] DOM loaded, starting error detection');
        const observer = new MutationObserver(observerCallback);
        observer.observe(document.body || document.documentElement, config);

        // Check for existing errors
        checkExistingErrors();
      });
    } else {
      console.debug('[Kleap] DOM already loaded, starting error detection');
      const observer = new MutationObserver(observerCallback);
      observer.observe(document.body || document.documentElement, config);

      // Check for existing errors
      checkExistingErrors();
    }
  }

  /**
   * Check for errors that already exist in the DOM
   */
  function checkExistingErrors() {
    console.debug('[Kleap] Checking for existing errors');

    try {
      // Look for Next.js error elements
      const selectors = [
        '[data-nextjs-dialog]',
        '[data-nextjs-toast]',
        '[id*="nextjs"][id*="error"]',
        'div[class*="error-overlay"]',
      ];

      selectors.forEach(selector => {
        const elements = document.querySelectorAll(selector);
        elements.forEach(element => {
          console.log('[Kleap] Found existing error element:', element);
          const errorData = extractNextJsError(element);
          if (errorData) {
            reportError(errorData);
          }
        });
      });
    } catch (error) {
      console.error('[Kleap] Error checking existing errors:', error);
    }
  }

  /**
   * Also intercept console.error for build errors
   * Next.js sometimes logs errors to console before showing overlay
   */
  const originalConsoleError = console.error;
  console.error = function(...args) {
    // Call original
    originalConsoleError.apply(console, args);

    // Check if it looks like a Next.js error
    const message = args.map(arg =>
      typeof arg === 'string' ? arg : String(arg)
    ).join(' ');

    if (message.includes('Module not found') ||
        message.includes("Can't resolve 'tailwindcss'") ||
        message.includes('Build Error') ||
        message.includes('Compile Error')) {

      console.log('[Kleap] Detected build error in console.error');

      reportError({
        type: 'build-error',
        message: message.substring(0, 200),
        details: message.substring(0, 1000),
        fullText: message.substring(0, 2000),
        source: 'console.error',
      });
    }
  };

  // Start watching
  watchForNextJsErrors();

  console.debug('[Kleap] Next.js error detector initialized');
})();
