/**
 * eBay URL Parser Service (Stub)
 * Extrahiert Account-Daten aus eBay-URLs
 * 
 * WICHTIG: Dies ist eine Stub-Implementierung ohne echte Network-Calls.
 * Später wird diese Funktion durch einen Call zur Browser-Extension ersetzt.
 * 
 * Regeln:
 * - Deterministisch: Gleiche URL → gleiche Daten
 * - Keine Network-Calls (kein fetch, kein iframe, kein HTML-Parsing)
 * - Ersetzbar durch Extension-Call
 */

/**
 * Einfacher stabiler Hash für deterministische IDs
 * @param {string} str - Input string
 * @returns {string} - Hash string
 */
function stableHash(str) {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    const char = str.charCodeAt(i);
    hash = ((hash << 5) - hash) + char;
    hash = hash & hash; // Convert to 32bit integer
  }
  return Math.abs(hash).toString(36).padStart(10, '0');
}

/**
 * Extrahiert Marktplatz aus eBay-URL (Domain)
 * @param {string} url - eBay-URL
 * @returns {string} - Market Code (z.B. "DE", "US", "UK")
 */
function extractMarketFromUrl(url) {
  try {
    const urlObj = new URL(url);
    const hostname = urlObj.hostname.toLowerCase();

    // eBay Domain-Patterns
    if (hostname.includes('.de') || hostname.includes('ebay.de')) {
      return 'DE';
    }
    if (hostname.includes('.com') || hostname.includes('ebay.com')) {
      // Prüfe auf US-spezifische Patterns
      if (hostname.includes('ebay.com') && !hostname.includes('.uk')) {
        return 'US';
      }
    }
    if (hostname.includes('.uk') || hostname.includes('ebay.co.uk')) {
      return 'UK';
    }
    if (hostname.includes('.fr') || hostname.includes('ebay.fr')) {
      return 'FR';
    }
    if (hostname.includes('.it') || hostname.includes('ebay.it')) {
      return 'IT';
    }
    if (hostname.includes('.es') || hostname.includes('ebay.es')) {
      return 'ES';
    }
    if (hostname.includes('.nl') || hostname.includes('ebay.nl')) {
      return 'NL';
    }
    if (hostname.includes('.at') || hostname.includes('ebay.at')) {
      return 'AT';
    }
    if (hostname.includes('.ch') || hostname.includes('ebay.ch')) {
      return 'CH';
    }

    // Fallback: erster Teil der Domain nach "ebay."
    const match = hostname.match(/ebay\.([a-z]{2,3})/);
    if (match && match[1]) {
      return match[1].toUpperCase();
    }

    // Default: US
    return 'US';
  } catch (e) {
    return 'US'; // Fallback
  }
}

// Extension-ID Cache (gesetzt via postMessage vom Content Script)
let cachedExtensionId = null;

// Listener für Extension-ID vom Content Script
if (typeof window !== 'undefined') {
  window.addEventListener('message', (event) => {
    if (event.data?.source === 'eship-extension' && event.data?.type === 'EXTENSION_ID' && event.data?.extensionId) {
      cachedExtensionId = event.data.extensionId;
    }
  });
}

/**
 * Prüft ob die Browser-Extension verfügbar ist
 * @returns {boolean} - true wenn Extension verfügbar
 */
export function isExtensionAvailable() {
  if (typeof window === 'undefined') {
    return false;
  }
  
  // Prüfe ob Extension-ID gecacht ist (via postMessage empfangen)
  if (cachedExtensionId) {
    return true;
  }
  
  // Window flag (set by content script) - das ist das Haupt-Kriterium
  // Der Content Script setzt window.__EBAY_EXTENSION__ = true wenn er läuft
  const flagValue = window.__EBAY_EXTENSION__;
  if (flagValue === true) {
    return true;
  }
  
  // chrome.runtime.sendMessage allein bedeutet NICHT, dass die Extension verfügbar ist
  // (Chrome macht chrome.runtime auch ohne Extension verfügbar, aber ohne Extension-ID können wir sie nicht nutzen)
  // Daher: Nur window.__EBAY_EXTENSION__ ist der zuverlässige Indikator
  
  return false;
}

/**
 * Holt Extension-ID (für externally_connectable messaging)
 * @returns {Promise<string|null>} - Extension-ID oder null
 */
async function getExtensionId() {
  try {
    // Methode 1: Verwende gecachte Extension-ID (via postMessage vom Content Script empfangen)
    if (cachedExtensionId) {
      return cachedExtensionId;
    }
    
    // Retry-Mechanismus: Warte auf postMessage vom Content Script
    for (let attempt = 0; attempt < 10; attempt++) {
      if (cachedExtensionId) {
        return cachedExtensionId;
      }
      
      // Warte kurz vor dem nächsten Versuch (außer beim letzten Versuch)
      if (attempt < 9) {
        await new Promise(resolve => setTimeout(resolve, 200)); // 200ms delay
      }
    }
    
    return null; // Nicht verfügbar
  } catch (e) {
    return null;
  }
}

