← back to Handbag Authentication

public/js/product.js

799 lines

// Product Detail Page Intelligence

const brandMultipliers = {
  'Hermes': 2.5, 'Hermès': 2.5, 'エルメス': 2.5,
  'Chanel': 2.2, 'シャネル': 2.2,
  'Louis Vuitton': 1.9, 'ルイヴィトン': 1.9,
  'Gucci': 1.7, 'グッチ': 1.7,
  'Dior': 1.8, 'ディオール': 1.8,
  'Prada': 1.6, 'プラダ': 1.6,
  'Fendi': 1.7, 'フェンディ': 1.7,
  'Balenciaga': 1.6, 'バレンシアガ': 1.6,
  'Celine': 1.8, 'セリーヌ': 1.8,
  'Bottega Veneta': 1.7, 'ボッテガヴェネタ': 1.7
};

// Brand Official Websites
const brandRetailers = {
  'Hermes': {
    name: 'Hermès Official',
    url: 'https://www.hermes.com/us/en/category/women/bags-and-small-leather-goods/',
    searchUrl: (model) => `https://www.hermes.com/us/en/search/?q=${encodeURIComponent(model)}`,
    logo: 'https://logo.clearbit.com/hermes.com'
  },
  'Chanel': {
    name: 'Chanel Official',
    url: 'https://www.chanel.com/us/fashion/handbags/c/1x1x1/',
    searchUrl: (model) => `https://www.chanel.com/us/search#q=${encodeURIComponent(model)}`,
    logo: 'https://logo.clearbit.com/chanel.com'
  },
  'Louis Vuitton': {
    name: 'Louis Vuitton Official',
    url: 'https://us.louisvuitton.com/eng-us/women/handbags/_/N-tfrs5hy',
    searchUrl: (model) => `https://us.louisvuitton.com/eng-us/search/${encodeURIComponent(model)}`,
    logo: 'https://logo.clearbit.com/louisvuitton.com'
  },
  'Gucci': {
    name: 'Gucci Official',
    url: 'https://www.gucci.com/us/en/ca/women/handbags-for-women-c-women-handbags',
    searchUrl: (model) => `https://www.gucci.com/us/en/st/search?query=${encodeURIComponent(model)}`,
    logo: 'https://logo.clearbit.com/gucci.com'
  },
  'Prada': {
    name: 'Prada Official',
    url: 'https://www.prada.com/us/en/women/bags.html',
    searchUrl: (model) => `https://www.prada.com/us/en/search.html?q=${encodeURIComponent(model)}`,
    logo: 'https://logo.clearbit.com/prada.com'
  },
  'Dior': {
    name: 'Dior Official',
    url: 'https://www.dior.com/en_us/fashion/womens-fashion/bags',
    searchUrl: (model) => `https://www.dior.com/en_us/search?q=${encodeURIComponent(model)}`,
    logo: 'https://logo.clearbit.com/dior.com'
  },
  'Fendi': {
    name: 'Fendi Official',
    url: 'https://www.fendi.com/us-en/woman/bags',
    searchUrl: (model) => `https://www.fendi.com/us-en/search?q=${encodeURIComponent(model)}`,
    logo: 'https://logo.clearbit.com/fendi.com'
  }
};

// Price History Data Sources
const priceHistorySources = {
  stockx: {
    name: 'StockX',
    apiUrl: (sku) => `https://stockx.com/api/products/${sku}/activity`,
    note: 'Limited luxury bag data'
  },
  rebag: {
    name: 'Rebag Clair AI',
    url: 'https://clair.rebag.com/',
    note: 'Best for Hermès, Chanel, LV'
  },
  fashionphile: {
    name: 'Fashionphile',
    searchUrl: (brand, model) => `https://www.fashionphile.com/search?query=${encodeURIComponent(brand + ' ' + model)}&sold=true`,
    note: 'Extensive sold archive'
  },
  '1stdibs': {
    name: '1stDibs',
    searchUrl: (brand, model) => `https://www.1stdibs.com/search/?q=${encodeURIComponent(brand + ' ' + model)}`,
    note: 'High-end vintage data'
  }
};

