/* FinPulse shared components + formatters. Exports to window. */

// ---- formatters ----
const fmt = {
  price: (n) => n.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }),
  pct: (n) => (n > 0 ? '+' : '') + n.toFixed(2) + '%',
  signed: (n) => (n > 0 ? '+' : '') + n.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }),
  mcap: (cr) => {
    if (cr >= 100000) return '₹' + (cr / 100000).toFixed(2) + 'L Cr';
    if (cr >= 1000) return '₹' + (cr / 1000).toFixed(1) + 'K Cr';
    return '₹' + cr.toFixed(0) + ' Cr';
  },
  usMcap: (m) => {
    if (!m || m <= 0) return '—';
    if (m >= 1e6) return '$' + (m / 1e6).toFixed(2) + 'T';
    if (m >= 1e3) return '$' + (m / 1e3).toFixed(1) + 'B';
    return '$' + m.toFixed(0) + 'M';
  },
  stockMcap: (s) => ((s && s.live && s.cur === 'USD') ? fmt.usMcap(s.mcap) : fmt.mcap(s.mcap)),
  stockPrice: (s) => {
    const c = s && s.live ? window.FinnhubMappers.curSym(s.cur) : '$';
    return c + fmt.price(s.price);
  },
  vol: (lakh) => lakh.toFixed(1) + 'L',
  idx: (n) => n.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }),
};

// ---- change chip ----
function ChangeChip({ value, sm, showArrow = true }) {
  const up = value >= 0;
  return (
    <span className={`chip ${up ? 'up' : 'down'} ${sm ? 'sm' : ''}`}>
      {showArrow && <span style={{ fontSize: sm ? 9 : 10 }}>{up ? '▲' : '▼'}</span>}
      {fmt.pct(value)}
    </span>
  );
}

// ---- stock avatar ----
function StockAvatar({ stock, size = 36 }) {
  return (
    <div className="stock-ava" style={{ background: stock.sectorColor, width: size, height: size, fontSize: size * 0.33 }}>
      {stock.initials}
    </div>
  );
}

// ---- index tile ----
function IndexTile({ ix, selected, onClick }) {
  const up = ix.chg >= 0;
  const sym = ix.cur === 'INR' ? '₹' : (ix.cur === 'USD' ? '$' : '');
  const Tag = onClick ? 'button' : 'div';
  return (
    <Tag
      type={onClick ? 'button' : undefined}
      className={`index-tile ${selected ? 'sel' : ''}`}
      onClick={onClick}
    >
      <div className="it-label">{ix.label}</div>
      <div className="it-row">
        <span className="it-val">{sym}{fmt.idx(ix.value)}</span>
        <span className={`it-chg ${up ? 'up' : 'down'}`}>{fmt.pct(ix.chg)}</span>
      </div>
    </Tag>
  );
}

// ---- stock quote card ----
function StockQuoteCard({ stock, onOpen }) {
  return (
    <div className="quote-card hoverable" onClick={() => onOpen && onOpen(stock)} style={{ cursor: onOpen ? 'pointer' : 'default' }}>
      <div className="qc-left" style={{ display: 'flex', alignItems: 'center', gap: 11 }}>
        <StockAvatar stock={stock} size={34} />
        <div style={{ minWidth: 0 }}>
          <div className="qc-name">{stock.name}</div>
          <div className="qc-ticker">{stock.ticker}</div>
        </div>
      </div>
      <div className="qc-right">
        <div className="qc-price">{fmt.stockPrice(stock)}</div>
        <ChangeChip value={stock.chg} sm />
      </div>
    </div>
  );
}

// ---- metric card ----
function MetricCard({ label, value, sub, color = 'var(--accent)' }) {
  return (
    <div className="metric-card">
      <div className="metric-band" style={{ background: color }}></div>
      <div className="metric-body">
        <div className="metric-label">{label}</div>
        <div className="metric-val">{value}</div>
        {sub && <div className="metric-sub">{sub}</div>}
      </div>
    </div>
  );
}

// ---- category pill ----
function CatPill({ cat, color }) {
  return <span className="cat-pill" style={{ background: color }}>{cat}</span>;
}

