// ROAMR — Travel-led atoms: photo placeholder, photo cards, place cards,
// map mocks with style variants, pill chips, save/heart buttons, etc.
//
// All of these read `window.TOKENS` (T) directly so they re-render with
// the live theme. Photo placeholders are deliberately tasteful striped
// SVGs with monospace captions — they say "drop a real photo here."

const TR = () => window.TOKENS;

// ─── Photo placeholder ─────────────────────────────────────────────────────
// Striped diagonals + monospace caption. Optional `tone` shifts the stripe
// color so a wall of cards doesn't look identical.
function Photo({ caption = 'photo', tone = 0, height, rounded = 0, children }) {
  const T = TR();
  // tone 0..4 maps to slightly different stripe hue/lightness
  const tones = [
    { a: T.signalGlow, b: T.signalDeep, bg: T.cardElev },
    { a: T.lichen, b: '#2A5340', bg: T.cardElev },
    { a: T.amber, b: '#7A5A20', bg: T.cardElev },
    { a: T.slate, b: '#2E4A5C', bg: T.cardElev },
    { a: T.rust, b: '#5A1F10', bg: T.cardElev },
  ];
  const c = tones[tone % tones.length];
  const id = `ph-${tone}-${(caption || '').replace(/\W/g, '').slice(0, 8)}`;
  return (
    <div style={{
      position: 'relative', width: '100%', height: height || '100%',
      background: c.bg, overflow: 'hidden', borderRadius: rounded,
    }}>
      <svg width="100%" height="100%" viewBox="0 0 400 300" preserveAspectRatio="xMidYMid slice"
        style={{ display: 'block', position: 'absolute', inset: 0 }}>
        <defs>
          <pattern id={id} patternUnits="userSpaceOnUse" width="14" height="14" patternTransform="rotate(-32)">
            <rect width="14" height="14" fill={c.bg}/>
            <rect width="7" height="14" fill={c.a} opacity="0.16"/>
          </pattern>
          <linearGradient id={`${id}-grad`} x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor={c.b} stopOpacity="0.20"/>
            <stop offset="100%" stopColor="#000" stopOpacity="0.55"/>
          </linearGradient>
        </defs>
        <rect width="400" height="300" fill={`url(#${id})`}/>
        <rect width="400" height="300" fill={`url(#${id}-grad)`}/>
        {/* horizon hint line */}
        <line x1="0" y1="190" x2="400" y2="180" stroke={c.a} strokeWidth="1.5" opacity="0.35"/>
      </svg>
      <div style={{
        position: 'absolute', left: 10, bottom: 8,
        fontFamily: T.fontM, fontSize: 9, letterSpacing: 1, color: '#fff',
        padding: '3px 7px', background: 'rgba(0,0,0,0.35)',
        backdropFilter: 'blur(4px)',
        borderRadius: 4,
        textTransform: 'uppercase', opacity: 0.85,
      }}>▢ {caption}</div>
      {children}
    </div>
  );
}

// ─── Save / heart button (floating, glass) ───────────────────────────────
function SaveBtn({ saved, onClick, size = 36 }) {
  const T = TR();
  return (
    <button onClick={(e) => { e.stopPropagation(); onClick && onClick(); }} style={{
      width: size, height: size, borderRadius: size / 2,
      background: 'rgba(0,0,0,0.42)', backdropFilter: 'blur(10px)',
      border: '1px solid rgba(255,255,255,0.25)',
      color: '#fff', cursor: 'pointer',
      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
      fontSize: 16, padding: 0,
    }}>
      <svg width="16" height="16" viewBox="0 0 16 16" fill={saved ? T.signal : 'none'} stroke={saved ? T.signal : '#fff'} strokeWidth="1.6">
        <path d="M8 13.5 C 1.5 9.5 2 4.5 5 3.5 C 6.7 3 7.6 4 8 5 C 8.4 4 9.3 3 11 3.5 C 14 4.5 14.5 9.5 8 13.5 Z"/>
      </svg>
    </button>
  );
}

