// itrymo — Place detail. Opens when a card is tapped.
// Web: centered modal over a scrim. Mobile: full-screen sheet.
// Loaded after proto-shared.jsx (uses T, Icon, placePrice).

// Deterministic, stable "facts" derived from the place id so the
// page feels real without inventing different data on every render.
function placeHours(place) {
  let h = 0;
  for (let i = 0; i < place.id.length; i++) h = (h * 33 + place.id.charCodeAt(i)) >>> 0;
  const opens = [9, 10, 11, 11, 12, 17][h % 6];
  const closes = [21, 22, 22, 23, 0, 2][(h >> 3) % 6];
  const fmt = (n) => `${String(n).padStart(2, '0')}:00`;
  return `${fmt(opens)}–${closes === 0 ? '24:00' : fmt(closes)}`;
}

function DetailFact({ icon, label, value }) {
  return (
    <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}>
      <div style={{
        width: 34, height: 34, borderRadius: 10, background: T.bg, flexShrink: 0,
        display: 'flex', alignItems: 'center', justifyContent: 'center', color: T.faintInk,
      }}><Icon name={icon} size={15} /></div>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 11, color: T.muted, fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.4 }}>{label}</div>
        <div style={{ fontSize: 14, fontWeight: 600, color: T.ink, marginTop: 1 }}>{value}</div>
      </div>
    </div>
  );
}

