// Shared UI primitives — icons, buttons, listing card, sold tile

// Brand glyphs as inline SVG — Lucide dropped these from the CDN bundle.
const BRAND_SVG = {
  instagram: 'M12 2.2c3.2 0 3.6 0 4.85.07 1.17.05 1.8.25 2.23.41.56.22.96.48 1.38.9.42.42.68.82.9 1.38.16.42.36 1.06.41 2.23.06 1.27.07 1.65.07 4.85s0 3.58-.07 4.85c-.05 1.17-.25 1.8-.41 2.23-.22.56-.48.96-.9 1.38-.42.42-.82.68-1.38.9-.42.16-1.06.36-2.23.41-1.27.06-1.65.07-4.85.07s-3.58 0-4.85-.07c-1.17-.05-1.8-.25-2.23-.41a3.7 3.7 0 0 1-1.38-.9 3.7 3.7 0 0 1-.9-1.38c-.16-.42-.36-1.06-.41-2.23C2.21 15.58 2.2 15.2 2.2 12s0-3.58.07-4.85c.05-1.17.25-1.8.41-2.23.22-.56.48-.96.9-1.38.42-.42.82-.68 1.38-.9.42-.16 1.06-.36 2.23-.41C8.42 2.21 8.8 2.2 12 2.2zm0 6.3a3.5 3.5 0 1 0 0 7 3.5 3.5 0 0 0 0-7zm5.4-.4a.85.85 0 1 0 0-1.7.85.85 0 0 0 0 1.7z',
  facebook: 'M22 12a10 10 0 1 0-11.56 9.88V14.9H7.9V12h2.54V9.8c0-2.5 1.5-3.9 3.78-3.9 1.1 0 2.24.2 2.24.2v2.46h-1.26c-1.25 0-1.64.78-1.64 1.57V12h2.78l-.44 2.9h-2.34v6.98A10 10 0 0 0 22 12z',
  youtube: 'M21.6 7.2a2.5 2.5 0 0 0-1.76-1.77C18.27 5 12 5 12 5s-6.27 0-7.84.43A2.5 2.5 0 0 0 2.4 7.2 26 26 0 0 0 2 12a26 26 0 0 0 .4 4.8 2.5 2.5 0 0 0 1.76 1.77C5.73 19 12 19 12 19s6.27 0 7.84-.43a2.5 2.5 0 0 0 1.76-1.77A26 26 0 0 0 22 12a26 26 0 0 0-.4-4.8zM10 15V9l5.2 3L10 15z',
};

// kebab-case data-lucide name -> PascalCase key in window.lucide.icons
// e.g. "arrow-right" -> "ArrowRight", "building-2" -> "Building2", "grid-3x3" -> "Grid3x3"
const _pascal = (name) => name.split('-').map(p => p.charAt(0).toUpperCase() + p.slice(1)).join('');

const _lucideNode = (name) => {
  const L = window.lucide;
  if (!L) return null;
  const key = _pascal(name);
  return (L.icons && L.icons[key]) || L[key] || null;
};

// Convert a Lucide IconNode ([tag, attrs, children?]) into a React element.
// Rendering inline through React (instead of lucide.createIcons() mutating the
// DOM) is essential: DOM mutation behind React's back causes "removeChild"
// crashes on the next re-render.
const _renderNode = ([tag, attrs = {}, children = []], i) => {
  const props = { key: i };
  for (const k in attrs) {
    const rk = k === 'class' ? 'className'
      : k.includes('-') ? k.replace(/-([a-z])/g, (_, c) => c.toUpperCase())
      : k;
    props[rk] = attrs[k];
  }
  return React.createElement(tag, props, Array.isArray(children) ? children.map(_renderNode) : undefined);
};