/**
 * Parst eine eBay-URL über die Browser-Extension
 * @param {string} url - eBay-Verkäuferprofil oder Shop-URL
 * @returns {Promise<{sellerId: string, shopName: string, market: string, status: "active" | "unknown", stats?: object}>}
 * @throws {Error} - "Extension not available" oder andere Fehler
 */
async function parseViaExtension(url) {
  // Validierung
  if (!url || typeof url !== 'string') {
    throw new Error("Invalid URL");
  }
  
  // Methode 1: chrome.runtime.sendMessage (externally_connectable)
  // Versuche zuerst mit Extension-ID, dann ohne (Chrome findet Extension automatisch bei externally_connectable)
  if (typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.sendMessage) {
    try {
      const extensionId = await getExtensionId();
      
      // Versuche chrome.runtime.sendMessage (mit oder ohne Extension-ID)
      return new Promise((resolve, reject) => {
        const message = {
          action: "PARSE_URL",
          url: url
        };
        
        // SendMessage-Callback
        const sendMessageCallback = (response) => {
          // Check for Chrome runtime errors
          if (chrome.runtime.lastError) {
            const errorMsg = chrome.runtime.lastError.message || "Extension communication error";
            reject(new Error(errorMsg));
            return;
          }
          
          if (response && response.ok && response.data) {
            // Ensure stats object is included (even if empty)
            let sellerId = response.data.sellerId || "";
            
            // Fallback: Wenn Extension keinen sellerId liefert, versuche aus URL zu extrahieren
            if (!sellerId || sellerId.trim() === "") {
              // Versuche _ssn Parameter aus Suchergebnis-URLs zu extrahieren
              const ssnMatch = url.match(/[?&]_ssn=([^&]+)/i);
              if (ssnMatch && ssnMatch[1]) {
                sellerId = decodeURIComponent(ssnMatch[1]).trim();
              }
            }
            
            const data = {
              sellerId: sellerId,
              shopName: response.data.shopName || "",
              market: response.data.market || "US",
              status: response.data.status || "unknown",
              stats: response.data.stats || {}
            };
            resolve(data);
          } else {
            reject(new Error(response?.error || "Extension parsing failed"));
          }
        };
        
        // Benötigt Extension-ID (sendMessage von Webseiten aus erfordert immer Extension-ID)
        if (!extensionId) {
          reject(new Error("Extension ID not available"));
          return;
        }
        
        chrome.runtime.sendMessage(extensionId, message, sendMessageCallback);
      
        // Timeout nach 20s (Extension hat intern 15s, hier etwas mehr Puffer)
        setTimeout(() => {
          reject(new Error("Extension timeout"));
        }, 20000);
      });
    } catch (error) {
      // Chrome API Fehler: Fallback zu window.postMessage wenn möglich
      if (error.message && !error.message.includes("Extension")) {
        throw error;
      }
      // Weiter zu Methode 2
    }
  }
  
  // Methode 2: Window flag + postMessage (falls Content Script Relay vorhanden)
  if (window.__EBAY_EXTENSION__ === true) {
    return new Promise((resolve, reject) => {
      const messageId = `parse_${Date.now()}_${Math.random()}`;
      
      // Listener für Antwort
      const responseHandler = (event) => {
        if (event.data?.source !== 'eship-extension' || event.data?.messageId !== messageId) {
          return;
        }
        
        window.removeEventListener('message', responseHandler);
        
        if (event.data?.ok && event.data?.data) {
          let sellerId = event.data.data.sellerId || "";
          
          // Fallback: Wenn Extension keinen sellerId liefert, versuche aus URL zu extrahieren
          if (!sellerId || sellerId.trim() === "") {
            // Versuche _ssn Parameter aus Suchergebnis-URLs zu extrahieren
            const ssnMatch = url.match(/[?&]_ssn=([^&]+)/i);
            if (ssnMatch && ssnMatch[1]) {
              sellerId = decodeURIComponent(ssnMatch[1]).trim();
            }
          }
          
          const data = {
            sellerId: sellerId,
            shopName: event.data.data.shopName || "",
            market: event.data.data.market || "US",
            status: event.data.data.status || "unknown",
            stats: event.data.data.stats || {}
          };
          resolve(data);
        } else {
          reject(new Error(event.data?.error || "Extension parsing failed"));
        }
      };
      
      window.addEventListener('message', responseHandler);
      
      // Sende Request via postMessage
      window.postMessage({
        source: 'eship-webapp',
        action: 'PARSE_URL',
        url: url,
        messageId: messageId
      }, '*');
      
      // Timeout
      setTimeout(() => {
        window.removeEventListener('message', responseHandler);
        reject(new Error("Extension timeout"));
      }, 20000);
    });
  }
  
  // Keine Extension verfügbar
  throw new Error("Extension not available");
}

