// WebDrop Bridge - Intercept Version
// Prevents browser drag for ALT+drag, hands off to Qt for file drag

(function() {
  try {
    if (window.__webdrop_intercept_injected) return;
    window.__webdrop_intercept_injected = true;

    // Intercept mode enabled
    var INTERCEPT_ENABLED = true;

    console.log('%c[WebDrop Intercept] Script loaded - INTERCEPT_ENABLED=' + INTERCEPT_ENABLED, 'background: #2196F3; color: white; font-weight: bold; padding: 4px 8px;');
    
    var currentDragUrls = [];  // Array to support multiple URLs
    var angularDragHandlers = [];
    var originalAddEventListener = EventTarget.prototype.addEventListener;
    var listenerPatchActive = true;
    var dragHandlerInstalled = false;
    
    // Capture Authorization token from XHR requests (only if checkout is enabled)
    window.capturedAuthToken = null;
    if (window.webdropConfig && window.webdropConfig.enableCheckout) {
      console.log('[Intercept] Auth token capture enabled (checkout feature active)');
      var originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
      XMLHttpRequest.prototype.setRequestHeader = function(header, value) {
        if (header === 'Authorization' && value.startsWith('Bearer ')) {
          window.capturedAuthToken = value;
          console.log('[Intercept] Captured auth token');
        }
        return originalXHRSetRequestHeader.apply(this, arguments);
      };
    } else {
      console.log('[Intercept] Auth token capture disabled (checkout feature inactive)');
    }
    
    // Only patch addEventListener for dragstart events
    // This minimizes impact on other event listeners (mouseover, mouseenter, etc.)
    EventTarget.prototype.addEventListener = function(type, listener, options) {
      if (listenerPatchActive && type === 'dragstart' && listener) {
        // Store Angular's dragstart handler instead of registering it
        console.log('[Intercept] Storing Angular dragstart listener for', this.tagName || this.constructor.name);
        angularDragHandlers.push({
          target: this,
          listener: listener,
          options: options
        });
        return; // Don't actually register it yet
      }
      // All other events (mouseover, mouseenter, mousedown, etc.): use original
      // This is critical to ensure mouseover/hover events work properly
      return originalAddEventListener.call(this, type, listener, options);
    };
  
  // ============================================================================
  // PART 2: Intercept DataTransfer.setData to capture URL
  // ============================================================================
  
  var originalSetData = DataTransfer.prototype.setData;
  
  DataTransfer.prototype.setData = function(format, data) {
    if (format === 'text/plain' || format === 'text/uri-list') {
      // text/uri-list contains newline-separated URLs
      // text/plain may be single URL or multiple newline-separated URLs
      currentDragUrls = data.trim().split('\n').filter(function(url) {
        return url.trim().length > 0;
      }).map(function(url) {
        return url.trim();
      });
      console.log('%c[Intercept] Captured ' + currentDragUrls.length + ' URL(s)', 'color: #4CAF50; font-weight: bold;', currentDragUrls[0].substring(0, 60));
    }
    return originalSetData.call(this, format, data);
  };
  
  console.log('[Intercept] DataTransfer.setData patched ✓');
  
  // ============================================================================
  // PART 3: Install OUR dragstart handler in capture phase
  // ============================================================================
  
  function installDragHandler() {
    console.log('[Intercept] Installing dragstart handler, have', angularDragHandlers.length, 'Angular handlers');

    if (angularDragHandlers.length === 0) {
      console.warn('[Intercept] No Angular handlers found yet, will retry in 1s...');
      setTimeout(installDragHandler, 1000);
      return;
    }

    // Only install once, even if called multiple times
    if (dragHandlerInstalled) {
      console.log('[Intercept] Handler already installed, skipping');
      return;
    }
    
    dragHandlerInstalled = true;
    
    // NOTE: Keep listenerPatchActive = true to catch new Angular handlers registered later
    // This is important for page reloads where Angular might register handlers at different times
    
    // Register OUR handler in capture phase
    originalAddEventListener.call(document, 'dragstart', function(e) {
      currentDragUrls = []; // Reset
      
      // Call Angular's handlers first to let them set the data
      var handled = 0;
      for (var i = 0; i < angularDragHandlers.length; i++) {
        var h = angularDragHandlers[i];
        if (h.target === document || h.target === e.target || 
            (h.target.contains && h.target.contains(e.target))) {
          try {
            h.listener.call(e.target, e);
            handled++;
          } catch(err) {
            console.error('[Intercept] Error calling Angular handler:', err);
          }
        }
      }
      
      console.log('[Intercept] Called', handled, 'Angular handlers, URLs:', currentDragUrls.length, 'URL(s)', currentDragUrls.length > 0 ? currentDragUrls[0].substring(0, 60) : 'none');
      
      // NOW check if we should intercept
      // Intercept any drag with URLs that match our configured mappings
      if (currentDragUrls.length > 0) {
        var shouldIntercept = false;

        // Check each URL against configured URL mappings
        // Intercept if ANY URL matches
        if (window.webdropConfig && window.webdropConfig.urlMappings) {
          for (var k = 0; k < currentDragUrls.length; k++) {
            var dragUrl = currentDragUrls[k];
            for (var j = 0; j < window.webdropConfig.urlMappings.length; j++) {
              var mapping = window.webdropConfig.urlMappings[j];
              if (dragUrl.toLowerCase().startsWith(mapping.url_prefix.toLowerCase())) {
                shouldIntercept = true;
                console.log('[Intercept] URL #' + (k+1) + ' matches mapping for:', mapping.local_path);
                break;
              }
            }
            if (shouldIntercept) break;
          }
        } else {
          // Fallback: Check for legacy Z: drive pattern if no config available
          for (var k = 0; k < currentDragUrls.length; k++) {
            if (/^z:/i.test(currentDragUrls[k])) {
              shouldIntercept = true;
              console.warn('[Intercept] Using fallback Z: drive pattern (no URL mappings configured)');
              break;
            }
          }
        }

        if (shouldIntercept) {
          console.log('%c[Intercept] PREVENTING browser drag, using Qt for ' + currentDragUrls.length + ' file(s)', 
                      'background: #F44336; color: white; font-weight: bold; padding: 4px 8px;');

          e.preventDefault();
          e.stopPropagation();

          ensureChannel(function() {
            if (window.bridge && typeof window.bridge.start_file_drag === 'function') {
              console.log('%c[Intercept] → Qt: start_file_drag with ' + currentDragUrls.length + ' file(s)', 'color: #9C27B0; font-weight: bold;');
              // Pass as JSON string to avoid Qt WebChannel array conversion issues
              window.bridge.start_file_drag(JSON.stringify(currentDragUrls));
            } else {
              console.error('[Intercept] bridge.start_file_drag not available!');
            }
          });

          currentDragUrls = [];
          return false;
        }
      }
      
      console.log('[Intercept] Normal drag, allowing browser');
    }, true); // Capture phase
    
    console.log('[Intercept] dragstart handler installed ✓');
  }

  // Wait for Angular to register its listeners, then install our handler
  // Start checking after 3 seconds (give Angular time to load), then retry for up to 30 seconds
  var installRetries = 0;
  var maxRetries = 27; // 3 initial + 27 retries * 1s = 30s total

  function scheduleInstall() {
    if (dragHandlerInstalled) return; // Already done
    installRetries++;
    console.log('[Intercept] Install attempt', installRetries, '/', maxRetries + 3);
    installDragHandler();
    if (!dragHandlerInstalled && installRetries < maxRetries) {
      setTimeout(scheduleInstall, 1000);
    } else if (!dragHandlerInstalled) {
      console.warn('[Intercept] Gave up waiting for Angular handlers after 30s');
    }
  }

  setTimeout(scheduleInstall, 3000);
  
  // ============================================================================
  // PART 3: QWebChannel connection
  // ============================================================================
  
  function ensureChannel(callback) {
    if (window.bridge) {
      callback();
      return;
    }
    
    if (window.QWebChannel && window.qt && window.qt.webChannelTransport) {
      new QWebChannel(window.qt.webChannelTransport, function(channel) {
        window.bridge = channel.objects.bridge;
        console.log('[WebDrop Intercept] QWebChannel connected ✓');
        callback();
      });
    } else {
      console.error('[WebDrop Intercept] QWebChannel not available!');
    }
  }
  
  // Initialize channel on load
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', function() {
      ensureChannel(function() {
        console.log('[WebDrop Intercept] Bridge ready ✓');
      });
    });
  } else {
    ensureChannel(function() {
      console.log('[WebDrop Intercept] Bridge ready ✓');
    });
  }
  
  console.log('%c[WebDrop Intercept] Ready! URL-mapped drags will use Qt file drag.', 
              'background: #4CAF50; color: white; font-weight: bold; padding: 4px 8px;');
  } catch(e) {
    console.error('[WebDrop Intercept] FATAL ERROR in bridge script:', e);
    console.error('[WebDrop Intercept] Stack:', e.stack);
  }
})();