// Initialize page
document.addEventListener('DOMContentLoaded', () => {
  initializeTabs();
  calculateArbitrage();
  extractSKUDetails();
  loadRetailerLinks();
  loadPriceHistory();
  loadSoldComps();
  loadPlatformComparison();
});

// Tab Navigation
function initializeTabs() {
  const tabs = document.querySelectorAll('.tab');
  const tabContents = document.querySelectorAll('.tab-content');

  tabs.forEach(tab => {
    tab.addEventListener('click', () => {
      const target = tab.dataset.tab;

      tabs.forEach(t => t.classList.remove('active'));
      tabContents.forEach(tc => tc.classList.remove('active'));

      tab.classList.add('active');
      document.getElementById(target).classList.add('active');
    });
  });
}

// Calculate Complete Arbitrage Breakdown
function calculateArbitrage() {
  const brand = identifyBrand(productData.brand || productData.title);
  const multiplier = brandMultipliers[brand] || 1.5;

  const japanPrice = productData.price_usd;
  const estimatedUSPrice = Math.round(japanPrice * multiplier);

  // Cost breakdown
  const costs = {
    'Purchase Price (Japan)': japanPrice,
    'International Shipping (Buyee/FromJapan)': 50,
    'Authentication Service': 50,
    'Import Duties & Taxes (Est.)': Math.round(japanPrice * 0.05),
    'Payment Processing (3%)': Math.round(japanPrice * 0.03)
  };

  const totalCosts = Object.values(costs).reduce((a, b) => a + b, 0);

  // Display quick stats
  document.getElementById('est-us-price').textContent = `$${estimatedUSPrice.toLocaleString()}`;

  const grossProfit = estimatedUSPrice - totalCosts;
  const profitMargin = ((grossProfit / totalCosts) * 100).toFixed(1);

  document.getElementById('profit-amount').textContent = `$${grossProfit.toLocaleString()}`;
  document.getElementById('profit-margin').textContent = `${profitMargin}% margin`;

  // Build cost breakdown table
  const tbody = document.getElementById('cost-breakdown-body');
  tbody.innerHTML = '';

  Object.entries(costs).forEach(([item, amount]) => {
    tbody.innerHTML += `
      <tr>
        <td>${item}</td>
        <td>$${amount.toLocaleString()}</td>
        <td>${getItemNote(item)}</td>
      </tr>
    `;
  });

  tbody.innerHTML += `
    <tr class="total-row">
      <td>Total Investment</td>
      <td>$${totalCosts.toLocaleString()}</td>
      <td>All costs included</td>
    </tr>
    <tr class="total-row" style="background: #d4edda; color: #155724;">
      <td>Estimated Sale Price</td>
      <td>$${estimatedUSPrice.toLocaleString()}</td>
      <td>${multiplier}x multiplier for ${brand}</td>
    </tr>
    <tr class="total-row" style="background: #c3e6cb; color: #155724; font-size: 1.2rem;">
      <td><strong>💰 Net Profit</strong></td>
      <td><strong>$${grossProfit.toLocaleString()}</strong></td>
      <td><strong>${profitMargin}% ROI</strong></td>
    </tr>
  `;

  // Platform scenarios
  buildPlatformScenarios(totalCosts, estimatedUSPrice);

  // Negotiation strategy
  buildNegotiationStrategy();
}

function getItemNote(item) {
  const notes = {
    'Purchase Price (Japan)': 'Current auction/listing price',
    'International Shipping (Buyee/FromJapan)': 'Typical EMS/DHL to USA',
    'Authentication Service': 'Entrupy, Real Authentication, or similar',
    'Import Duties & Taxes (Est.)': '~5% for handbags under $2500',
    'Payment Processing (3%)': 'PayPal, Credit Card fees'
  };
  return notes[item] || '';
}