// ---- news image: real photo when available, striped placeholder otherwise ----
function NewsImg({ seed, className, h, src }) {
  const [failed, setFailed] = useState(false);
  if (src && !failed) {
    return <img className={className} src={src} alt="" loading="lazy" width={className === 'nf-img' ? 800 : 80} height={h}
      style={{ height: h, objectFit: 'cover', width: className === 'ns-img' ? 80 : '100%' }} onError={() => setFailed(true)} />;
  }
  const hue = (seed * 47) % 360;
  return (
    <div className={className} style={{
      background: `repeating-linear-gradient(135deg, oklch(0.85 0.04 ${hue}), oklch(0.85 0.04 ${hue}) 8px, oklch(0.8 0.05 ${hue}) 8px, oklch(0.8 0.05 ${hue}) 16px)`,
      display: 'grid', placeItems: 'center', height: h,
    }}>
      <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'rgba(0,0,0,0.45)', letterSpacing: '0.05em' }}>news photo</span>
    </div>
  );
}

function newsOpenProps(item, onOpen) {
  if (!onOpen) return {};
  return {
    role: 'button',
    tabIndex: 0,
    onClick: () => onOpen(item),
    onKeyDown: (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onOpen(item); } },
    style: { cursor: 'pointer' },
  };
}

// ---- featured news ----
function NewsFeatured({ item, onOpen }) {
  return (
    <div className="news-featured" style={{ display: 'block' }} {...newsOpenProps(item, onOpen)}>
      <NewsImg seed={item.id} className="nf-img" h={220} src={item.image} />
      <div className="nf-body">
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <span className="source-badge"><span className="source-dot"></span>{item.source}</span>
          <CatPill cat={item.cat} color={item.catColor} />
        </div>
        <div className="nf-head">{item.headline}</div>
        {item.summary && <div className="nf-sum">{(window.HtmlText ? window.HtmlText.stripHtml(item.summary) : item.summary)}</div>}
        <div className="nf-meta">
          <span>{item.author}</span><span>·</span><span>{item.time}</span><span>·</span><span>{item.read} read</span>
          <span className={`sentiment ${item.sentiment === 'bull' ? 'bull' : 'bear'}`}>{item.sentiment === 'bull' ? 'Bullish' : 'Bearish'}</span>
        </div>
      </div>
    </div>
  );
}

// ---- standard news card ----
function NewsStandard({ item, onOpen }) {
  return (
    <div className="news-std" {...newsOpenProps(item, onOpen)}>
      <NewsImg seed={item.id} className="ns-img" h={64} src={item.image} />
      <div style={{ minWidth: 0, flex: 1 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span className="source-badge" style={{ fontSize: 11 }}><span className="source-dot" style={{ background: item.catColor }}></span>{item.source}</span>
        </div>
        <div className="ns-head">{item.headline}</div>
        <div className="ns-time">{item.time}</div>
      </div>
    </div>
  );
}

// ---- compact news row ----
function NewsCompact({ items, onOpen }) {
  return (
    <div className="news-compact">
      {items.map((n) => (
        <div key={n.id} className="nc-row" {...newsOpenProps(n, onOpen)}>
          <span className="nc-dot" style={{ background: n.catColor }}></span>
          <span className="nc-head">{n.headline}</span>
          <span className="nc-time">{n.time}</span>
        </div>
      ))}
    </div>
  );
}

// ---- empty state ----
function EmptyState({ icon, title, sub, action }) {
  return (
    <div className="empty-state">
      <div className="es-icon"><Icon name={icon} size={26} /></div>
      <div className="h3" style={{ color: 'var(--text-secondary)' }}>{title}</div>
      <div className="muted" style={{ maxWidth: 320 }}>{sub}</div>
      {action && <div style={{ marginTop: 14 }}>{action}</div>}
    </div>
  );
}

Object.assign(window, { fmt, ChangeChip, StockAvatar, IndexTile, StockQuoteCard, MetricCard, CatPill, NewsImg, NewsFeatured, NewsStandard, NewsCompact, EmptyState });
