/**
 * eBay Content Script
 * Wird auf eBay-Seiten ausgeführt und extrahiert Verkäufer-/Shop-Daten aus dem DOM
 */

// Log dass Content Script geladen wurde
console.log("[EBAY-CONTENT] Content script loaded on:", window.location.href);

// Message Listener für Parsing-Anfragen
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  // Ping-Handler für Content Script Verfügbarkeitsprüfung
  if (message.action === "PING") {
    sendResponse({ ok: true, ready: true });
    return true;
  }

  if (message.action === "PARSE_EBAY") {
    // Wrapper um sicherzustellen, dass immer eine Antwort gesendet wird
    try {
      // Prüfe ob DOM bereit ist
      if (document.readyState === 'loading') {
        // DOM noch nicht bereit, warte kurz
        document.addEventListener('DOMContentLoaded', () => {
          try {
            const parsedData = parseEbayPage();
            sendResponse({ ok: true, data: parsedData });
          } catch (error) {
            console.error("[EBAY-CONTENT] Error parsing:", error);
            sendResponse({ 
              ok: true, 
              data: {
                sellerId: "",
                shopName: "",
                market: extractMarketFromHostname(),
                status: "unknown",
                stats: {}
              }
            });
          }
        }, { once: true });
        return true; // async response
      }
      
      // DOM ist bereit, parse sofort
      const parsedData = parseEbayPage();
      sendResponse({ ok: true, data: parsedData });
    } catch (error) {
      // Niemals unhandled throws - immer graceful response
      console.error("[EBAY-CONTENT] Error in parse handler:", error);
      sendResponse({ 
        ok: true, 
        data: {
          sellerId: "",
          shopName: "",
          market: extractMarketFromHostname(),
          status: "unknown",
          stats: {}
        }
      });
    }
    return true; // async response
  }

  if (message.action === "PARSE_ITEM_DETAIL") {
    try {
      const detail = parseItemDetailPage();
      sendResponse({ ok: true, data: detail });
    } catch (e) {
      console.warn("[EBAY-CONTENT] PARSE_ITEM_DETAIL error:", e);
      sendResponse({ ok: true, data: {} });
    }
    return true;
  }

  if (message.action === "PARSE_PRODUCT_LIST") {
    // async function, need to return promise
    parseProductList()
      .then(result => {
        // result hat bereits die Struktur { ok, items?, error?, meta }
        if (result.ok) {
          sendResponse({ 
            ok: true, 
            items: result.items || [],
            meta: result.meta || {}
          });
        } else {
          sendResponse({
            ok: false,
            error: result.error || "Failed to parse product list",
            meta: result.meta || {}
          });
        }
      })
      .catch(error => {
        // Niemals unhandled throws - immer graceful response
        console.error("Error parsing product list:", error);
        const pageType = detectPageType();
        sendResponse({ 
          ok: false, 
          error: error.message || "Failed to parse product list",
          meta: {
            pageType,
            finalUrl: window.location.href,
            attempts: 1,
            reason: "unhandled_error"
          }
        });
      });
    return true; // async response
  }
});

/**
 * Extrahiert Marktplatz aus hostname
 * @returns {string} Market Code (z.B. "DE", "US", "UK")
 */