function buildPlatformScenarios(totalCosts, basePrice) {
  const brand = identifyBrand(productData.brand || productData.title);
  const model = extractModel(productData.title);

  const platforms = [
    {
      name: 'Fashionphile',
      commission: 0.30,
      speed: 'Fast (24-48h)',
      salePrice: basePrice * 0.95,
      searchUrl: `https://www.fashionphile.com/search?query=${encodeURIComponent(brand + ' ' + model)}&sold=true`
    },
    {
      name: 'Rebag',
      commission: 0.25,
      speed: 'Instant Quote',
      salePrice: basePrice * 0.70,
      searchUrl: `https://clair.rebag.com/`
    },
    {
      name: 'TheRealReal',
      commission: 0.35,
      speed: 'Medium (1-2 wks)',
      salePrice: basePrice * 0.90,
      searchUrl: `https://www.therealreal.com/search?q=${encodeURIComponent(brand + ' ' + model)}`
    },
    {
      name: 'Vestiaire Collective',
      commission: 0.18,
      speed: 'Slow (2-4 wks)',
      salePrice: basePrice * 1.00,
      searchUrl: `https://www.vestiairecollective.com/search/?q=${encodeURIComponent(brand + ' ' + model)}`
    },
    {
      name: 'eBay Authenticated',
      commission: 0.125,
      speed: 'Fast (3-7 days)',
      salePrice: basePrice * 0.85,
      searchUrl: `https://www.ebay.com/sch/i.html?_nkw=${encodeURIComponent(brand + ' ' + model)}&LH_Sold=1&LH_Complete=1`
    },
    {
      name: 'Poshmark',
      commission: 0.20,
      speed: 'Variable',
      salePrice: basePrice * 0.80,
      searchUrl: `https://poshmark.com/search?query=${encodeURIComponent(brand + ' ' + model)}&department=Women&availability=sold_out`
    }
  ];

  const container = document.getElementById('platform-scenarios');
  container.innerHTML = '<table class="breakdown-table"><thead><tr><th>Platform</th><th>Est. Sale Price</th><th>Commission</th><th>Your Profit</th><th>ROI</th><th>Speed</th><th>Sold Comps</th></tr></thead><tbody>';

  platforms.forEach(p => {
    const afterCommission = p.salePrice * (1 - p.commission);
    const profit = afterCommission - totalCosts;
    const roi = ((profit / totalCosts) * 100).toFixed(1);
    const profitClass = profit > 0 ? 'profit-positive' : 'profit-negative';

    // Show loading state initially, will be replaced with real data
    const compsHtml = `<div class="comps-loading" data-platform="${p.name}">Loading real sold data...</div>`;

    container.innerHTML += `
      <tr>
        <td><strong>${p.name}</strong></td>
        <td>$${Math.round(p.salePrice).toLocaleString()}</td>
        <td>${(p.commission * 100)}%</td>
        <td class="${profitClass}"><strong>$${Math.round(profit).toLocaleString()}</strong></td>
        <td class="${profitClass}"><strong>${roi}%</strong></td>
        <td>${p.speed}</td>
        <td class="comps-cell">
          ${compsHtml}
          <a href="${p.searchUrl}" target="_blank" rel="noopener noreferrer" class="btn-view-comps">View All Sold →</a>
        </td>
      </tr>
    `;
  });

  container.innerHTML += '</tbody></table>';

  // Fetch REAL sold data from API
  fetchRealSoldData(brand, model);
}