/**
 * Parst eine eBay-URL über die Browser-Extension für Produkt-Scan
 * @param {string} url - eBay-Verkäuferprofil oder Shop-URL
 * @param {string} accountId - Account-ID (wird an Extension übergeben)
 * @returns {Promise<Array>} - Array von Produkt-Items
 * @throws {Error} - "Extension not available" oder andere Fehler
 */
export async function parseViaExtensionScanProducts(url, accountId) {
  // Validierung
  if (!url || typeof url !== 'string') {
    throw new Error("Invalid URL");
  }
  
  if (!accountId || typeof accountId !== 'string') {
    throw new Error("Invalid accountId");
  }
  
  // Methode 1: chrome.runtime.sendMessage (externally_connectable)
  if (typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.sendMessage) {
    try {
      const extensionId = await getExtensionId();
      
      // Versuche chrome.runtime.sendMessage (mit oder ohne Extension-ID)
      return new Promise((resolve, reject) => {
        const message = {
          action: "SCAN_PRODUCTS",
          url: url,
          accountId: accountId
        };
        
        const SCAN_TIMEOUT_MS = 300000;

        // SendMessage-Callback
        const sendMessageCallback = (response) => {
          clearTimeout(timeoutId);
          // Check for Chrome runtime errors
          if (chrome.runtime.lastError) {
            const errorMsg = chrome.runtime.lastError.message || "Extension communication error";
            reject(new Error(errorMsg));
            return;
          }
          
          console.log("[ebayParserService] SCAN_PRODUCTS response:", response);
          
          if (response && response.ok) {
            const items = response.data?.items || response.items || [];
            const meta = response.data?.meta || response.meta || {};
            
            if (!Array.isArray(items) || items.length === 0) {
              const errorMsg = response?.error || "no_items_found";
              const error = new Error(`SCAN_PRODUCTS failed: ${errorMsg} (${meta.pageType || "unknown"})`);
              error.meta = meta;
              reject(error);
              return;
            }
            
            resolve(items);
          } else {
            const meta = response?.meta || {};
            const errorMsg = response?.error || "Extension scanning failed";
            console.log("[ebayParserService] SCAN_PRODUCTS error:", errorMsg, "meta:", meta);
            const error = new Error(`SCAN_PRODUCTS failed: ${errorMsg} (${meta.pageType || "unknown"})`);
            error.meta = meta;
            reject(error);
          }
        };
        
        if (!extensionId) {
          reject(new Error("Extension ID not available"));
          return;
        }
        
        const timeoutId = setTimeout(() => {
          reject(new Error("Extension timeout"));
        }, SCAN_TIMEOUT_MS);
        
        chrome.runtime.sendMessage(extensionId, message, sendMessageCallback);
      });
    } catch (error) {
      // Chrome API Fehler: weiter zu Methode 2
      if (error.message && !error.message.includes("Extension")) {
        throw error;
      }
      // Weiter zu Methode 2
    }
  }
  
  // Methode 2: Window flag + postMessage (falls Content Script Relay vorhanden)
  if (typeof window !== 'undefined' && window.__EBAY_EXTENSION__ === true) {
    const SCAN_TIMEOUT_MS = 300000;
    return new Promise((resolve, reject) => {
      const messageId = `scan_${Date.now()}_${Math.random()}`;
      let settled = false;

      const finish = (fn) => {
        if (settled) return;
        settled = true;
        clearTimeout(timeoutId);
        window.removeEventListener('message', responseHandler);
        fn();
      };

      const responseHandler = (event) => {
        if (event.data?.source !== 'eship-extension' || event.data?.messageId !== messageId) {
          return;
        }
        
        if (event.data?.ok && event.data?.data) {
          const items = event.data.data.items || event.data.items || [];
          const meta = event.data.data.meta || event.data.meta || {};
          
          if (!Array.isArray(items) || items.length === 0) {
            const errorMsg = event.data?.error || "no_items_found";
            const error = new Error(`SCAN_PRODUCTS failed: ${errorMsg} (${meta.pageType || "unknown"})`);
            error.meta = meta;
            finish(() => reject(error));
            return;
          }
          finish(() => resolve(items));
        } else {
          const meta = event.data?.meta || event.data?.data?.meta || {};
          const errorMsg = event.data?.error || "Extension scanning failed";
          const error = new Error(`SCAN_PRODUCTS failed: ${errorMsg} (${meta.pageType || "unknown"})`);
          error.meta = meta;
          finish(() => reject(error));
        }
      };
      
      window.addEventListener('message', responseHandler);
      
      const timeoutId = setTimeout(() => {
        finish(() => reject(new Error("Extension timeout")));
      }, SCAN_TIMEOUT_MS);
      
      window.postMessage({
        source: 'eship-webapp',
        action: 'SCAN_PRODUCTS',
        url: url,
        accountId: accountId,
        messageId: messageId
      }, '*');
    });
  }
  
  // Keine Extension verfügbar - kein Stub für Produkt-Scan (User will echte Daten)
  throw new Error("Extension not available");
}

