import { Item } from '../models';

export function getDiscountedPrice(item: Item): number {
  return item.price * (1 - (item.discount || 0) / 100);
}

export function getMainImage(item: Item): string {
  // Support both backOffice format (imgs: string[]) and legacy (photos: Photo[])
  if (item.imgs && item.imgs.length > 0) {
    return item.imgs[0];
  }
  return item.photos?.[0]?.url || '/assets/images/placeholder.svg';
}

const PLACEHOLDER_IMAGE = '/assets/images/placeholder.svg';

/** Swaps a broken/404'd <img> src to the shared placeholder, once, to avoid an infinite error loop. */
export function onImageError(event: Event): void {
  const img = event.target as HTMLImageElement;
  if (img.src.endsWith(PLACEHOLDER_IMAGE)) return;
  img.src = PLACEHOLDER_IMAGE;
}

export function trackByItemId(_index: number, item: Item): number | string {
  return item.id || item.itemID;
}

/**
 * Compute stock status from quantity if the legacy `remainings` field is absent.
 */
export function getStockStatus(item: Item): string {
  if (item.remainings) return item.remainings;
  if (item.quantity == null) return 'high';
  if (item.quantity <= 0) return 'out';
  if (item.quantity <= 5) return 'low';
  if (item.quantity <= 20) return 'medium';
  return 'high';
}

/**
 * Map backOffice badge names to CSS color classes.
 */
export function getBadgeClass(badge: string): string {
  const map: Record<string, string> = {
    'new': 'badge-new',
    'sale': 'badge-sale',
    'exclusive': 'badge-exclusive',
    'hot': 'badge-hot',
    'limited': 'badge-limited',
    'bestseller': 'badge-bestseller',
    'featured': 'badge-featured',
  };
  return map[badge.toLowerCase()] || 'badge-custom';
}

const HTML_ENTITY_MAP: Record<string, string> = {
  '&lt;': '<',
  '&gt;': '>',
  '&quot;': '"',
  '&#39;': "'",
  '&apos;': "'",
  '&nbsp;': ' ',
  '&amp;': '&',
};

/**
 * Cleans up seller-supplied description text for safe plain-text display: decodes
 * HTML entities (some catalog listings arrive HTML-escaped, e.g. "&lt;attention&gt;")
 * and strips any resulting tag-like markup. Never renders as HTML — output stays a
 * plain string for text interpolation, so this cannot introduce an XSS surface.
 */
export function cleanDescription(text: string | undefined | null): string {
  if (!text) {
    return '';
  }
  const decoded = text.replace(/&lt;|&gt;|&quot;|&#39;|&apos;|&nbsp;|&amp;/g, match => HTML_ENTITY_MAP[match]);
  return decoded.replace(/<\/?[a-zA-Z][^>]*>/g, '').trim();
}

/**
 * Get the translated name/description for the current language.
 * Checks translations map first, then names[]/descriptions[] arrays,
 * then falls back to the default (base) field.
 */
export function getTranslatedField(
  item: Item,
  field: 'name' | 'simpleDescription',
  lang: string
): string {
  // 1. Check translations map (already normalized to frontend codes)
  const translation = item.translations?.[lang];
  if (translation && translation[field]) {
    return translation[field]!;
  }

  // 2. Check names[]/descriptions[] arrays (may have API codes: RU/EN/AM)
  //    Note: API has typo "valuue" in some responses — handle both
  if (field === 'name' && item.names?.length) {
    const entry = item.names.find(n => n.language === lang || n.language === lang.toUpperCase() || (lang === 'hy' && n.language === 'AM'));
    const val = entry?.value || (entry as any)?.valuue || '';
    if (val) return val;
  }
  // 3. Fallback to base field
  if (field === 'name') return item.name;
  if (field === 'simpleDescription') return item.simpleDescription || item.description || '';
  return '';
}