// Fetch real sold comps from eBay USA, eBay Japan, Fashionphile, Poshmark
async function fetchRealSoldData(brand, model) {
  try {
    console.log(`Fetching real sold data for: ${brand} ${model}`);

    const response = await fetch(`/api/sold-comps/${encodeURIComponent(brand)}/${encodeURIComponent(model)}`);
    const data = await response.json();

    if (!data.success || !data.soldItems) {
      console.error('No sold data available');
      return;
    }

    console.log(`✓ Received ${data.soldItems.length} sold comps`);

    // Group by source
    const bySource = {
      'eBay USA': data.soldItems.filter(i => i.source === 'ebay_usa').slice(0, 3),
      'eBay Japan': data.soldItems.filter(i => i.source === 'ebay_japan').slice(0, 3),
      'Fashionphile': data.soldItems.filter(i => i.source === 'fashionphile').slice(0, 3),
      'Poshmark': data.soldItems.filter(i => i.source === 'poshmark').slice(0, 3)
    };

    // Update each platform's comps cell
    document.querySelectorAll('.comps-loading').forEach(loadingEl => {
      const platform = loadingEl.dataset.platform;
      const cell = loadingEl.parentElement;

      // Get relevant sold items for this platform
      let relevantComps = [];
      if (platform === 'eBay Authenticated') {
        relevantComps = [...bySource['eBay USA'], ...bySource['eBay Japan']].slice(0, 3);
      } else if (platform === 'Fashionphile') {
        relevantComps = bySource['Fashionphile'];
      } else if (platform === 'Poshmark') {
        relevantComps = bySource['Poshmark'];
      } else {
        // Use eBay data for others
        relevantComps = bySource['eBay USA'].slice(0, 3);
      }

      if (relevantComps.length === 0) {
        cell.innerHTML = '<div class="no-comps">No recent sold data</div>';
        return;
      }

      // Build comps HTML
      let compsHtml = relevantComps.map(comp => {
        const priceUSD = comp.currency === 'JPY' ? Math.round(comp.price / 150) : comp.price;
        const source = comp.source.replace('_', ' ').toUpperCase();
        return `<div class="comp-item-mini">
          <span class="comp-price">$${priceUSD.toLocaleString()}</span>
          <span class="comp-source">${source}</span>
        </div>`;
      }).join('');

      // Add search link
      const searchUrl = getSearchUrl(platform, brand, model);
      compsHtml += `<a href="${searchUrl}" target="_blank" rel="noopener noreferrer" class="btn-view-comps">View All Sold →</a>`;

      cell.innerHTML = compsHtml;
    });

  } catch (error) {
    console.error('Error fetching sold data:', error);
  }
}

function getSearchUrl(platform, brand, model) {
  const query = `${brand} ${model}`;
  switch (platform) {
    case 'Fashionphile':
      return `https://www.fashionphile.com/search?query=${encodeURIComponent(query)}&sold=true`;
    case 'eBay Authenticated':
      return `https://www.ebay.com/sch/i.html?_nkw=${encodeURIComponent(query + ' bag')}&LH_Sold=1&LH_Complete=1`;
    case 'Poshmark':
      return `https://poshmark.com/search?query=${encodeURIComponent(query)}&department=Women&availability=sold_out`;
    case 'TheRealReal':
      return `https://www.therealreal.com/search?q=${encodeURIComponent(query)}`;
    default:
      return `https://www.ebay.com/sch/i.html?_nkw=${encodeURIComponent(query)}&LH_Sold=1`;
  }
}

function buildNegotiationStrategy() {
  const container = document.getElementById('negotiation-tips');

  // Calculate listing age
  const listedDate = new Date(productData.crawled_at || productData.created_at || Date.now());
  const now = new Date();
  const daysOld = Math.floor((now - listedDate) / (1000 * 60 * 60 * 24));

  let strategy = '';
  let discount = 0;

  if (daysOld <= 7) {
    strategy = '📅 <strong>Fresh Listing (< 1 week)</strong><br>Offer 5-10% below asking. Seller likely testing market.';
    discount = 10;
  } else if (daysOld <= 30) {
    strategy = `📅 <strong>Listed ${daysOld} days ago</strong><br>Offer 10-15% below. Seller showing flexibility signals.`;
    discount = 15;
  } else if (daysOld <= 60) {
    strategy = `📅 <strong>Stale listing (${daysOld} days)</strong><br>Strong negotiation position! Offer 20-25% below asking.`;
    discount = 25;
  } else {
    strategy = `📅 <strong>Very old listing (${daysOld} days!)</strong><br>🎯 Seller very motivated. Try 30-40% discount or best offer!`;
    discount = 35;
  }

  const currentPrice = productData.price_usd;
  const offerPrice = Math.round(currentPrice * (1 - discount / 100));

  container.innerHTML = `
    <div style="background: linear-gradient(135deg, #fff3e0 0%, #ffe0b2 100%); padding: 1.5rem; border-radius: 10px; border-left: 4px solid #f57c00;">
      <p style="margin: 0 0 1rem 0;">${strategy}</p>
      <div style="background: white; padding: 1rem; border-radius: 8px; margin-top: 1rem;">
        <p style="margin: 0;"><strong>Recommended Offer:</strong></p>
        <p style="font-size: 1.5rem; color: #f57c00; margin: 0.5rem 0;"><strong>$${offerPrice.toLocaleString()}</strong> (${discount}% discount)</p>
        <p style="margin: 0; font-size: 0.9rem; color: #666;">Original: $${currentPrice.toLocaleString()}</p>
      </div>
      <p style="margin: 1rem 0 0 0; font-size: 0.9rem;">💡 <em>Tip: Use auction ending time pressure or "similar item" comparisons to strengthen your position.</em></p>
    </div>
  `;
}