/**
 * Holt den aktuellen Scan-Fortschritt von der Extension (für Polling während SCAN_PRODUCTS).
 * @returns {Promise<{ percent: number, phase: string, total: number, current: number, complete: boolean }|null>}
 */
export async function getScanProgress() {
  if (typeof chrome === "undefined" || !chrome?.runtime?.sendMessage) {
    return null;
  }
  try {
    const extensionId = await getExtensionId();
    if (!extensionId) return null;
    return new Promise((resolve) => {
      chrome.runtime.sendMessage(extensionId, { action: "GET_SCAN_PROGRESS" }, (response) => {
        if (chrome.runtime.lastError) {
          resolve(null);
          return;
        }
        resolve(response ?? null);
      });
    });
  } catch {
    return null;
  }
}

/**
 * Parst eine eBay-URL mit Stub-Logik (deterministisch, keine Network-Calls)
 * @param {string} url - eBay-Verkäuferprofil oder Shop-URL
 * @returns {Promise<{sellerId: string, shopName: string, market: string, status: "active" | "unknown"}>}
 * @throws {Error} - Wenn URL ungültig ist oder keine eBay-URL
 */
async function parseViaStub(url) {
  // Validierung: Muss gültige URL sein
  let urlObj;
  try {
    urlObj = new URL(url);
  } catch (e) {
    throw new Error("Bitte gib eine gültige URL ein.");
  }

  // Validierung: Muss eBay-URL sein
  const hostname = urlObj.hostname.toLowerCase();
  if (!hostname.includes('ebay.')) {
    throw new Error("Bitte gib eine gültige eBay-URL ein.");
  }

  // Stub-Implementierung: Deterministische Daten aus URL generieren
  const hash = stableHash(url);
  const market = extractMarketFromUrl(url);

  // Seller ID: Versuche zuerst aus URL zu extrahieren (_ssn Parameter)
  let sellerId = "";
  const ssnMatch = url.match(/[?&]_ssn=([^&]+)/i);
  if (ssnMatch && ssnMatch[1]) {
    sellerId = decodeURIComponent(ssnMatch[1]).trim();
  }
  
  // Fallback: Deterministic aus URL-Hash wenn kein _ssn Parameter gefunden
  if (!sellerId || sellerId.trim() === "") {
    // Format: "ebay_" + hash (first 10 chars)
    sellerId = `ebay_${hash.slice(0, 10)}`;
  }

  // Shop Name: Generiert aus Hash (last 4 chars als Suffix)
  const shopNameSuffix = hash.slice(-4);
  const shopName = `eBay Seller ${shopNameSuffix}`;

  // Status: Immer "active" für Stub
  const status = "active";

  return {
    sellerId,
    shopName,
    market,
    status,
    stats: {
      itemsSold: null, // Stub liefert keine echten Daten
    },
  };
}

/**
 * Parst eine eBay-URL und extrahiert Account-Daten (Facade)
 * Versucht zuerst Extension-Pfad, fällt zurück auf Stub-Implementierung
 * @param {string} url - eBay-Verkäuferprofil oder Shop-URL
 * @returns {Promise<{sellerId: string, shopName: string, market: string, status: "active" | "unknown", stats?: object}>}
 * @throws {Error} - Wenn URL ungültig ist oder keine eBay-URL
 */
export async function parseEbayAccount(url) {
  // Versuche IMMER Extension-Pfad zuerst (auch wenn Flag nicht gesetzt)
  // parseViaExtension prüft selbst, ob Extension verfügbar ist
  try {
    // Versuche Extension zu nutzen (auch wenn Flag nicht gesetzt - parseViaExtension prüft selbst)
    return await parseViaExtension(url);
  } catch (e) {
    // Extension-Fehler: Fallback zu Stub
    console.warn("Extension parsing failed, falling back to stub:", e.message);
  }

  // Fallback: Stub-Implementierung
  return await parseViaStub(url);
}