// ─── Pill chip (rounded, travel feel) ────────────────────────────────────
// Renders as <button> when interactive (onClick), else as <span> — so it's
// safe to use as a decorative chip inside another button (route/trip/place
// cards) without nested-button warnings.
function Pill({ children, active, onClick, icon, dark, glass }) {
  const T = TR();
  const base = {
    display: 'inline-flex', alignItems: 'center', gap: 6,
    padding: '8px 14px', borderRadius: 100,
    fontFamily: T.fontB, fontWeight: 500, fontSize: 13,
    cursor: onClick ? 'pointer' : 'default', whiteSpace: 'nowrap',
    border: `1px solid ${T.borderSoft}`, background: T.card, color: T.text,
  };
  const styles = active
    ? { ...base, background: T.textHi, color: T.bg, borderColor: T.textHi }
    : glass
      ? { ...base, background: 'rgba(255,255,255,0.16)', backdropFilter: 'blur(10px)', borderColor: 'rgba(255,255,255,0.30)', color: '#fff' }
      : dark
        ? { ...base, background: T.bg, borderColor: T.border }
        : base;
  if (onClick) return <button onClick={onClick} style={styles}>{icon}{children}</button>;
  return <span style={styles}>{icon}{children}</span>;
}

// ─── Big stat label (travel — number + tiny caption) ────────────────────
function MetaLine({ items }) {
  const T = TR();
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 14, fontFamily: T.fontB, fontSize: 12, color: T.textLo, alignItems: 'center' }}>
      {items.map((it, i) => (
        <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
          {i > 0 && <span style={{ color: T.textMute }}>·</span>}
          {it.icon && <span style={{ color: T.textMid }}>{it.icon}</span>}
          <span><b style={{ color: T.textHi, fontWeight: 600 }}>{it.v}</b> {it.l}</span>
        </span>
      ))}
    </div>
  );
}