// Extract and Display SKU Details
function extractSKUDetails() {
  const title = productData.title || '';
  const brand = identifyBrand(productData.brand || title);

  document.getElementById('sku-brand').textContent = brand || 'Unknown';
  document.getElementById('sku-model').textContent = productData.model || extractModel(title);
  document.getElementById('sku-size').textContent = productData.size || extractSize(title);
  document.getElementById('sku-color').textContent = productData.color || extractColor(title);
  document.getElementById('sku-material').textContent = productData.material || extractMaterial(title);
  document.getElementById('sku-condition').textContent = productData.condition || 'Used';
  document.getElementById('sku-external-id').textContent = productData.external_id || 'N/A';

  // Authentication markers
  const authPoints = getAuthenticationMarkers(brand);
  const authList = document.getElementById('auth-points');
  authList.innerHTML = authPoints.map(point => `<li>${point}</li>`).join('');
}

function identifyBrand(text) {
  if (!text) return 'Unknown';

  const brandMap = {
    'エルメス': 'Hermes',
    'シャネル': 'Chanel',
    'ルイヴィトン': 'Louis Vuitton',
    'グッチ': 'Gucci',
    'プラダ': 'Prada',
    'ディオール': 'Dior',
    'フェンディ': 'Fendi',
    'バレンシアガ': 'Balenciaga',
    'セリーヌ': 'Celine',
    'ボッテガヴェネタ': 'Bottega Veneta'
  };

  for (const [jp, en] of Object.entries(brandMap)) {
    if (text.includes(jp) || text.toLowerCase().includes(en.toLowerCase())) {
      return en;
    }
  }

  return 'Unknown';
}

function extractModel(title) {
  const models = {
    'Birkin': /バーキン|Birkin/i,
    'Kelly': /ケリー|Kelly/i,
    'Constance': /コンスタンス|Constance/i,
    'Neverfull': /ネヴァーフル|Neverfull/i,
    'Speedy': /スピーディ|Speedy/i,
    'Classic Flap': /マトラッセ|Classic Flap|2\.55/i,
    'Boy': /ボーイ|Boy Chanel/i,
    'Peekaboo': /ピーカブー|Peekaboo/i,
    'Baguette': /バゲット|Baguette/i
  };

  for (const [model, regex] of Object.entries(models)) {
    if (regex.test(title)) return model;
  }

  return 'See title';
}

function extractSize(title) {
  const sizeMatch = title.match(/(\d+)\s*cm|PM|MM|GM|Mini|Small|Medium|Large/i);
  return sizeMatch ? sizeMatch[0] : 'See details';
}

function extractColor(title) {
  const colors = {
    'Black': /ブラック|Black|Noir/i,
    'White': /ホワイト|White|Blanc/i,
    'Red': /レッド|Red|Rouge/i,
    'Blue': /ブルー|Blue|Bleu/i,
    'Brown': /ブラウン|Brown|Marron/i,
    'Beige': /ベージュ|Beige/i,
    'Gold': /ゴールド|Gold/i,
    'Silver': /シルバー|Silver/i
  };

  for (const [color, regex] of Object.entries(colors)) {
    if (regex.test(title)) return color;
  }

  return 'See photos';
}