function DetailBody({ place, surface }) {
  const price = placePrice(place);
  const distLabel = place.distKm < 10 ? `${place.distKm.toFixed(1)} km away` : `${Math.round(place.distKm)} km away`;
  const subLabel = ((GROUPS[place.bucket] || []).find((g) => g.id === place.sub) || {}).label || '';
  const bucketLabel = (BUCKETS.find((b) => b.id === place.bucket) || {}).label || '';
  // Fill sensible defaults so the "Good to know" grid is never empty
  const reservations = place.bucket === 'eat' ? (place.reservations || 'Walk-in only') : (place.reservations || null);
  const payment = place.payment && place.payment.length > 0 ? place.payment : (place.bucket === 'eat' ? ['cash', 'card'] : null);

  // Bucket-specific highlight chips, drawn from real fields.
  const highlights = [];
  if (place.bucket === 'eat') {
    if (place.occasion === 'with') highlights.push('Great for special occasions');
    if (place.companions && place.companions.includes('large')) highlights.push('Good for large groups');
    if (place.withFlags && place.withFlags.includes('kids')) highlights.push('Kid-friendly');
    if (place.noExtra && place.noExtra.charges) highlights.push('No hidden charges');
    if (place.withFlags && place.withFlags.includes('elderly')) highlights.push('Senior-friendly');
    if (place.withFlags && place.withFlags.includes('pet')) highlights.push('Pet-friendly');
  } else if (place.bucket === 'do') {
    const energyMap = { t1: 'Relaxed pace', t2: 'Light activity', t3: 'Action-packed', t4: 'Bucket-list thrill' };
    const budgetMap = { free: 'Free entry', mid: 'Budget-friendly', high: 'Mid-range', splurge: 'Premium experience' };
    if (place.budget) highlights.push(budgetMap[place.budget] || place.budget);
    if (place.energy) highlights.push(energyMap[place.energy] || place.energy);
    if (place.env) highlights.push(place.env === 'indoor' ? 'Indoors' : 'Outdoors');
    if (place.withFlags && place.withFlags.includes('kids')) highlights.push('Kid-friendly');
    if (place.withFlags && place.withFlags.includes('pet')) highlights.push('Pet-friendly');
    if (place.parking) highlights.push('Parking available');
  } else if (place.bucket === 'stay') {
    const tierMap = { savings: 'Budget stay', safe: 'Mid-range comfort', premium: 'Luxury & boutique' };
    if (place.tier) highlights.push(tierMap[place.tier] || place.tier);
    const mustHaveMap = { privateBath: 'Private bathroom', wifi: 'Free Wi-Fi', elevator: 'Elevator', aircon: 'Air conditioning', frontDesk247: '24/7 front desk', freeCancel: 'Free cancellation', noExtraFees: 'No hidden fees', parking: 'Parking available', petsAllowed: 'Pet-friendly' };
    if (place.mustHaves) place.mustHaves.slice(0, 4).forEach((m) => highlights.push(mustHaveMap[m] || m));
  }

  return (
    <div>
      {/* Title block */}
      <div style={{ padding: surface === 'mobile' ? '16px 20px 0' : '24px 28px 0' }}>
        <h2 style={{ fontSize: surface === 'mobile' ? 24 : 30, fontWeight: 700, letterSpacing: -0.6, lineHeight: 1.15, margin: 0 }}>
          {place.name}
        </h2>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginTop: 10, fontSize: 13, color: T.faintInk, flexWrap: 'wrap' }}>
          <span style={{ fontWeight: 600 }}>
            <Icon name="star" size={13} color={T.accent} style={{ verticalAlign: -2 }} /> {place.rating.toFixed(1)}
          </span>
          <span style={{ color: T.muted }}><Icon name="pin" size={12} style={{ verticalAlign: -1 }} /> {place.area} · {distLabel}</span>
          <span style={{ color: T.muted }}><Icon name="heart" size={12} style={{ verticalAlign: -1 }} /> {place.saved.toLocaleString()} saved</span>
        </div>
      </div>

      {/* Blurb */}
      {place.blurb && (
        <div style={{ padding: surface === 'mobile' ? '16px 20px 0' : '20px 28px 0', fontSize: 14, lineHeight: 1.6, color: T.faintInk }}>
          {place.blurb}
        </div>
      )}

      {/* Good to know */}
      <div style={{
        margin: surface === 'mobile' ? '20px 20px 0' : '24px 28px 0',
        padding: surface === 'mobile' ? 16 : 18, borderRadius: 14,
        border: `1px solid ${T.borderSoft}`, background: T.bg,
        display: 'grid', gridTemplateColumns: surface === 'mobile' ? '1fr 1fr' : '1fr 1fr 1fr', gap: 16,
      }}>
        <DetailFact icon="bookmark" label="Price" value={`${price.label} ${price.unit}`} />
        <DetailFact icon="calendar" label="Open today" value={placeHours(place)} />
        <DetailFact icon="pin" label="Area" value={place.area} />
        {reservations && <DetailFact icon="calendar" label="Reservations" value={
          reservations === 'walk-in only' ? 'Walk-in only' :
          reservations === 'reservation required' ? 'Reservation required' :
          reservations === 'online only' ? 'Online only' :
          'Recommended to reserve'
        } />}
        {payment && <DetailFact icon="bookmark" label="Payment" value={payment.map(p =>
          p === 'cash only' ? 'Cash only' :
          p === 'ic card' ? 'IC Card' :
          p.charAt(0).toUpperCase() + p.slice(1)
        ).join(' · ')} />}
        {place.bucket === 'eat' && (place.foreignerFriendly || place.access === 'japanese-language-only') && (
          <DetailFact icon="globe" label="Language" value={
            place.access === 'japanese-language-only' ? '🇯🇵 Japanese Only' :
            place.foreignerFriendly === 'foreigner friendly' ? '🌏 English OK' :
            place.foreignerFriendly === 'limited english' ? '🌏 Limited English' :
            '🇯🇵 Japanese only'
          } />
        )}
      </div>

      {/* Why people go */}
      {highlights.length > 0 && (
        <div style={{ padding: surface === 'mobile' ? '20px 20px 0' : '24px 28px 0' }}>
          <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 10 }}>Why people go</div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
            {highlights.map((h) => (
              <span key={h} style={{
                fontSize: 12.5, fontWeight: 500, color: T.faintInk,
                background: '#fff', border: `1px solid ${T.border}`,
                padding: '6px 11px', borderRadius: 999,
                display: 'inline-flex', alignItems: 'center', gap: 6,
              }}><Icon name="check" size={12} color={T.accent} /> {h}</span>
            ))}
          </div>
        </div>
      )}

      {/* Tags */}
      <div style={{ padding: surface === 'mobile' ? '20px 20px 0' : '24px 28px 0' }}>
        <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 10 }}>Tags</div>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
          {place.access === 'by-introduction-only' && (
            <span style={{
              fontSize: 12, padding: '4px 10px', borderRadius: 999, fontWeight: 700,
              color: '#7C3AED', background: '#F5F3FF', border: '1px solid #DDD6FE',
            }}>By Introduction Only</span>
          )}
          {place.tags.map((tg) => (
            <span key={tg} style={{
              fontSize: 12, padding: '4px 10px', borderRadius: 999,
              background: T.bg, color: T.faintInk, border: `1px solid ${T.borderSoft}`, fontWeight: 500,
            }}>{tg}</span>
          ))}
        </div>
      </div>

      {/* Map placeholder — matches the striped image vocabulary */}
      <div style={{ padding: surface === 'mobile' ? '20px 20px 28px' : '24px 28px 28px' }}>
        <div style={{ fontSize: 14, fontWeight: 700, marginBottom: 10 }}>Location</div>
        <div style={{
          height: surface === 'mobile' ? 140 : 200, borderRadius: 14, overflow: 'hidden',
          border: `1px solid ${T.borderSoft}`, position: 'relative',
          background: `repeating-linear-gradient(135deg, ${T.bg} 0 16px, #F1ECE2 16px 32px)`,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <div style={{
            background: 'rgba(255,255,255,0.94)', padding: '8px 14px', borderRadius: 999,
            fontSize: 12, fontWeight: 600, color: T.faintInk,
            display: 'inline-flex', alignItems: 'center', gap: 7,
          }}>
            <Icon name="pin" size={13} color={T.accent} /> {place.area}, {distLabel}
          </div>
          <code style={{
            position: 'absolute', bottom: 8, right: 10, fontSize: 10,
            color: T.muted, fontFamily: 'ui-monospace, Menlo, monospace',
          }}>[ interactive map ]</code>
        </div>
      </div>
    </div>
  );
}

