/* VendorScreen — vendor detail. Slides up over MapScreen. */

function TierBadge({ tier, dark }) {
  // tier label: U0..U4 with descriptive name. NEVER color-coded — same hue ladder.
  // Tier name ladder (consumer surface). Presence-intensity framing — never
  // good/bad/best. The U-prefix and numeric aura are internal API vocabulary.
  const names = ['Listed', 'Spark', 'Glow', 'Bright', 'Beacon'];
  const name = names[tier] ?? names[0];
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding: '5px 11px',
      borderRadius: 999,
      background: dark ? 'rgba(255,255,255,0.06)' : 'rgba(31,27,22,0.05)',
      color: 'var(--ink-2)',
      fontFamily: 'var(--font-mono)',
      fontSize: 11,
      fontWeight: 500,
      letterSpacing: '0.10em',
      textTransform: 'uppercase',
    }}>{name}</div>
  );
}

function VendorScreen({ vendor: v, onClose, onPlaceOrder, cart, setCart, dark, preset, reducedMotion, intensity, frameId }) {
  const liveTicket = useTickingMinute(v.ticket || 0);
  const liveQueue  = useTickingMinute(v.queue  || 0, 16000);
  const [following, setFollowing] = React.useState(false);
  const [staleSec, setStaleSec] = React.useState(8);
  React.useEffect(() => {
    const id = setInterval(() => setStaleSec(s => s + 1), 1000);
    return () => clearInterval(id);
  }, []);

  const cartCount = Object.values(cart).reduce((a, b) => a + b, 0);
  const cartTotal = (v.menu || []).reduce((sum, m) => sum + (cart[m.name] || 0) * m.price, 0);

  return (
    <div style={{
      position: 'absolute', inset: 0,
      background: dark ? '#0F0D0A' : 'var(--cream)',
      color: 'var(--ink)',
      overflow: 'auto',
      animation: reducedMotion ? 'none' : 'sheet-up 360ms cubic-bezier(0.2, 0.85, 0.25, 1)',
      zIndex: 60,
    }}
    className="no-scrollbar"
    >
      {/* Hero — image slot on user-fillable image; warm color block fallback */}
      <div style={{ position: 'relative', height: 320, background: v.blockTone, overflow: 'hidden' }}>
        <image-slot
          id={`hero-${frameId}-${v.id}`}
          shape="rect"
          placeholder={`Drop a hero photo for ${v.name}`}
          style={{
            position: 'absolute', inset: 0,
            width: '100%', height: '100%',
            color: 'rgba(255,255,255,0.96)',
            background: v.blockTone,
          }}
        ></image-slot>
        {/* Tonal warm overlay for legibility */}
        <div style={{
          position: 'absolute', inset: 0,
          background: 'linear-gradient(180deg, rgba(0,0,0,0.0) 0%, rgba(0,0,0,0.22) 70%, rgba(0,0,0,0.45) 100%)',
          pointerEvents: 'none',
        }}/>

        {/* Status bar spacer */}
        <div style={{ height: 56 }}/>

        {/* Top controls */}
        <div style={{
          position: 'absolute', top: 56, left: 12, right: 12,
          display: 'flex', justifyContent: 'space-between',
          zIndex: 5,
        }}>
          <button
            onClick={onClose}
            style={{
              width: 40, height: 40, borderRadius: 20,
              background: 'rgba(255,253,248,0.92)',
              backdropFilter: 'blur(10px)',
              border: 'none', cursor: 'pointer',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              boxShadow: '0 1px 2px rgba(0,0,0,0.18), 0 4px 12px rgba(0,0,0,0.10)',
            }}
          >
            <Ic.ChevronDown s={18} c="var(--ink)" />
          </button>
          <div style={{ display: 'flex', gap: 8 }}>
            <button style={{
              width: 40, height: 40, borderRadius: 20,
              background: 'rgba(255,253,248,0.92)',
              backdropFilter: 'blur(10px)',
              border: 'none', cursor: 'pointer',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              boxShadow: '0 1px 2px rgba(0,0,0,0.18), 0 4px 12px rgba(0,0,0,0.10)',
            }}>
              <Ic.Bell s={16} c="var(--ink)" />
            </button>
            <button
              onClick={() => setFollowing(f => !f)}
              style={{
                width: 40, height: 40, borderRadius: 20,
                background: following ? 'var(--ink)' : 'rgba(255,253,248,0.92)',
                backdropFilter: 'blur(10px)',
                border: 'none', cursor: 'pointer',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                boxShadow: '0 1px 2px rgba(0,0,0,0.18), 0 4px 12px rgba(0,0,0,0.10)',
                transition: 'background 200ms',
              }}>
              <Ic.Heart s={16} c={following ? 'var(--cream)' : 'var(--ink)'} filled={following}/>
            </button>
          </div>
        </div>

        {/* Caption strip at bottom of hero */}
        <div style={{
          position: 'absolute', left: 16, right: 16, bottom: 14,
          display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end',
          color: 'rgba(255,253,248,0.92)',
          zIndex: 4,
        }}>
          <div style={{
            fontFamily: 'var(--font-mono)', fontSize: 11,
            letterSpacing: '0.06em', textTransform: 'uppercase',
            opacity: 0.85,
          }}>{v.photoCaption || ''}</div>
          <div style={{
            fontFamily: 'var(--font-mono)', fontSize: 11,
            background: 'rgba(0,0,0,0.42)', padding: '4px 9px', borderRadius: 999,
            backdropFilter: 'blur(8px)',
            whiteSpace: 'nowrap',
          }}>{v.kind}</div>
        </div>
      </div>

      {/* Main card — pulls up over the hero */}
      <div style={{
        position: 'relative',
        marginTop: -22,
        background: dark ? '#0F0D0A' : 'var(--cream)',
        borderTopLeftRadius: 26, borderTopRightRadius: 26,
        padding: '20px 20px 100px',
      }}>
        {/* Identity row */}
        <div style={{ display: 'flex', alignItems: 'flex-start', gap: 16 }}>
          <div style={{ flex: 1, minWidth: 0 }}>
            <TierBadge tier={v.tier} dark={dark} />
            <h1 style={{
              margin: '8px 0 4px',
              fontFamily: 'var(--font-display)',
              fontSize: 38, fontWeight: 400,
              lineHeight: 1.0, letterSpacing: '-0.01em',
              color: 'var(--ink)',
            }}>{v.name}</h1>
            <div style={{
              display: 'flex', flexWrap: 'wrap', gap: 6, alignItems: 'center',
              fontSize: 13.5, color: 'var(--ink-3)',
            }}>
              <span>{v.cuisine}</span>
              <span style={{ opacity: 0.5 }}>·</span>
              <span>{v.priceTier}</span>
              <span style={{ opacity: 0.5 }}>·</span>
              <Ic.Pin s={12} c="var(--ink-3)" />
              <span>{v.neighborhood}</span>
              <span style={{ opacity: 0.5 }}>·</span>
              <Ic.Walk s={12} c="var(--ink-3)" />
              <span>{v.walkMin} min walk</span>
            </div>
          </div>

          <div style={{ position: 'relative', width: 96, height: 96, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <Halo tier={v.tier} size={96} preset={preset} reducedMotion={reducedMotion} intensity={intensity} accepting={v.accepting && !v.paused} stale={v.stale} />
          </div>
        </div>

        {/* Live signals — chip rail */}
        <div style={{ marginTop: 22 }}>
          <div style={{
            display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
            marginBottom: 8,
          }}>
            <div style={{
              fontFamily: 'var(--font-mono)', fontSize: 10.5,
              letterSpacing: '0.16em', textTransform: 'uppercase',
              color: 'var(--ink-3)',
            }}>Right now</div>
            <div style={{
              fontFamily: 'var(--font-mono)', fontSize: 10.5,
              color: v.stale ? '#A2761B' : 'var(--ink-4)',
            }}>
              {v.stale ? `stale · checked ${staleSec * 7 + 26}m ago` : `checked ${staleSec}s ago`}
            </div>
          </div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
            {v.accepting && !v.paused
              ? <OpChip tone="good"  icon={<Ic.Check s={11}/>}  label="Accepting orders" stale={v.stale} />
              : v.paused
              ? <OpChip tone="warn"  label="Paused — back in 12m" stale={v.stale} />
              : <OpChip tone="muted" label="Closed" />
            }
            {v.ticket > 0 && (
              <OpChip tone="default" icon={<Ic.Clock s={11}/>} label="Ticket" value={bucketTicketCompact(liveTicket)} stale={v.stale}/>
            )}
            {v.queue > 0 && (
              <OpChip tone="default" icon={<Ic.Users s={11}/>} label="Queue" value={`${liveQueue}`} stale={v.stale}/>
            )}
            {v.onSite === 'on-site'  && <OpChip tone="default" icon={<Ic.Pin s={11}/>} label="On-site" stale={v.stale}/>}
            {v.onSite === 'delayed'  && <OpChip tone="warn"    icon={<Ic.Pin s={11}/>} label="Delayed" stale={v.stale}/>}
            {v.onSite === 'not-here' && <OpChip tone="muted"   label="Not on-site" />}
            {v.onSite === 'moved'    && <OpChip tone="warn"    label="Moved location"/>}
            {v.pickupNext && v.pickupNext !== '—' && (
              <OpChip tone="default" label="Next pickup" value={v.pickupNext} stale={v.stale}/>
            )}
          </div>
          {v.soldOut?.length > 0 && (
            <div style={{
              marginTop: 10,
              padding: '8px 12px',
              borderRadius: 12,
              background: dark ? 'rgba(232,176,76,0.10)' : 'rgba(232,176,76,0.16)',
              fontSize: 12.5,
              color: dark ? '#E8B04C' : '#9B7220',
              display: 'flex', gap: 8, alignItems: 'center',
            }}>
              <span style={{ fontWeight: 600 }}>Sold out today:</span>
              <span>{v.soldOut.join(', ')}</span>
            </div>
          )}
        </div>

        {/* Menu (or unscored note) */}
        {v.menu && v.menu.length > 0 ? (
          <div style={{ marginTop: 28 }}>
            <SectionHeader>Today's menu</SectionHeader>
            <div style={{ marginTop: 8, display: 'flex', flexDirection: 'column', gap: 10 }}>
              {v.menu.map((m, i) => (
                <MenuItem
                  key={m.name}
                  item={m}
                  count={cart[m.name] || 0}
                  onAdd={() => setCart(c => ({ ...c, [m.name]: (c[m.name] || 0) + 1 }))}
                  onRemove={() => setCart(c => {
                    const n = { ...c, [m.name]: Math.max(0, (c[m.name] || 0) - 1) };
                    if (n[m.name] === 0) delete n[m.name];
                    return n;
                  })}
                  dark={dark}
                />
              ))}
            </div>
          </div>
        ) : v.tier === 0 ? (
          <div style={{
            marginTop: 22,
            padding: '14px 16px',
            borderRadius: 16,
            background: dark ? 'rgba(255,255,255,0.04)' : 'rgba(31,27,22,0.04)',
            color: 'var(--ink-3)', fontSize: 13.5,
          }}>
            <div style={{ fontWeight: 600, color: 'var(--ink-2)', marginBottom: 4 }}>
              No aura yet — that's okay.
            </div>
            Aura is earned by operating, not paid for. This vendor is on the map because
            they're here. Once orders, ticket times, and identity-anchored reviews come in,
            they'll start to glow.
          </div>
        ) : null}

        {/* Foodie posts — identity-anchored reviews */}
        {v.posts && v.posts.length > 0 && (
          <div style={{ marginTop: 28 }}>
            <SectionHeader>From foodies you might trust</SectionHeader>
            <div style={{ marginTop: 8, display: 'flex', flexDirection: 'column', gap: 10 }}>
              {v.posts.map((p, i) => (
                <Post key={i} p={p} dark={dark} />
              ))}
            </div>
          </div>
        )}

        {/* Footer note */}
        <div style={{
          marginTop: 32, paddingTop: 20,
          borderTop: dark ? '0.5px solid rgba(255,255,255,0.08)' : '0.5px solid rgba(31,27,22,0.08)',
          fontSize: 11, color: 'var(--ink-4)',
          fontFamily: 'var(--font-mono)',
          letterSpacing: '0.04em',
        }}>
          {v.handle} · wheresthefood.app/{v.id}
          <br/>
          <span style={{ opacity: 0.7 }}>Aura is earned, not bought, never weaponized.</span>
        </div>
      </div>

      {/* Sticky order bar */}
      {v.menu && v.menu.length > 0 && (
        <div style={{
          position: 'sticky', bottom: 0, left: 0, right: 0,
          padding: '12px 16px 32px',
          background: dark
            ? 'linear-gradient(180deg, rgba(15,13,10,0) 0%, rgba(15,13,10,0.92) 30%, rgba(15,13,10,0.98) 100%)'
            : 'linear-gradient(180deg, rgba(245,243,238,0) 0%, rgba(245,243,238,0.95) 30%, rgba(245,243,238,1) 100%)',
        }}>
          <button
            disabled={!v.accepting || v.paused}
            onClick={() => v.accepting && !v.paused && onPlaceOrder && onPlaceOrder()}
            style={{
              width: '100%', height: 56,
              borderRadius: 18, border: 'none', cursor: v.accepting && !v.paused ? 'pointer' : 'not-allowed',
              background: v.accepting && !v.paused ? 'var(--ink)' : (dark ? 'rgba(255,255,255,0.10)' : 'rgba(31,27,22,0.12)'),
              color: v.accepting && !v.paused ? 'var(--cream)' : 'var(--ink-3)',
              fontFamily: 'var(--font-body)',
              fontSize: 16, fontWeight: 600,
              letterSpacing: '-0.01em',
              display: 'flex', alignItems: 'center', justifyContent: 'space-between',
              padding: '0 18px 0 22px',
              boxShadow: v.accepting && !v.paused ? '0 6px 18px rgba(31,27,22,0.20)' : 'none',
              transition: 'all 180ms',
            }}
          >
            <span style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <Ic.Bag s={16} c={v.accepting && !v.paused ? 'var(--cream)' : 'var(--ink-3)'}/>
              {v.accepting && !v.paused
                ? (cartCount > 0 ? `Place pickup order · ${cartCount} item${cartCount > 1 ? 's' : ''}` : 'Place pickup order')
                : (v.paused ? 'Paused — try again in a few' : 'Not accepting orders')}
            </span>
            <span style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              {cartCount > 0 && (
                <span className="mono" style={{ fontSize: 14 }}>${cartTotal.toFixed(2)}</span>
              )}
              {v.accepting && !v.paused && (
                <span style={{
                  fontFamily: 'var(--font-mono)', fontSize: 11.5,
                  background: 'rgba(255,253,248,0.14)',
                  padding: '4px 8px', borderRadius: 999,
                }}>{bucketTicketCompact(liveTicket)}</span>
              )}
            </span>
          </button>
          {v.accepting && !v.paused && (
            <div style={{
              marginTop: 8, textAlign: 'center',
              fontFamily: 'var(--font-mono)', fontSize: 10.5,
              letterSpacing: '0.10em', textTransform: 'uppercase',
              color: 'var(--ink-4)',
            }}>Less Lines · More Eating</div>
          )}
        </div>
      )}
    </div>
  );
}

function SectionHeader({ children }) {
  return (
    <div style={{
      fontFamily: 'var(--font-display)',
      fontSize: 22, lineHeight: 1.1,
      color: 'var(--ink)',
      letterSpacing: '-0.005em',
    }}>{children}</div>
  );
}

function MenuItem({ item, count, onAdd, onRemove, dark }) {
  const sold = item.soldOut;
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 14,
      padding: '12px 14px',
      background: dark ? 'rgba(255,255,255,0.04)' : '#fff',
      borderRadius: 16,
      border: dark ? '0.5px solid rgba(255,255,255,0.07)' : '0.5px solid rgba(31,27,22,0.06)',
      opacity: sold ? 0.5 : 1,
    }}>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{
          display: 'flex', alignItems: 'baseline', gap: 8,
          fontFamily: 'var(--font-body)',
          fontSize: 15, fontWeight: 600,
          color: 'var(--ink)',
        }}>
          {item.name}
          {sold && <span style={{
            fontSize: 10, fontFamily: 'var(--font-mono)',
            color: '#A2761B', textTransform: 'uppercase', letterSpacing: '0.08em',
          }}>· sold out</span>}
        </div>
        {item.desc && (
          <div style={{ fontSize: 12.5, color: 'var(--ink-3)', marginTop: 2 }}>{item.desc}</div>
        )}
      </div>
      <div className="mono" style={{ fontSize: 14, color: 'var(--ink-2)' }}>${item.price.toFixed(2)}</div>
      {!sold && (
        count === 0 ? (
          <button onClick={onAdd} style={{
            width: 32, height: 32, borderRadius: 16,
            background: 'var(--ink)', color: 'var(--cream)',
            border: 'none', cursor: 'pointer',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            <Ic.Plus s={14} c="var(--cream)" />
          </button>
        ) : (
          <div style={{
            display: 'flex', alignItems: 'center', gap: 8,
            background: 'var(--ink)', color: 'var(--cream)',
            borderRadius: 16, padding: '4px 8px',
          }}>
            <button onClick={onRemove} style={{
              width: 22, height: 22, border: 'none', background: 'transparent',
              color: 'var(--cream)', cursor: 'pointer', fontSize: 18, lineHeight: 1,
            }}>−</button>
            <span className="mono" style={{ fontSize: 13 }}>{count}</span>
            <button onClick={onAdd} style={{
              width: 22, height: 22, border: 'none', background: 'transparent',
              color: 'var(--cream)', cursor: 'pointer', fontSize: 18, lineHeight: 1,
            }}>+</button>
          </div>
        )
      )}
    </div>
  );
}