function extractMaterial(title) {
  const materials = {
    'Togo': /トゴ|Togo/i,
    'Epsom': /エプソン|Epsom/i,
    'Clemence': /クレマンス|Clemence/i,
    'Lambskin': /ラムスキン|Lambskin/i,
    'Caviar': /キャビア|Caviar/i,
    'Monogram': /モノグラム|Monogram/i,
    'Damier': /ダミエ|Damier/i,
    'Epi': /エピ|Epi/i,
    'Saffiano': /サフィアーノ|Saffiano/i
  };

  for (const [material, regex] of Object.entries(materials)) {
    if (regex.test(title)) return material;
  }

  return 'See details';
}

function getAuthenticationMarkers(brand) {
  const markers = {
    'Hermes': [
      'Check date stamp and craftsman code (e.g., "A" in square = 2017)',
      'Verify saddle stitching quality and symmetry',
      'Inspect hardware for "Hermès Paris" engraving',
      'Check leather grain consistency (Togo/Clemence/Epsom patterns)',
      'Verify lock and key numbers match'
    ],
    'Chanel': [
      'Authenticate serial number sticker inside (8-digit)',
      'Check CC logo symmetry and stitching (11 stitches per quilted diamond)',
      'Verify chain weight and interlaced leather',
      'Inspect interior logo stamping clarity',
      'Check authenticity card font and hologram'
    ],
    'Louis Vuitton': [
      'Verify date code format (2 letters + 4 numbers)',
      'Check canvas print alignment and symmetry',
      'Inspect vachetta leather oxidation (natural darkening)',
      'Verify heat stamp clarity and font',
      'Check hardware engraving depth'
    ],
    'default': [
      'Verify serial number or date code',
      'Check stitching quality and consistency',
      'Inspect hardware weight and engravings',
      'Verify material authenticity',
      'Request authentication certificate'
    ]
  };

  return markers[brand] || markers['default'];
}

// Load Brand Retailer Links
function loadRetailerLinks() {
  const brand = identifyBrand(productData.brand || productData.title);
  const model = extractModel(productData.title);
  const container = document.getElementById('retailer-links');

  if (!brandRetailers[brand]) {
    container.innerHTML = '<p>No official retailer links available for this brand.</p>';
    return;
  }

  const retailer = brandRetailers[brand];

  container.innerHTML = `
    <div class="retailer-card">
      <img src="${retailer.logo}" alt="${retailer.name}" onerror="this.src='data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%2260%22 height=%2260%22><rect width=%2260%22 height=%2260%22 fill=%22%23667eea%22/><text x=%2250%%22 y=%2250%%22 fill=%22white%22 font-size=%2224%22 text-anchor=%22middle%22 dy=%22.3em%22>🏬</text></svg>'">
      <h4>${retailer.name}</h4>
      <p>Compare to NEW retail version</p>
      <a href="${retailer.searchUrl(model)}" target="_blank" rel="noopener noreferrer">Search for ${model}</a>
      <a href="${retailer.url}" target="_blank" rel="noopener noreferrer" style="margin-top: 0.5rem; background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);">Browse All Bags</a>
    </div>
  `;

  // Add secondary retailers
  const secondaryRetailers = [
    { name: 'Nordstrom', url: `https://www.nordstrom.com/sr?keyword=${encodeURIComponent(brand + ' ' + model)}`, logo: 'https://logo.clearbit.com/nordstrom.com' },
    { name: 'Neiman Marcus', url: `https://www.neimanmarcus.com/search.jsp?q=${encodeURIComponent(brand + ' ' + model)}`, logo: 'https://logo.clearbit.com/neimanmarcus.com' },
    { name: 'Saks Fifth Avenue', url: `https://www.saksfifthavenue.com/search?q=${encodeURIComponent(brand + ' ' + model)}`, logo: 'https://logo.clearbit.com/saksfifthavenue.com' }
  ];

  secondaryRetailers.forEach(r => {
    container.innerHTML += `
      <div class="retailer-card">
        <img src="${r.logo}" alt="${r.name}" onerror="this.src='data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%2260%22 height=%2260%22><rect width=%2260%22 height=%2260%22 fill=%22%23c3cfe2%22/><text x=%2250%%22 y=%2250%%22 fill=%22%23667eea%22 font-size=%2224%22 text-anchor=%22middle%22 dy=%22.3em%22>🛍️</text></svg>'">
        <h4>${r.name}</h4>
        <p>Authorized retailer</p>
        <a href="${r.url}" target="_blank" rel="noopener noreferrer">Search ${r.name}</a>
      </div>
    `;
  });

  // Create value comparison chart
  createValueComparisonChart(brand);
}