function PlaceDetail({ place, surface = 'web', onClose }) {
  useEscClose(onClose);
  const fav   = useIsFav(place && place.id);
  const tried = useIsTried(place && place.id);
  if (!place) return null;
  const heroH = surface === 'mobile' ? 220 : 300;

  const hero = (
    <div style={{
      height: heroH, flexShrink: 0, position: 'relative',
      background: `repeating-linear-gradient(135deg, ${place.swatch} 0 18px, ${place.swatch}b3 18px 36px)`,
    }}>
      <button onClick={onClose} title="Back" style={{
        all: 'unset', cursor: 'pointer', position: 'absolute', top: 14, left: 14,
        width: 38, height: 38, borderRadius: 19, background: 'rgba(255,255,255,0.94)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        boxShadow: '0 2px 8px rgba(0,0,0,0.12)',
      }}>
        <Icon name={surface === 'mobile' ? 'chevR' : 'close'} size={16}
              style={surface === 'mobile' ? { transform: 'rotate(180deg)' } : null} />
      </button>
      <button onClick={() => toggleFav(place.id)} title="Save" style={{
        all: 'unset', cursor: 'pointer', position: 'absolute', top: 14, right: 14,
        width: 38, height: 38, borderRadius: 19, background: 'rgba(255,255,255,0.94)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        boxShadow: '0 2px 8px rgba(0,0,0,0.12)',
      }}>
        <Icon name="heart" size={17} color={fav ? '#E0533D' : T.faintInk} fill={fav ? '#E0533D' : 'none'} />
      </button>
      <code style={{
        position: 'absolute', bottom: 10, left: 16, fontSize: 11,
        color: 'rgba(0,0,0,0.35)', fontFamily: 'ui-monospace, Menlo, monospace',
      }}>[ photo gallery ]</code>
    </div>
  );

  const actionBar = (
    <div style={{
      display: 'flex', gap: 10, padding: surface === 'mobile' ? '12px 20px' : '16px 28px',
      borderTop: `1px solid ${T.border}`, background: '#fff',
      ...(surface === 'mobile' ? {} : { borderBottomLeftRadius: 18, borderBottomRightRadius: 18 }),
    }}>
      <button onClick={() => toggleFav(place.id)} style={{
        all: 'unset', cursor: 'pointer', flex: '1 1 0', minWidth: 0, height: 48, borderRadius: 12,
        border: `1px solid ${fav ? T.selBg : T.border}`, background: fav ? T.selBg : '#fff',
        color: fav ? T.selFg : T.ink, fontWeight: 600, fontSize: 14,
        display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
      }}>
        <Icon name="heart" size={16} fill={fav ? T.selFg : 'none'} /> {fav ? 'Saved' : 'Save'}
      </button>
      {/* Tried button */}
      <button onClick={() => toggleTried(place.id)} style={{
        all: 'unset', cursor: 'pointer', flex: '1 1 0', minWidth: 0, height: 48, borderRadius: 12,
        border: `1.5px solid ${tried ? '#065F46' : '#D1FAE5'}`,
        background: tried ? '#065F46' : '#ECFDF5',
        color: tried ? '#fff' : '#065F46', fontWeight: 600, fontSize: 14,
        display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
        transition: 'background .15s, color .15s',
      }}>
        <Icon name="tried" size={22} color={tried ? '#fff' : '#065F46'} fill="none" />
        {tried ? 'Tried ✓' : "I've Tried"}
      </button>
      <button onClick={() => {
        const url = place.mapsUrl || ('https://www.google.com/maps/search/?api=1&query=' + encodeURIComponent(place.name + ' ' + (place.area || '')));
        window.open(url, '_blank');
      }} style={{
        all: 'unset', cursor: 'pointer', flex: 1, height: 48, borderRadius: 12,
        background: T.accent, color: '#fff', fontWeight: 600, fontSize: 14,
        display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
      }}>
        <Icon name="pin" size={16} /> Directions
      </button>
      {place.fastPassUrl && (
        <button onClick={() => window.open(place.fastPassUrl, '_blank')} style={{
          all: 'unset', cursor: 'pointer', flex: 1, height: 48, borderRadius: 12,
          background: T.accent, color: '#fff', fontWeight: 600, fontSize: 14,
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
        }}>
          <Icon name="calendar" size={16} /> FastPass
        </button>
      )}
      {place.reservationUrl && (
        <button onClick={() => window.open(place.reservationUrl, '_blank')} style={{
          all: 'unset', cursor: 'pointer', flex: 1, height: 48, borderRadius: 12,
          background: T.accent, color: '#fff', fontWeight: 600, fontSize: 14,
          display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
        }}>
          <Icon name="calendar" size={16} /> Reserve
        </button>
      )}
    </div>
  );

  if (surface === 'mobile') {
    return (
      <div role="dialog" aria-modal="true" aria-label={place.name} style={{
        position: 'absolute', inset: 0, background: '#fff', zIndex: 60,
        display: 'flex', flexDirection: 'column',
        animation: 'itrymo-slideup .22s ease',
      }}>
        <div style={{ flex: 1, overflowY: 'auto' }}>
          {hero}
          <DetailBody place={place} surface="mobile" />
        </div>
        {actionBar}
      </div>
    );
  }

  // Web modal
  return (
    <div onClick={onClose} style={{
      position: 'fixed', inset: 0, zIndex: 60,
      background: 'rgba(20,18,14,0.45)',
      display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24,
      animation: 'itrymo-fade .18s ease',
    }}>
      <div onClick={(e) => e.stopPropagation()} role="dialog" aria-modal="true" aria-label={place.name} style={{
        width: '100%', maxWidth: 860, maxHeight: '90vh', background: '#fff',
        borderRadius: 18, overflow: 'hidden', display: 'flex', flexDirection: 'column',
        boxShadow: '0 30px 80px rgba(0,0,0,0.30)',
        animation: 'itrymo-pop .2s ease',
      }}>
        <div style={{ flex: 1, overflowY: 'auto' }}>
          {hero}
          <DetailBody place={place} surface="web" />
        </div>
        {actionBar}
      </div>
    </div>
  );
}

Object.assign(window, { PlaceDetail, DetailBody, DetailFact, placeHours });