function Post({ p, dark }) {
  const initials = p.who.split(' ').map(w => w[0]).join('').slice(0, 2);
  const tones = ['#C2682E', '#7E8C4A', '#8B5232', '#D49A2B', '#5A6E48', '#3E4A55'];
  const tone = tones[Math.abs(hashString(p.who)) % tones.length];
  return (
    <div style={{
      display: 'flex', gap: 12, padding: '12px 14px',
      background: dark ? 'rgba(255,255,255,0.04)' : '#fff',
      borderRadius: 16,
      border: dark ? '0.5px solid rgba(255,255,255,0.07)' : '0.5px solid rgba(31,27,22,0.06)',
    }}>
      <div style={{
        width: 36, height: 36, borderRadius: 18,
        background: tone, color: 'rgba(255,253,248,0.92)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontFamily: 'var(--font-display)',
        fontSize: 14, fontStyle: 'italic',
        flexShrink: 0,
      }}>{initials}</div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 8,
        }}>
          <div style={{ fontSize: 13.5, fontWeight: 600, color: 'var(--ink)' }}>{p.who}</div>
          <div className="mono" style={{ fontSize: 10.5, color: 'var(--ink-4)' }}>{p.when}</div>
        </div>
        <div style={{ fontSize: 11.5, color: 'var(--ink-3)', marginBottom: 4 }}>{p.role}</div>
        <div style={{ fontSize: 13.5, color: 'var(--ink-2)', lineHeight: 1.4 }}>{p.note}</div>
      </div>
    </div>
  );
}

function hashString(s) {
  let h = 0;
  for (let i = 0; i < s.length; i++) h = (h * 31 + s.charCodeAt(i)) | 0;
  return h;
}

window.VendorScreen = VendorScreen;