// ─── Section header (travel — bigger, photo-warm) ───────────────────────
function TravelSection({ kicker, title, action, onAction, children }) {
  const T = TR();
  return (
    <div style={{ marginBottom: 22 }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', padding: '0 20px', marginBottom: 14 }}>
        <div>
          {kicker && <div style={{ fontFamily: T.fontM, fontSize: 10, color: T.signal, letterSpacing: 1.6, marginBottom: 6 }}>{kicker}</div>}
          <div style={{ fontFamily: T.fontD, fontSize: 22, fontWeight: 600, color: T.textHi, letterSpacing: -0.4 }}>{title}</div>
        </div>
        {action && <button onClick={onAction} style={{ background: 'transparent', border: 'none', cursor: 'pointer', fontFamily: T.fontB, fontSize: 13, color: T.signal, fontWeight: 500 }}>{action} ›</button>}
      </div>
      {children}
    </div>
  );
}

// ─── Map mock with style variants ────────────────────────────────────────
// Reads T.mapStyle from tokens: 'contour' (current technical) | 'soft' (topography-shaded) | 'satellite' (faux satellite tiles)
function MapMockV2({ height = 200, routePath, pins = [], showLabels, rounded = 0, overlay }) {
  const T = TR();
  const style = T.mapStyle || 'soft';
  const defaultPath = "M40 170 Q 80 140 110 110 Q 150 80 200 100 Q 260 130 310 95 Q 360 60 380 90";
  const isLight = T.modeName === 'light';

  // ── Background per style ──
  let bg;
  if (style === 'satellite') {
    bg = (
      <g>
        <rect width="400" height="200" fill={isLight ? '#A8B89A' : '#1F2620'}/>
        {/* faux blobs */}
        {[
          { cx: 90, cy: 60, r: 90, fill: isLight ? '#B8C5A4' : '#2A3023' },
          { cx: 280, cy: 80, r: 110, fill: isLight ? '#C2D0A8' : '#262C1F' },
          { cx: 200, cy: 170, r: 130, fill: isLight ? '#9CAA8E' : '#1B201B' },
          { cx: 350, cy: 180, r: 60, fill: isLight ? '#A8B89A' : '#272C20' },
        ].map((b, i) => <circle key={i} cx={b.cx} cy={b.cy} r={b.r} fill={b.fill} opacity="0.85"/>)}
        {/* lakes */}
        <path d="M40 130 Q 100 120 160 132 T 280 128 L 280 145 Q 220 152 160 145 T 40 148 Z"
          fill={isLight ? '#7C99B0' : '#3B5468'} opacity="0.7"/>
        {/* trees / texture dots */}
        {Array.from({ length: 80 }).map((_, i) => {
          const x = (i * 37) % 400, y = ((i * 71) % 200);
          return <circle key={i} cx={x} cy={y} r="1.2" fill={isLight ? '#7A8C68' : '#414838'} opacity="0.5"/>;
        })}
      </g>
    );
  } else if (style === 'soft') {
    // Topo-shaded with smooth bands
    bg = (
      <g>
        <rect width="400" height="200" fill={T.cardElev}/>
        {[
          { d: 'M0 60 Q 100 30 200 50 T 400 80 L 400 0 L 0 0 Z', opacity: 0.16 },
          { d: 'M0 90 Q 100 60 200 80 T 400 110 L 400 60 L 0 60 Z', opacity: 0.13 },
          { d: 'M0 120 Q 100 90 200 110 T 400 140 L 400 90 L 0 90 Z', opacity: 0.10 },
          { d: 'M0 150 Q 100 120 200 140 T 400 170 L 400 120 L 0 120 Z', opacity: 0.07 },
        ].map((b, i) => <path key={i} d={b.d} fill={T.signal} opacity={b.opacity}/>)}
        {/* gentle contour rings */}
        <g stroke={T.borderSoft} strokeWidth="0.6" fill="none" opacity="0.5">
          <path d="M0 80 Q 100 50 200 70 T 400 90"/>
          <path d="M0 110 Q 100 80 200 100 T 400 120"/>
          <path d="M0 140 Q 100 110 200 130 T 400 150"/>
        </g>
        <path d="M0 175 Q 100 168 200 172 T 400 175" stroke={T.slate} strokeWidth="1.2" fill="none" opacity="0.5"/>
      </g>
    );
  } else {
    // contour (technical — original)
    bg = (
      <g>
        <rect width="400" height="200" fill={T.bg}/>
        <defs>
          <pattern id={`grid-${style}`} width="40" height="40" patternUnits="userSpaceOnUse">
            <path d="M40 0 L0 0 L0 40" fill="none" stroke={T.border} strokeWidth="0.5"/>
          </pattern>
        </defs>
        <rect width="400" height="200" fill={`url(#grid-${style})`}/>
        <g stroke={T.borderSoft} strokeWidth="0.6" fill="none" opacity="0.6">
          {[60, 80, 100, 120, 140].map(y => (
            <path key={y} d={`M0 ${y} Q 80 ${y - 20} 160 ${y - 10} T 320 ${y - 5} T 400 ${y + 10}`}/>
          ))}
        </g>
        <path d="M0 165 Q 100 175 200 168 T 400 165" stroke={T.slate} strokeWidth="1.2" fill="none" opacity="0.6"/>
      </g>
    );
  }

  return (
    <div style={{ position: 'relative', width: '100%', height, borderRadius: rounded, overflow: 'hidden' }}>
      <svg viewBox="0 0 400 200" preserveAspectRatio="xMidYMid slice"
        style={{ width: '100%', height: '100%', display: 'block' }}>
        {bg}
        {/* route */}
        <path d={routePath || defaultPath}
          stroke={T.signal} strokeWidth="3.2" fill="none"
          strokeLinecap="round" strokeLinejoin="round"
          style={{ filter: 'drop-shadow(0 0 4px rgba(0,0,0,0.30))' }} />
        {pins.map((p, i) => (
          <g key={i} transform={`translate(${p.x},${p.y})`}>
            <circle r={p.size || 7} fill={p.color || T.signal} stroke="#fff" strokeWidth="1.8"/>
            {p.label && <text y="3" textAnchor="middle" fontFamily="JetBrains Mono" fontSize="8" fontWeight="700" fill="#fff">{p.label}</text>}
          </g>
        ))}
        {showLabels && (
          <text x="10" y="16" fontFamily="JetBrains Mono" fontSize="8" fill={T.textMute} letterSpacing="1.2">{showLabels}</text>
        )}
      </svg>
      {overlay}
    </div>
  );
}

// ─── Travel route card (cardStyle-aware) ─────────────────────────────────
// Reads T.cardStyle: 'photo' | 'map' | 'minimal'
function TravelRouteCard({ route, onClick, photoTone = 0 }) {
  const T = TR();
  const style = T.cardStyle || 'photo';
  const radius = T.density?.radius ?? 14;

  if (style === 'minimal') {
    return (
      <div role="button" tabIndex={0} onClick={onClick} style={{
        background: T.card, border: `1px solid ${T.border}`,
        borderRadius: radius, padding: '14px 16px',
        display: 'flex', alignItems: 'center', gap: 14, width: '100%', textAlign: 'left', cursor: 'pointer',
      }}>
        <div style={{ width: 48, height: 48, borderRadius: radius - 6, overflow: 'hidden', flexShrink: 0 }}>
          <MapMockV2 height={48} routePath={route.routePath} />
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontFamily: T.fontD, fontSize: 16, fontWeight: 600, color: T.textHi, letterSpacing: -0.2, marginBottom: 4 }}>{route.name}</div>
          <MetaLine items={[
            { v: route.distance, l: 'km' },
            { v: route.time, l: '' },
            { v: route.diff?.slice(0, 3) || '—', l: '' },
          ]} />
        </div>
        <span style={{ color: T.textMute, fontSize: 18 }}>›</span>
      </div>
    );
  }

  if (style === 'map') {
    return (
      <div role="button" tabIndex={0} onClick={onClick} style={{
        background: T.card, border: `1px solid ${T.border}`,
        borderRadius: radius, overflow: 'hidden', padding: 0, width: '100%', textAlign: 'left', cursor: 'pointer',
        display: 'flex', flexDirection: 'column',
      }}>
        <MapMockV2 height={150} routePath={route.routePath}
          pins={[{ x: 45, y: 165, label: 'R' }, { x: 370, y: 75, size: 6 }]}
          overlay={
            <>
              <div style={{ position: 'absolute', top: 10, left: 10 }}>
                <Pill glass>{route.activity?.toUpperCase()}</Pill>
              </div>
              <div style={{ position: 'absolute', top: 10, right: 10 }}>
                <SaveBtn />
              </div>
            </>
          } />
        <div style={{ padding: '14px 16px 16px', display: 'flex', flexDirection: 'column', gap: 8 }}>
          <div>
            <div style={{ fontFamily: T.fontD, fontSize: 17, fontWeight: 600, color: T.textHi, letterSpacing: -0.2, marginBottom: 3 }}>{route.name}</div>
            <div style={{ fontFamily: T.fontB, fontSize: 12, color: T.textLo }}>{route.region}</div>
          </div>
          <MetaLine items={[
            { v: route.distance, l: 'km' },
            { v: route.elev, l: 'm gain' },
            { v: route.time, l: '' },
          ]} />
        </div>
      </div>
    );
  }

  // 'photo' (default — Airbnb feel)
  return (
    <div role="button" tabIndex={0} onClick={onClick} style={{
      background: 'transparent', border: 'none', padding: 0, width: '100%', textAlign: 'left', cursor: 'pointer',
      display: 'flex', flexDirection: 'column', gap: 10,
    }}>
      <div style={{ position: 'relative', height: 220, borderRadius: radius, overflow: 'hidden' }}>
        <Photo caption={`${route.name.toLowerCase().split(' ').slice(0, 2).join(' ')}`} tone={photoTone} height={220} />
        <div style={{ position: 'absolute', top: 12, left: 12, display: 'flex', gap: 6 }}>
          <Pill glass>{route.activity?.toUpperCase()}</Pill>
          {route.warn && <Pill glass>⚠ check access</Pill>}
        </div>
        <div style={{ position: 'absolute', top: 12, right: 12 }}>
          <SaveBtn />
        </div>
        <div style={{ position: 'absolute', left: 14, bottom: 12, right: 14, color: '#fff' }}>
          <div style={{ fontFamily: T.fontD, fontSize: 20, fontWeight: 600, letterSpacing: -0.3, textShadow: '0 1px 8px rgba(0,0,0,0.4)' }}>{route.name}</div>
          <div style={{ fontFamily: T.fontB, fontSize: 12, opacity: 0.92, textShadow: '0 1px 4px rgba(0,0,0,0.4)' }}>{route.region}</div>
        </div>
      </div>
      <div style={{ padding: '0 4px' }}>
        <MetaLine items={[
          { v: route.distance, l: 'km' },
          { v: route.elev, l: 'm gain' },
          { v: route.time, l: '' },
          { v: route.diff?.slice(0, 3) || 'EZ', l: '' },
        ]} />
      </div>
    </div>
  );
}