const Icon = ({ name, size = 20, stroke = 2, className = "" }) => {
  const baseStyle = { display: 'inline-block', verticalAlign: 'middle', flexShrink: 0 };

  if (BRAND_SVG[name]) {
    return (
      <svg
        width={size} height={size} viewBox="0 0 24 24" fill="currentColor"
        className={className} style={baseStyle} aria-hidden="true"
      >
        <path d={BRAND_SVG[name]} />
      </svg>
    );
  }

  const node = _lucideNode(name);
  return (
    <svg
      xmlns="http://www.w3.org/2000/svg"
      width={size} height={size} viewBox="0 0 24 24"
      fill="none" stroke="currentColor" strokeWidth={stroke}
      strokeLinecap="round" strokeLinejoin="round"
      className={className} style={baseStyle} aria-hidden="true"
    >
      {node ? node.map(_renderNode) : null}
    </svg>
  );
};
window.Icon = Icon;

const formatPrice = (n) => {
  if (n >= 1_000_000) return `$${(n / 1_000_000).toFixed(n % 1_000_000 === 0 ? 0 : 2).replace(/\.?0+$/, '')}M`;
  return `$${(n / 1000).toFixed(0)}K`;
};
const formatFullPrice = (n) => `$${n.toLocaleString('en-CA')}`;
window.formatPrice = formatPrice;
window.formatFullPrice = formatFullPrice;

const ListingCard = ({ listing, onClick, faved, onFav }) => {
  return (
    <article className="listing-card" onClick={() => onClick && onClick(listing)}>
      <div className="listing-image">
        <span className={`pill ${listing.status === 'sold' ? 'pill-sold' : 'pill-active'} listing-status`}>
          {listing.status === 'sold' ? 'Sold' : 'For Sale'}
        </span>
        <button
          className={`listing-fav ${faved ? 'is-faved' : ''}`}
          onClick={(e) => { e.stopPropagation(); onFav && onFav(listing.id); }}
          aria-label="Save listing"
        >
          <Icon name={faved ? 'heart' : 'heart'} size={16} />
        </button>
        <span className="image-count"><Icon name="image" size={12} /> {listing.images.length}</span>
        <img src={listing.images[0]} alt={listing.address} loading="lazy" />
      </div>
      <div className="listing-body">
        <span className="listing-price">{formatFullPrice(listing.price)}</span>
        <div className="listing-address">
          <span>{listing.address}</span>
        </div>
        <div className="listing-address"><span className="city">{listing.neighbourhood} · {listing.city}</span></div>
        <div className="listing-specs">
          {listing.beds > 0 && <span><Icon name="bed" size={14} /> {listing.beds} bed</span>}
          {listing.baths > 0 && <span><Icon name="bath" size={14} /> {listing.baths} bath</span>}
          {listing.sqft > 0 && <span><Icon name="ruler" size={14} /> {listing.sqft.toLocaleString()} sqft</span>}
        </div>
      </div>
    </article>
  );
};
window.ListingCard = ListingCard;

const SoldTile = ({ item, onClick }) => {
  const overAsk = item.soldPrice - item.askPrice;
  const overAskPct = ((overAsk / item.askPrice) * 100).toFixed(1);
  return (
    <div className="sold-tile" onClick={() => onClick && onClick(item)}>
      <img src={item.image} alt={item.address} loading="lazy" />
      <div className="sold-meta">
        <div className="top">
          <span className="pill pill-sold">Sold</span>
          {item.daysOnMarket != null && (
            <span style={{ fontSize: 11, color: 'rgba(255,255,255,0.8)', letterSpacing: '0.06em' }}>
              {item.daysOnMarket} days
            </span>
          )}
        </div>
        <div className="bot">
          <div>
            <div className="addr">{item.address}</div>
            <div className="city">{item.neighbourhood} · {item.city}</div>
          </div>
          <div className="price">
            {formatFullPrice(item.soldPrice)}
            {overAsk > 0 && <span className="over">+{overAskPct}% over ask</span>}
          </div>
        </div>
      </div>
    </div>
  );
};
window.SoldTile = SoldTile;

const Toast = ({ message }) => message ? <div className="toast">{message}</div> : null;
window.Toast = Toast;

// Icons are now rendered inline as React SVGs (see Icon above), so there is no
// DOM to re-initialise. Kept as a no-op so existing useLucide() calls still work.
const useLucide = () => {};
window.useLucide = useLucide;