function createValueComparisonChart(brand) {
  const ctx = document.getElementById('valueComparisonChart');
  const multiplier = brandMultipliers[brand] || 1.5;
  const usedPrice = productData.price_usd;
  const newPrice = usedPrice * multiplier;

  new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ['This Used Item', 'NEW Retail (Est.)', 'Your Savings'],
      datasets: [{
        label: 'Price (USD)',
        data: [usedPrice, newPrice, newPrice - usedPrice],
        backgroundColor: [
          'rgba(102, 126, 234, 0.8)',
          'rgba(231, 76, 60, 0.8)',
          'rgba(46, 213, 115, 0.8)'
        ],
        borderColor: [
          'rgba(102, 126, 234, 1)',
          'rgba(231, 76, 60, 1)',
          'rgba(46, 213, 115, 1)'
        ],
        borderWidth: 2
      }]
    },
    options: {
      responsive: true,
      plugins: {
        legend: { display: false },
        title: {
          display: true,
          text: `Buying Used Saves You $${(newPrice - usedPrice).toLocaleString()} (${(((newPrice - usedPrice) / newPrice) * 100).toFixed(0)}%)`
        }
      },
      scales: {
        y: {
          beginAtZero: true,
          ticks: {
            callback: value => '$' + value.toLocaleString()
          }
        }
      }
    }
  });
}

// Load Price History (Mock data - integrate with real APIs)
function loadPriceHistory() {
  const brand = identifyBrand(productData.brand || productData.title);
  const model = extractModel(productData.title);

  // Mock price history data
  const mockData = generateMockPriceHistory(productData.price_usd);

  const ctx = document.getElementById('priceHistoryChart');
  new Chart(ctx, {
    type: 'line',
    data: {
      labels: mockData.dates,
      datasets: [{
        label: 'Average Sale Price',
        data: mockData.prices,
        borderColor: 'rgba(102, 126, 234, 1)',
        backgroundColor: 'rgba(102, 126, 234, 0.1)',
        tension: 0.4,
        fill: true
      }]
    },
    options: {
      responsive: true,
      plugins: {
        legend: { display: true },
        title: {
          display: true,
          text: `${brand} ${model} - 6 Month Price Trend`
        }
      },
      scales: {
        y: {
          beginAtZero: false,
          ticks: {
            callback: value => '$' + value.toLocaleString()
          }
        }
      }
    }
  });

  // Update stats
  document.getElementById('avg-sale-price').textContent = '$' + Math.round(mockData.avg).toLocaleString();
  document.getElementById('high-sale-price').textContent = '$' + Math.round(mockData.high).toLocaleString();
  document.getElementById('low-sale-price').textContent = '$' + Math.round(mockData.low).toLocaleString();
  document.getElementById('sales-volume').textContent = mockData.volume;
}

function generateMockPriceHistory(basePrice) {
  const dates = [];
  const prices = [];
  const now = new Date();

  for (let i = 180; i >= 0; i -= 30) {
    const date = new Date(now);
    date.setDate(date.getDate() - i);
    dates.push(date.toLocaleDateString('en-US', { month: 'short', year: 'numeric' }));

    const variance = (Math.random() - 0.5) * basePrice * 0.2;
    prices.push(Math.round(basePrice + variance));
  }

  return {
    dates,
    prices,
    avg: prices.reduce((a, b) => a + b, 0) / prices.length,
    high: Math.max(...prices),
    low: Math.min(...prices),
    volume: Math.floor(Math.random() * 20) + 5
  };
}