function extractMarketFromHostname() {
  try {
    const hostname = window.location.hostname.toLowerCase();
    
    // eBay Domain-Patterns
    if (hostname.includes('.de') || hostname.includes('ebay.de')) {
      return 'DE';
    }
    if (hostname.includes('.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();
    }
    
    return 'US'; // Default
  } catch (e) {
    return 'US';
  }
}

/**
 * Extrahiert Seller ID aus URL oder DOM
 * @returns {string} Seller ID
 */
function extractSellerId() {
  try {
    // Methode 1: URL-Patterns
    const url = window.location.href;
    const urlLower = url.toLowerCase();
    
    // Pattern: /usr/username oder /str/storename
    const usrMatch = url.match(/\/usr\/([^\/\?]+)/i);
    if (usrMatch && usrMatch[1]) {
      return usrMatch[1].trim();
    }
    
    const strMatch = url.match(/\/str\/([^\/\?]+)/i);
    if (strMatch && strMatch[1]) {
      return strMatch[1].trim();
    }
    
    // Pattern: _ssn=username (Seller Name Parameter in Suchergebnis-URLs)
    const ssnMatch = url.match(/[?&]_ssn=([^&]+)/i);
    if (ssnMatch && ssnMatch[1]) {
      return decodeURIComponent(ssnMatch[1]).trim();
    }
    
    // Methode 2: DOM-Elemente suchen
    // Suche nach verschiedenen Selektoren, die Seller-ID enthalten könnten
    const possibleSelectors = [
      '[data-testid*="seller"]',
      '.seller-username',
      '.member-info-username',
      '[class*="seller-id"]',
      '[class*="username"]',
      '[id*="seller"]'
    ];
    
    for (const selector of possibleSelectors) {
      try {
        const element = document.querySelector(selector);
        if (element) {
          const text = element.textContent?.trim();
          if (text && text.length > 0 && text.length < 100) {
            return text;
          }
        }
      } catch (e) {
        // Continue to next selector
      }
    }
    
    // Methode 3: Meta-Tags
    try {
      const metaSeller = document.querySelector('meta[property*="seller"], meta[name*="seller"]');
      if (metaSeller && metaSeller.content) {
        return metaSeller.content.trim();
      }
    } catch (e) {
      // Continue
    }
    
    return ""; // Nicht gefunden
  } catch (e) {
    return "";
  }
}

/**
 * Extrahiert Shop Name aus DOM
 * @returns {string} Shop Name
 */
function extractShopName() {
  try {
    // Methode 1: Shop-Name aus Storefront-Link extrahieren
    // Pattern: <a href="/str/storename" data-track="...">Shop Name</a>
    try {
      const storefrontLinks = document.querySelectorAll('a[href*="/str/"]');
      for (const link of storefrontLinks) {
        // Prüfe ob Link data-track Attribut hat (typisch für Storefront-Links)
        if (link.hasAttribute('data-track') || link.href.includes('/str/')) {
          const linkText = link.textContent?.trim();
          if (linkText && linkText.length > 0 && linkText.length < 200) {
            // Prüfe dass es nicht nur ein URL-Pfad ist
            if (!linkText.match(/^https?:\/\//) && !linkText.match(/^\/str\//)) {
              return linkText;
            }
          }
        }
      }
    } catch (e) {
      // Continue to next method
    }
    
    // Methode 2: Spezifische Selektoren versuchen
    const shopNameSelectors = [
      'h1.shop-name',
      '.store-name',
      '[data-testid="store-name"]',
      '.store-title',
      '[class*="shop-name"]',
      '[class*="store-title"]',
      'h1[class*="store"]',
      'h1[class*="shop"]'
    ];
    
    for (const selector of shopNameSelectors) {
      try {
        const element = document.querySelector(selector);
        if (element) {
          const text = element.textContent?.trim();
          if (text && text.length > 0) {
            return text;
          }
        }
      } catch (e) {
        // Continue to next selector
      }
    }
    
    // Methode 3: document.title parsen
    try {
      const title = document.title || "";
      // Versuche Muster wie "Shop Name | eBay" zu extrahieren
      const titleMatch = title.match(/^(.+?)\s*[\|\-]\s*eBay/i);
      if (titleMatch && titleMatch[1]) {
        return titleMatch[1].trim();
      }
      // Wenn Titel einfach genug ist, verwende ihn direkt
      if (title && title.length < 100 && !title.toLowerCase().includes('ebay')) {
        return title.trim();
      }
    } catch (e) {
      // Continue
    }
    
    // Methode 4: h1 Tag als Fallback
    try {
      const h1 = document.querySelector('h1');
      if (h1) {
        const text = h1.textContent?.trim();
        if (text && text.length > 0 && text.length < 200) {
          return text;
        }
      }
    } catch (e) {
      // Continue
    }
    
    return ""; // Nicht gefunden
  } catch (e) {
    return "";
  }
}

/**
 * Extrahiert "Artikel verkauft" aus Storefront-Profilen
 * @returns {number|null} Anzahl verkaufter Artikel oder null
 */
function extractItemsSold() {
  try {
    // Suche nach Container
    const container = document.querySelector(".str-seller-card__store-stats-content");
    if (!container) {
      return null;
    }

    // Finde div children, die "Artikel verkauft" enthalten
    const divs = container.querySelectorAll("div");
    for (const div of divs) {
      const divText = div.textContent || "";
      if (divText.includes("Artikel verkauft")) {
        // Suche nach span mit Klasse str-text-span BOLD (Klasse kann als "str-text-span BOLD" sein)
        const span1 = div.querySelector("span.str-text-span.BOLD");
        const span2 = div.querySelector("span.BOLD");
        const span3 = div.querySelector('span[class*="BOLD"]');
        const span = span1 || span2 || span3;
        if (span) {
          let valueText = span.textContent?.trim() || "";
          
          // Normalisierung: Entferne Leerzeichen
          valueText = valueText.replace(/\s/g, "");
          
          // Ersetze Tausendertrenner (. und ,) durch leeren String
          valueText = valueText.replace(/[.,]/g, "");
          
          // Nur Digits behalten
          valueText = valueText.replace(/\D/g, "");
          
          // Parse zu Integer
          if (valueText.length > 0) {
            const parsedValue = parseInt(valueText, 10);
            if (!isNaN(parsedValue) && parsedValue >= 0) {
              return parsedValue;
            }
          }
        }
        
        // Fallback: Regex auf div-Text, falls Struktur abweicht
        const regexMatch = divText.match(/([\d.,]+)\s*Artikel\s*verkauft/i);
        if (regexMatch && regexMatch[1]) {
          let valueText = regexMatch[1].trim();
          valueText = valueText.replace(/\s/g, "").replace(/[.,]/g, "").replace(/\D/g, "");
          if (valueText.length > 0) {
            const parsedValue = parseInt(valueText, 10);
            if (!isNaN(parsedValue) && parsedValue >= 0) {
              return parsedValue;
            }
          }
        }
      }
    }
    
    return null;
  } catch (e) {
    // Graceful fallback bei Fehlern
    return null;
  }
}

/**
 * Extrahiert Stats aus DOM (Feedback Score, Positive Rate, etc.)
 * @returns {object} Stats Objekt
 */
function extractStats() {
  const stats = {};
  
  try {
    const pageText = document.body?.textContent || "";
    
    // Feedback Score
    try {
      const feedbackScorePatterns = [
        /feedback\s*score[:\s]+(\d+)/i,
        /(?:score|bewertung)[:\s]+(\d+)/i,
        /(\d+)\s*feedback/i
      ];
      
      for (const pattern of feedbackScorePatterns) {
        const match = pageText.match(pattern);
        if (match && match[1]) {
          const score = parseInt(match[1], 10);
          if (!isNaN(score) && score >= 0) {
            stats.feedbackScore = score;
            break;
          }
        }
      }
    } catch (e) {
      // Continue
    }
    
    // Positive Rate (%)
    try {
      const positiveRatePatterns = [
        /positive[:\s]+(\d+\.?\d*)\s*%/i,
        /(\d+\.?\d*)\s*%\s*positive/i,
        /(?:rate|quote)[:\s]+(\d+\.?\d*)\s*%/i
      ];
      
      for (const pattern of positiveRatePatterns) {
        const match = pageText.match(pattern);
        if (match && match[1]) {
          const rate = parseFloat(match[1]);
          if (!isNaN(rate) && rate >= 0 && rate <= 100) {
            stats.positiveRate = rate;
            break;
          }
        }
      }
    } catch (e) {
      // Continue
    }
    
    // Feedback Count
    try {
      const feedbackCountPatterns = [
        /(\d+)\s*(?:bewertungen|ratings|feedbacks?)/i,
        /(?:count|anzahl)[:\s]+(\d+)/i
      ];
      
      for (const pattern of feedbackCountPatterns) {
        const match = pageText.match(pattern);
        if (match && match[1]) {
          const count = parseInt(match[1], 10);
          if (!isNaN(count) && count >= 0) {
            stats.feedbackCount = count;
            break;
          }
        }
      }
    } catch (e) {
      // Continue
    }
    
    // Items for Sale
    try {
      const itemsPatterns = [
        /items?\s*(?:for\s*)?sale[:\s]+(\d+)/i,
        /(\d+)\s*artikel/i,
        /(\d+)\s*(?:items?|artikel)\s*(?:for\s*)?sale/i
      ];
      
      for (const pattern of itemsPatterns) {
        const match = pageText.match(pattern);
        if (match && match[1]) {
          const items = parseInt(match[1], 10);
          if (!isNaN(items) && items >= 0) {
            stats.itemsForSale = items;
            break;
          }
        }
      }
    } catch (e) {
      // Continue
    }
    
    // Member Since
    try {
      const memberSincePatterns = [
        /member\s*since[:\s]+(\d{1,2}[\/\-\.]\d{1,2}[\/\-\.]\d{2,4})/i,
        /mitglied\s*seit[:\s]+(\d{1,2}[\/\-\.]\d{1,2}[\/\-\.]\d{2,4})/i,
        /(?:since|seit)[:\s]+(\d{4})/i
      ];
      
      for (const pattern of memberSincePatterns) {
        const match = pageText.match(pattern);
        if (match && match[1]) {
          stats.memberSince = match[1].trim();
          break;
        }
      }
    } catch (e) {
      // Continue
    }
    
    // Items Sold (Artikel verkauft)
    try {
      const itemsSold = extractItemsSold();
      if (itemsSold !== null) {
        stats.itemsSold = itemsSold;
      }
    } catch (e) {
      // Continue
    }
    
  } catch (e) {
    // Return empty stats object
  }
  
  return stats;
}

/**
 * Haupt-Parsing-Funktion
 * @returns {object} Parsed eBay Account Data
 */
function parseEbayPage() {
  try {
    const sellerId = extractSellerId();
    const shopName = extractShopName();
    const market = extractMarketFromHostname();
    const stats = extractStats();
    
    // Status bestimmen: "active" wenn wir mindestens Shop Name oder Seller ID haben
    const status = (sellerId || shopName) ? "active" : "unknown";
    
    return {
      sellerId: sellerId || "",
      shopName: shopName || "",
      market: market,
      status: status,
      stats: stats
    };
  } catch (error) {
    // Graceful fallback
    return {
      sellerId: "",
      shopName: "",
      market: extractMarketFromHostname(),
      status: "unknown",
      stats: {}
    };
  }
}

/**
 * Erkennt den Seitentyp basierend auf URL und DOM
 * @returns {string} Page Type: "storefront" | "seller_profile" | "feedback" | "search_results" | "unknown"
 */
function detectPageType() {
  try {
    const pathname = window.location.pathname.toLowerCase();
    const search = window.location.search.toLowerCase();
    
    // Storefront
    if (pathname.includes("/str/")) {
      return "storefront";
    }
    
    // Seller Profile
    if (pathname.includes("/usr/")) {
      return "seller_profile";
    }
    
    // Feedback
    if (search.includes("_tab=feedback") || pathname.includes("feedback")) {
      return "feedback";
    }
    
    // Search Results
    if (document.querySelector("ul.srp-results")) {
      return "search_results";
    }
    
    return "unknown";
  } catch (e) {
    return "unknown";
  }
}

/**
 * Wartet auf Item-Links, bis minLinks gefunden wurden oder Timeout
 * @param {number} maxMs - Maximale Wartezeit in ms (default: 4000)
 * @param {number} intervalMs - Intervall zwischen Checks in ms (default: 250)
 * @param {number} minLinks - Minimale Anzahl Links (default: 5)
 * @returns {Promise<Array>} Array von Link-Elementen (kann 0 sein)
 */
async function waitForItemLinks(maxMs = 4000, intervalMs = 250, minLinks = 5) {
  const startTime = Date.now();
  
  while (Date.now() - startTime < maxMs) {
    const links = findItemLinks();
    if (links.length >= minLinks) {
      return links;
    }
    
    // Warte auf nächsten Check
    await new Promise(resolve => setTimeout(resolve, intervalMs));
  }
  
  // Timeout: gib gefundene Links zurück (kann 0 sein)
  return findItemLinks();
}

/**
 * Findet Navigations-Link zu Items-Seite (Angebote/Artikel)
 * @returns {string|null} Absolute URL oder null
 */
function findItemsNavigationLink() {
  try {
    const allLinks = Array.from(document.querySelectorAll("a"));
    const candidates = [];
    
    for (const link of allLinks) {
      const href = link.href || link.getAttribute("href");
      const text = (link.textContent || "").toLowerCase().trim();
      
      if (!href) continue;
      
      const hrefLower = href.toLowerCase();
      
      // Prüfe Anchor-Text
      const textMatches = 
        text.includes("artikel") ||
        text.includes("angebote") ||
        text.includes("items") ||
        text.includes("items for sale") ||
        text.includes("shop") ||
        text.includes("shop anzeigen");
      
      // Prüfe href-Patterns
      const hrefMatches = 
        hrefLower.includes("/sch/") ||
        hrefLower.includes("/s/i.html") ||
        hrefLower.includes("/str/") ||
        hrefLower.includes("?_tab=selling");
      
      if (textMatches || hrefMatches) {
        // Berechne Priorität
        let priority = 0;
        if (hrefLower.includes("/sch/")) priority = 1;
        else if (hrefLower.includes("/str/")) priority = 2;
        else if (hrefLower.includes("/s/i.html")) priority = 3;
        else if (text.includes("items")) priority = 4;
        else priority = 5;
        
        candidates.push({ link, href, priority });
      }
    }
    
    if (candidates.length === 0) {
      return null;
    }
    
    // Sortiere nach Priorität (niedrigste Zahl = höchste Priorität)
    candidates.sort((a, b) => a.priority - b.priority);
    
    const bestCandidate = candidates[0].href;
    const currentUrl = window.location.href;
    
    // Prüfe ob URL sich unterscheidet
    if (bestCandidate === currentUrl) {
      return null; // Gleiche URL, keine Navigation nötig
    }
    
    // Erstelle absolute URL falls nötig
    try {
      const url = new URL(bestCandidate, window.location.origin);
      return url.href;
    } catch (e) {
      return null;
    }
  } catch (e) {
    return null;
  }
}

/**
 * Parst Produktliste von eBay Storefront oder Seller Listings
 * @returns {Promise<{ok: boolean, items?: Array, error?: string, meta: object}>}
 */
async function parseProductList() {
  let attempts = 1;
  let pageType = detectPageType();
  let finalUrl = window.location.href;
  let reason = null;
  try {
    // Schritt 1: Warte auf Item-Links (Polling)
    let links = await waitForItemLinks(4000, 250, 5);
    
    // Schritt 2: Wenn keine Links gefunden, versuche Auto-Navigation (max. 1 Retry)
    if (links.length === 0 && attempts === 1) {
      const itemsLink = findItemsNavigationLink();
      
      if (itemsLink && itemsLink !== window.location.href) {
        // Navigiere zur Items-Seite
        window.location.href = itemsLink;
        
        // Warte auf DOM-Ready nach Navigation
        await new Promise(resolve => setTimeout(resolve, 1200));
        
        // Warte erneut auf Item-Links (längeres Timeout nach Navigation)
        links = await waitForItemLinks(5000, 250, 5);
        
        attempts = 2;
        pageType = detectPageType();
        finalUrl = window.location.href;
        reason = "navigated_to_items_page";
        
        // Wenn immer noch keine Links, gib Fehler zurück
        if (links.length === 0) {
          return {
            ok: false,
            error: "no_items_found",
            meta: {
              pageType,
              finalUrl,
              attempts,
              reason: "no_items_found_after_navigation"
            }
          };
        }
      } else {
        // Kein Navigations-Link gefunden
        return {
          ok: false,
          error: "no_items_found",
          meta: {
            pageType,
            finalUrl,
            attempts,
            reason: links.length === 0 ? "no_items_links_on_page" : "timed_out_waiting_for_items"
          }
        };
      }
    }
    
    // Schritt 3: Parse Items
    if (links.length === 0) {
      return {
        ok: false,
        error: "no_items_found",
        meta: {
          pageType,
          finalUrl,
          attempts,
          reason: reason || "no_items_links_on_page"
        }
      };
    }
    
    // Parse each item
    const parsedItems = [];
    const seenIds = new Set();
    
    for (const itemLink of links) {
      try {
        const item = parseItemFromLink(itemLink);
        
        // Deduplicate by platformProductId
        if (item.platformProductId && !seenIds.has(item.platformProductId)) {
          seenIds.add(item.platformProductId);
          parsedItems.push(item);
        }
      } catch (e) {
        // Continue with next item if one fails
        console.warn("Failed to parse item:", e);
      }
    }
    
    return {
      ok: true,
      items: parsedItems,
      meta: {
        pageType,
        finalUrl,
        attempts,
        reason: reason || (parsedItems.length > 0 ? "items_found" : "parsed_zero_items")
      }
    };
    
  } catch (error) {
    // Graceful error handling
    return {
      ok: false,
      error: error.message || "Failed to parse product list",
      meta: {
        pageType,
        finalUrl,
        attempts,
        reason: "parse_error"
      }
    };
  }
}

/**
 * Parst Produktdetail-Seite (/itm/...) für title, price, currency, category, condition,
 * quantityAvailable, quantitySold, watchCount, inCartsCount.
 */
function parseItemDetailPage() {
  const out = {
    title: "",
    price: null,
    currency: null,
    category: null,
    condition: null,
    quantityAvailable: null,
    quantitySold: null,
    watchCount: null,
    inCartsCount: null
  };
  try {
    const titleEl = document.querySelector("[data-testid=\"x-item-title\"] h1 .ux-textspans") ||
      document.querySelector("h1.x-item-title__mainTitle .ux-textspans");
    if (titleEl) {
      out.title = (titleEl.textContent || "").trim().replace(/\s+/g, " ");
    }

    const priceEl = document.querySelector("[data-testid=\"x-price-primary\"] .ux-textspans");
    if (priceEl) {
      const priceText = (priceEl.textContent || "").trim();
      const parsed = parsePrice(priceText);
      out.price = parsed.price;
      out.currency = parsed.currency;
    }

    const breadcrumbs = document.querySelectorAll("a.seo-breadcrumb-text span");
    if (breadcrumbs.length > 0) {
      const parts = [];
      breadcrumbs.forEach((span) => {
        const t = (span.textContent || "").trim();
        if (t) parts.push(t);
      });
      out.category = parts.join(" > ");
    }

    const condEl = document.querySelector("dd.ux-labels-values__values .ux-textspans");
    if (condEl) {
      const raw = (condEl.textContent || "").trim();
      const colonIdx = raw.indexOf(":");
      out.condition = colonIdx >= 0 ? raw.slice(0, colonIdx).trim() : raw.slice(0, 80);
    }

    // x-quantity__availability: "9 verfügbar", "8 verkauft"
    const availEl = document.querySelector(".x-quantity__availability");
    if (availEl) {
      const text = (availEl.textContent || "").trim();
      const verfMatch = text.match(/(\d+)\s*verfügbar/i);
      if (verfMatch && verfMatch[1]) {
        const n = parseInt(verfMatch[1], 10);
        if (!isNaN(n) && n >= 0) out.quantityAvailable = n;
      }
      const verkMatch = text.match(/(\d+)\s*verkauft/i);
      if (verkMatch && verkMatch[1]) {
        const n = parseInt(verkMatch[1], 10);
        if (!isNaN(n) && n >= 0) out.quantitySold = n;
      }
    }

    // x-watch-heart-btn: .x-watch-heart-btn-text "14" oder aria-label "14 Beobachter"
    const watchBtn = document.querySelector("button.x-watch-heart-btn");
    if (watchBtn) {
      const textEl = watchBtn.querySelector(".x-watch-heart-btn-text");
      if (textEl) {
        const n = parseInt((textEl.textContent || "").trim().replace(/\D/g, ""), 10);
        if (!isNaN(n) && n >= 0) out.watchCount = n;
      }
      if (out.watchCount == null) {
        const label = (watchBtn.getAttribute("aria-label") || "").trim();
        const m = label.match(/(\d+)\s*Beobachter/i);
        if (m && m[1]) {
          const n = parseInt(m[1], 10);
          if (!isNaN(n) && n >= 0) out.watchCount = n;
        }
      }
    }

    // [data-testid="x-ebay-signal"]: "In 8 Warenkörben"
    const signalEl = document.querySelector("[data-testid=\"x-ebay-signal\"]");
    if (signalEl) {
      const text = (signalEl.textContent || "").trim();
      const m = text.match(/in\s*(\d+)\s*warenkörben/i);
      if (m && m[1]) {
        const n = parseInt(m[1], 10);
        if (!isNaN(n) && n >= 0) out.inCartsCount = n;
      }
    }
  } catch (e) {
    console.warn("[EBAY-CONTENT] parseItemDetailPage error:", e);
  }
  return out;
}

/**
 * Findet Item-Links auf der Seite
 * @returns {Array} Array von Link-Elementen
 */
function findItemLinks() {
  const links = [];
  
  try {
    // Multiple selector fallbacks for item cards
    const selectors = [
      'a[href*="/itm/"]',           // Direct item links
      '.s-item a[href*="/itm/"]',   // Search result items
      '.srp-results .s-item a',     // Search results
      '.ebay-item-card a[href*="/itm/"]', // Item cards
      '[class*="item-card"] a[href*="/itm/"]', // Generic item cards
    ];
    
    for (const selector of selectors) {
      try {
        const found = document.querySelectorAll(selector);
        if (found.length > 0) {
          // Filter out duplicates by href
          const hrefs = new Set();
          for (const link of found) {
            const href = link.href || link.getAttribute('href');
            if (href && href.includes('/itm/') && !hrefs.has(href)) {
              hrefs.add(href);
              links.push(link);
            }
          }
          if (links.length > 0) break; // Found items, stop trying other selectors
        }
      } catch (e) {
        // Continue to next selector
      }
    }
  } catch (e) {
    // Return empty array on error
  }
  
  return links;
}

/**
 * Parst ein einzelnes Item aus einem Link-Element
 * @param {Element} itemLink - Link-Element zu einem eBay-Item
 * @returns {object} Parsed Item-Data
 */
function parseItemFromLink(itemLink) {
  const item = {
    platformProductId: null,
    title: "",
    price: null,
    currency: null,
    url: "",
    status: "active",
    category: null,
    condition: null
  };
  
  try {
    // URL (absolute)
    const href = itemLink.href || itemLink.getAttribute('href');
    if (href) {
      item.url = href.startsWith('http') ? href : new URL(href, window.location.origin).href;
      
      // Extract platformProductId from URL: /itm/<id> or ?item=<id>
      const itmMatch = item.url.match(/\/itm\/(\d+)/);
      if (itmMatch && itmMatch[1]) {
        item.platformProductId = itmMatch[1];
      } else {
        const itemParamMatch = item.url.match(/[?&]item=(\d+)/);
        if (itemParamMatch && itemParamMatch[1]) {
          item.platformProductId = itemParamMatch[1];
        }
      }
    }
    
    // Fallback: data attributes if present
    if (!item.platformProductId) {
      const dataItemId = itemLink.getAttribute('data-item-id') || 
                        itemLink.closest('[data-item-id]')?.getAttribute('data-item-id');
      if (dataItemId) {
        item.platformProductId = dataItemId;
      }
    }
    
    // Title: from link text or title element
    try {
      const titleElement = itemLink.querySelector('.s-item__title') ||
                          itemLink.querySelector('[class*="title"]') ||
                          itemLink.closest('.s-item')?.querySelector('.s-item__title');
      
      if (titleElement) {
        item.title = titleElement.textContent?.trim() || "";
      } else {
        // Fallback: link text itself
        item.title = itemLink.textContent?.trim() || "";
      }
      
      // Normalize title (remove extra whitespace)
      item.title = item.title.replace(/\s+/g, ' ').trim();
    } catch (e) {
      // Continue without title
    }
    
    // Price + Currency
    try {
      const itemCard = itemLink.closest('.s-item') || itemLink.closest('[class*="item-card"]');
      if (itemCard) {
        const priceElement = itemCard.querySelector('.s-item__price') ||
                            itemCard.querySelector('[class*="price"]') ||
                            itemCard.querySelector('.BOLD');
        
        if (priceElement) {
          const priceText = priceElement.textContent?.trim() || "";
          const parsed = parsePrice(priceText);
          item.price = parsed.price;
          item.currency = parsed.currency;
        }
      }
    } catch (e) {
      // Continue without price
    }
    
    // Category (optional)
    try {
      const categoryElement = itemLink.closest('.s-item')?.querySelector('[class*="category"]');
      if (categoryElement) {
        item.category = categoryElement.textContent?.trim() || null;
      }
    } catch (e) {
      // Continue without category
    }
    
    // Condition (optional)
    try {
      const conditionElement = itemLink.closest('.s-item')?.querySelector('[class*="condition"]');
      if (conditionElement) {
        item.condition = conditionElement.textContent?.trim() || null;
      }
    } catch (e) {
      // Continue without condition
    }
    
    // Status: default "active" (storefront shows active listings)
    // Could check for "ended" indicators, but MVP keeps it simple
    item.status = "active";
    
  } catch (e) {
    // Continue with partial data
    console.warn("Error parsing item:", e);
  }
  
  return item;
}

/**
 * Parst Preis-String in Zahl und Währung
 * @param {string} priceText - Preis-String z.B. "EUR 12,99" oder "$15.50"
 * @returns {object} { price: number|null, currency: string|null }
 */
function parsePrice(priceText) {
  const result = { price: null, currency: null };
  
  try {
    if (!priceText) return result;
    
    // Extract currency symbols/codes
    const currencyMatch = priceText.match(/(EUR|USD|GBP|€|\$|£)/i);
    if (currencyMatch) {
      const currencyCode = currencyMatch[1].toUpperCase();
      if (currencyCode === '€') result.currency = 'EUR';
      else if (currencyCode === '$') result.currency = 'USD';
      else if (currencyCode === '£') result.currency = 'GBP';
      else result.currency = currencyCode;
    }
    
    // Extract numeric value (handle both comma and dot as decimal separator)
    const normalized = priceText
      .replace(/[^\d,.-]/g, '') // Remove non-numeric except , . -
      .replace(/\./g, '') // Remove thousand separators (assume dot)
      .replace(',', '.'); // Replace comma with dot for decimal
    
    const price = parseFloat(normalized);
    if (!isNaN(price) && price >= 0) {
      result.price = price;
    }
  } catch (e) {
    // Return null values on error
  }
  
  return result;
}