// ─── Place card (POI — campsite, viewpoint, café) ───────────────────────
function PlaceCard({ place, onClick, photoTone = 0, large }) {
  const T = TR();
  const radius = T.density?.radius ?? 14;
  return (
    <div role="button" tabIndex={0} onClick={onClick} style={{
      background: 'transparent', border: 'none', padding: 0, textAlign: 'left', cursor: 'pointer',
      display: 'flex', flexDirection: 'column', gap: 8, width: '100%',
    }}>
      <div style={{ position: 'relative', height: large ? 200 : 140, borderRadius: radius, overflow: 'hidden' }}>
        <Photo caption={place.kind} tone={photoTone} height={large ? 200 : 140} />
        <div style={{ position: 'absolute', top: 10, left: 10 }}>
          <Pill glass>{place.kind}</Pill>
        </div>
        <div style={{ position: 'absolute', top: 10, right: 10 }}>
          <SaveBtn />
        </div>
      </div>
      <div style={{ padding: '0 2px' }}>
        <div style={{ fontFamily: T.fontD, fontSize: large ? 17 : 15, fontWeight: 600, color: T.textHi, letterSpacing: -0.2, marginBottom: 3 }}>{place.name}</div>
        <div style={{ fontFamily: T.fontB, fontSize: 12, color: T.textLo, display: 'flex', alignItems: 'center', gap: 6 }}>
          <span style={{ color: T.signal }}>●</span> {place.region} <span style={{ color: T.textMute }}>·</span> {place.distFromYou}
        </div>
      </div>
    </div>
  );
}