// Load Sold Comps
function loadSoldComps() {
  const brand = identifyBrand(productData.brand || productData.title);
  const model = extractModel(productData.title);
  const container = document.getElementById('comps-grid');

  // Mock sold comps - integrate with eBay, Fashionphile sold APIs
  const mockComps = generateMockComps(brand, model, productData.price_usd);

  container.innerHTML = mockComps.map(comp => `
    <div class="comp-card">
      <img src="${comp.image}" alt="${comp.title}">
      <div class="comp-card-body">
        <h5>${comp.title}</h5>
        <p class="price">$${comp.price.toLocaleString()}</p>
        <p class="meta">Sold ${comp.daysAgo} days ago on ${comp.platform}</p>
        <p class="meta">${comp.condition}</p>
      </div>
    </div>
  `).join('');
}

function generateMockComps(brand, model, basePrice) {
  const platforms = ['eBay', 'Fashionphile', 'Rebag', 'TheRealReal', 'Vestiaire'];
  const conditions = ['Excellent', 'Good', 'Fair', 'New/Unused'];

  return Array.from({ length: 8 }, (_, i) => ({
    title: `${brand} ${model}`,
    price: Math.round(basePrice * (0.8 + Math.random() * 0.4)),
    image: productData.image_url || 'https://via.placeholder.com/250x200',
    platform: platforms[Math.floor(Math.random() * platforms.length)],
    condition: conditions[Math.floor(Math.random() * conditions.length)],
    daysAgo: Math.floor(Math.random() * 60) + 1
  }));
}

// Load Platform Comparison
function loadPlatformComparison() {
  const tbody = document.getElementById('platform-comparison-body');
  const brand = identifyBrand(productData.brand || productData.title);
  const multiplier = brandMultipliers[brand] || 1.5;
  const basePrice = productData.price_usd * multiplier;
  const totalCosts = productData.price_usd + 50 + 50 + Math.round(productData.price_usd * 0.08);

  const platforms = [
    { name: 'Fashionphile', commission: 30, speed: '24-48h', salePrice: basePrice * 0.95, url: 'https://www.fashionphile.com/sell-to-us' },
    { name: 'Rebag', commission: 25, speed: 'Instant', salePrice: basePrice * 0.70, url: 'https://www.rebag.com/sell' },
    { name: 'TheRealReal', commission: 35, speed: '1-2 weeks', salePrice: basePrice * 0.90, url: 'https://www.therealreal.com/consign' },
    { name: 'Vestiaire Collective', commission: 18, speed: '2-4 weeks', salePrice: basePrice * 1.00, url: 'https://www.vestiairecollective.com/sell/' },
    { name: 'eBay Authenticated', commission: 12.5, speed: '3-7 days', salePrice: basePrice * 0.85, url: 'https://www.ebay.com/sl/sell' },
    { name: 'Poshmark', commission: 20, speed: 'Variable', salePrice: basePrice * 0.80, url: 'https://poshmark.com/sell' }
  ];

  tbody.innerHTML = platforms.map(p => {
    const netPrice = p.salePrice * (1 - p.commission / 100);
    const profit = netPrice - totalCosts;
    const profitClass = profit > 0 ? 'profit-positive' : 'profit-negative';

    return `
      <tr>
        <td class="platform-name">${p.name}</td>
        <td>${p.commission}%</td>
        <td>${p.speed}</td>
        <td>$${Math.round(p.salePrice).toLocaleString()}</td>
        <td class="${profitClass}">$${Math.round(profit).toLocaleString()}</td>
        <td>
          <a href="${p.url}" target="_blank" rel="noopener noreferrer" class="btn-primary" style="padding: 0.5rem 1rem; font-size: 0.9rem;">List Now</a>
        </td>
      </tr>
    `;
  }).join('');
}

// Utility Functions
function zoomImage() {
  window.open(productData.image_url, '_blank');
}

function reverseImageSearch() {
  const imageUrl = encodeURIComponent(productData.image_url);
  window.open(`https://www.google.com/searchbyimage?image_url=${imageUrl}`, '_blank');
}

function presellItem() {
  alert('Presell strategy modal coming soon! This will guide you through listing the item before purchasing.');
}

function compareAllPlatforms() {
  document.querySelector('[data-tab="platforms"]').click();
}