// ─── Hero featured trip card (horizontal scroll showcase) ───────────────
function TripHeroCard({ trip, onClick, photoTone = 0, width = 280 }) {
  const T = TR();
  const radius = T.density?.radius ?? 14;
  return (
    <div role="button" tabIndex={0} onClick={onClick} style={{
      background: 'transparent', border: 'none', padding: 0, textAlign: 'left', cursor: 'pointer',
      flexShrink: 0, width, display: 'flex', flexDirection: 'column', gap: 0,
      borderRadius: radius, overflow: 'hidden', position: 'relative',
    }}>
      <div style={{ position: 'relative', height: 360 }}>
        <Photo caption={trip.tagline} tone={photoTone} height={360} />
        <div style={{
          position: 'absolute', inset: 0,
          background: 'linear-gradient(180deg, rgba(0,0,0,0.0) 30%, rgba(0,0,0,0.65) 100%)',
        }} />
        <div style={{ position: 'absolute', top: 14, left: 14, display: 'flex', gap: 6 }}>
          <Pill glass>{trip.days} {trip.days === 1 ? 'day' : 'days'}</Pill>
          <Pill glass>{trip.region}</Pill>
        </div>
        <div style={{ position: 'absolute', top: 14, right: 14 }}>
          <SaveBtn />
        </div>
        <div style={{ position: 'absolute', left: 16, right: 16, bottom: 16, color: '#fff' }}>
          <div style={{ fontFamily: T.fontM, fontSize: 10, color: 'rgba(255,255,255,0.85)', letterSpacing: 1.6, marginBottom: 8 }}>{trip.kicker.toUpperCase()}</div>
          <div style={{ fontFamily: T.fontD, fontSize: 24, fontWeight: 600, letterSpacing: -0.5, lineHeight: 1.1, marginBottom: 8, textShadow: '0 1px 8px rgba(0,0,0,0.4)' }}>{trip.name}</div>
          <div style={{ fontFamily: T.fontB, fontSize: 13, opacity: 0.92, lineHeight: 1.45, textShadow: '0 1px 4px rgba(0,0,0,0.4)' }}>{trip.tagline}</div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  Photo, SaveBtn, Pill, MetaLine, TravelSection,
  MapMockV2, TravelRouteCard, PlaceCard, TripHeroCard,
});
