/* =========================================================
   Result screen
   ========================================================= */
const { Icon: RI, Stars, PhotoUploader, MonsteraLeaf, Mascot, CoupleMark } = window;

/* ---------- ROUTE CARD ---------- */
function RouteCard({ person, onModeChange }){
  const mode = person.mode || 'transit';
  const wp = (person.waypoint && !person.waypointNone) ? person.waypoint : '';
  const legs = [];
  legs.push({ kind:'출발지', place:person.start || '미입력', cls:'start' });
  if (wp) legs.push({ kind:'경유 · 만날 곳', place:wp, cls:'' });
  legs.push({ kind:'도착지 · 함께 갈 곳', place:person.dest || '미입력', cls:'end' });
  if (person.home) legs.push({ kind:'귀가지', place:person.home, cls:'' });

  // 출발지·도착지 좌표 → 수단별 예상 소요 + 네이버 정확 경로 링크
  const [km, setKm] = React.useState(null);
  const [geoTried, setGeoTried] = React.useState(false);
  const [sC, setSC] = React.useState(null), [gC, setGC] = React.useState(null);
  React.useEffect(() => {
    let cancel = false;
    setKm(null); setGeoTried(false);
    if (!person.start || !person.dest) { setGeoTried(true); return; }
    Promise.all([window.geocodeOne(person.start), window.geocodeOne(person.dest)])
      .then(([s, g]) => { if (cancel) return; setSC(s); setGC(g); setKm(window.haversineKm(s, g)); setGeoTried(true); })
      .catch(() => { if (!cancel) setGeoTried(true); });
    return () => { cancel = true; };
  }, [person.start, person.dest]);

  const sel = window.TRAVEL_MODES.find(m => m.key === mode) || window.TRAVEL_MODES[0];
  const selMin = window.estMinutes(km, mode);

  // 실시간 경로 (대중교통=ODsay, 운전=네이버). {min,source}|{limited}|{none}|null
  const [route, setRoute] = React.useState(null);
  const [routeLoading, setRouteLoading] = React.useState(false);
  React.useEffect(() => {
    let cancel = false;
    setRoute(null);
    if (!sC || !gC || (mode !== 'transit' && mode !== 'driving')) return;
    setRouteLoading(true);
    window.fetchRoute(mode, sC, gC).then(r => { if (!cancel) { setRoute(r); setRouteLoading(false); } });
    return () => { cancel = true; };
  }, [mode, sC, gC]);

  const realMin = route && typeof route.min === 'number' ? route.min : null;
  const srcName = route && route.source === 'odsay' ? 'ODsay 대중교통' : (route && route.source === 'naver' ? '네이버 운전' : null);

  const naverUrl = window.naverDir(person.start, person.dest, wp, mode, sC, gC);
  const gUrl = window.gmDir(person.start, person.dest, wp, mode);
  const naverHome = person.home ? window.naverDir(person.dest, person.home, '', mode, gC, null) : null;

  return (
    <div className="route-card">
      <div className="rc-head">
        <span className={'av ' + person.key} style={{ background:'transparent', padding:0 }}>
          {person.key === 'couple' ? <CoupleMark size={30} /> : <Mascot variant={person.key} size={30} />}
        </span>
        <span className="nm">{person.key === 'couple' ? '우리 둘이' : person.name + '이'}</span>
        <span className="mode"><RI name={sel.icon} />{sel.label}</span>
      </div>

      {/* 수단 선택 (선택 가능 + 예상 소요 표기) */}
      <div className="mode-pick">
        {window.TRAVEL_MODES.map(m => {
          const min = window.estMinutes(km, m.key);
          const on = m.key === mode;
          return (
            <button key={m.key} className={'mode-opt' + (on ? ' on' : '')}
              onClick={() => onModeChange && onModeChange(m.key)}>
              <RI name={m.icon} />
              <span className="mo-label">{m.label}</span>
              <span className="mo-min">{min != null ? min + '분' : (geoTried ? '' : '…')}</span>
            </button>
          );
        })}
      </div>

      <div className="legs">
        {legs.map((lg, i) => (
          <div className="leg" key={i}>
            <div className="marker">
              <span className={'pt ' + lg.cls}></span>
              {i < legs.length - 1 && <span className="ln"></span>}
            </div>
            <div className="lg-body">
              <div className="lg-kind">{lg.kind}</div>
              <div className="lg-place">{lg.place}</div>
            </div>
          </div>
        ))}
      </div>

      <div className="route-est">
        <RI name={sel.icon} />
        {realMin != null ? (
          <span><b>{srcName}</b> <b>{realMin}분</b>{route.transfers > 0 ? ' · 환승 ' + route.transfers : ''}<span className="rt-live">실시간</span></span>
        ) : routeLoading ? (
          <span><b>{sel.label}</b> 경로 찾는 중…</span>
        ) : route && route.limited ? (
          <span><b>{sel.label}</b> 예상 <b>{selMin != null ? selMin + '분' : '–'}</b> · 오늘 무료조회 초과 → 네이버에서 확인</span>
        ) : selMin != null ? (
          <span><b>{sel.label}</b> 예상 <b>{selMin}분</b></span>
        ) : (
          <span><b>{sel.label}</b> · 정확한 시간은 네이버에서 확인해줘</span>
        )}
        {(realMin != null ? route.distKm : km) != null && <span className="re-km">· 약 {(realMin != null ? route.distKm : km).toFixed(1)}km</span>}
      </div>

      <div style={{ display:'flex', gap:8, marginTop:11 }}>
        <a className="btn btn-sm btn-route nv" style={{ flex:1.4 }} href={naverUrl} target="_blank" rel="noopener">
          <RI name="nav" />네이버 길찾기
        </a>
        <a className="btn btn-sm btn-map" style={{ flex:1 }} href={gUrl} target="_blank" rel="noopener">
          <RI name="map" />구글
        </a>
        {naverHome && (
          <a className="btn btn-sm btn-route" href={naverHome} target="_blank" rel="noopener" title="귀가 경로">
            <RI name="home" />귀가
          </a>
        )}
      </div>
      <p className="route-hint">대중교통·운전은 <b>실시간 조회</b>(하루 무료한도), 도보·자전거는 직선거리 <b>예상치</b>예요. 정확한 길은 네이버에서 확인해줘 🌿</p>
    </div>
  );
}

/* ---------- RESTAURANT CARD ---------- */
function RestaurantCard({ r, n, picked, onPick }){
  return (
    <div className={'rest ' + r.color + (picked ? ' picked' : '')}>
      <div className="rest-top">
        <div className="rest-head">
          <span className="rest-no">{n}</span>
          <div className="rest-title">
            <h4>{r.name}</h4>
            <div className="rest-sub">
              <span className="badge">{r.badge}</span>
              <Stars value={r.rating} />
              <span className="walk"><RI name="walk" />도보 {r.walk}분</span>
            </div>
          </div>
        </div>
        <p className="rest-desc">{r.desc}</p>
        <div className="rest-menu"><RI name="utensils" /><span><b>추천</b> · {r.menu}</span></div>
      </div>
      <div className="rest-actions">
        <button className={'pick'} title="여기로 정하기" onClick={() => onPick(r.id)}>
          <RI name={picked ? 'heart' : 'heart'} />
        </button>
        <a className="btn btn-map" href={window.gmSearch(r.query)} target="_blank" rel="noopener">
          <RI name="pin" />구글지도
        </a>
        <a className="btn btn-route" href={window.naverSearch(r.query)} target="_blank" rel="noopener">
          <RI name="nav" />길찾기
        </a>
      </div>
    </div>
  );
}

/* ---------- MINI SUMMARY CARD (2x2 grid) ---------- */
function RestMini({ r, n, picked, onOpen, onPick }){
  return (
    <div className={'rest-mini ' + r.color + (picked ? ' picked' : '')} onClick={() => onOpen(r, n)}>
      <div className="rm-top">
        <span className="rm-no">{n}</span>
        <button className="rm-heart" title="여기로 정하기" onClick={e => { e.stopPropagation(); onPick(r.id); }}>
          <RI name="heart" />
        </button>
      </div>
      <h4>{r.name}</h4>
      <div className="rm-tags">
        <span className="rm-badge">{r.badge}</span>
        {r.openOnMeet === true && <span className="open-tag ok">영업</span>}
        {r.openOnMeet === false && <span className="open-tag no">휴무</span>}
      </div>
      <div className="rm-foot">
        {r.rating > 0 ? <Stars value={r.rating} /> : <span className="walk">평점 정보 없음</span>}
        <span className="rm-more">자세히<RI name="chevR" /></span>
      </div>
    </div>
  );
}

/* ---------- DETAIL SHEET ---------- */
function RestDetailSheet({ item, picked, provider, onClose, onPick }){
  if (!item) return null;
  const r = item.r;
  const nv = provider === 'naver';
  return (
    <div className="scrim" onClick={onClose}>
      <div className="sheet" onClick={e => e.stopPropagation()}>
        <div className="sheet-grip"></div>
        <div className="sheet-head">
          <h3>가게 정보</h3>
          <button className="x" onClick={onClose}><RI name="x" /></button>
        </div>
        <div className="sheet-body">
          <div className="rd-hero">
            <span className={'rd-no ' + r.color}>{item.n}</span>
            <div>
              <h3>{r.name}</h3>
              <div className="rd-meta">
                <span className="badge">{r.badge}</span>
                {r.rating > 0 && <Stars value={r.rating} />}
                {r.walk != null
                  ? <span className="walk"><RI name="walk" />도보 {r.walk}분</span>
                  : (r.reviews ? <span className="walk"><RI name="users" />리뷰 {r.reviews.toLocaleString()}</span> : null)}
                {r.openOnMeet === true && <span className="open-tag ok">만나는 날 영업</span>}
                {r.openOnMeet === false && <span className="open-tag no">만나는 날 휴무</span>}
              </div>
            </div>
          </div>
          {r.desc && <p className="rest-desc" style={{ marginTop:12 }}>{r.desc}</p>}
          {r.menu && <div className="rest-menu"><RI name="utensils" /><span><b>추천</b> · {r.menu}</span></div>}
          <div className="map-embed" style={{ marginTop:13 }}>
            <iframe loading="lazy" referrerPolicy="no-referrer-when-downgrade" src={window.gmEmbed(r.query)}></iframe>
          </div>
          <button className={'btn btn-full ' + (picked ? 'btn-primary' : 'btn-ghost')} style={{ marginTop:13 }} onClick={() => onPick(r.id)}>
            <RI name="heart" />{picked ? '정한 곳이에요 💚' : '여기로 정하기'}
          </button>
          <div style={{ display:'flex', gap:8, marginTop:9 }}>
            <a className="btn btn-sm btn-map" style={{ flex:1 }} href={nv ? window.naverSearch(r.query) : window.gmSearch(r.query)} target="_blank" rel="noopener"><RI name="pin" />{nv ? '네이버 지도' : '구글 지도'}</a>
            <a className="btn btn-sm btn-route" style={{ flex:1 }} href={nv ? window.gmSearch(r.query) : window.naverSearch(r.query)} target="_blank" rel="noopener"><RI name="nav" />{nv ? '구글 지도' : '네이버 지도'}</a>
          </div>
        </div>
      </div>
    </div>
  );
}

/* ---------- API GUIDE ---------- */
function ApiGuide(){
  const [open, setOpen] = React.useState(false);
  return (
    <div className="info-panel" style={{ marginTop:22 }}>
      <div className="ip-head" onClick={() => setOpen(!open)}>
        <span className="ic"><RI name="info" /></span>
        <h4>구글 실시간 연동됨 ✓</h4>
        <span className={'chev' + (open ? ' open' : '')}><RI name="chevD" /></span>
      </div>
      {open && (
        <div className="fadein">
          <p style={{ fontSize:'.84rem', color:'var(--muted)', margin:'12px 0 4px' }}>
            맛집·포차는 이제 <b>구글 지도 실시간 검색 결과</b>로 보여요. (검색이 안 되면 잠시 큐레이션 추천으로 자동 전환돼요.)
          </p>
          <p style={{ fontSize:'.84rem', color:'var(--muted)', margin:'8px 0 4px', fontWeight:700 }}>🔐 키 보안 체크리스트</p>
          <ol>
            <li><b>Cloud Console → 사용자 인증 정보</b>에서 이 키의 <b>애플리케이션 제한 → HTTP 리퍼러</b>에 배포 주소를 등록하세요.</li>
            <li><b>API 제한</b>은 <code>Maps Embed API</code>, <code>Maps JavaScript API</code>, <code>Places API</code>만 허용.</li>
            <li>위 세 API가 <b>사용 설정(Enable)</b> 되어 있어야 지도·검색이 떠요.</li>
          </ol>
          <p style={{ fontSize:'.78rem', color:'var(--faint)' }}>
            ※ 키는 공유 파일에 노출됩니다. 리퍼러 제한을 꼭 걸어두세요.
          </p>
        </div>
      )}
    </div>
  );
}

/* ---------- WEATHER (만나는 날) ---------- */
function Weather({ place, date, tag }){
  const [wx, setWx] = React.useState(null);
  React.useEffect(() => {
    let c = false;
    if (!date) { setWx(null); return; }
    window.fetchWeather(place, date).then(w => { if (!c) setWx(w); });
    return () => { c = true; };
  }, [place, date]);
  if (!wx) return null;
  return (
    <div className="wx">
      {tag && <span className="tag">{tag}</span>}
      <span className="emoji">{wx.emoji}</span>
      <span className="temp">{wx.tmax}°<small>/{wx.tmin}°</small></span>
      <span className="lbl">{wx.label}</span>
    </div>
  );
}
function WeatherInline({ place, date }){
  const [wx, setWx] = React.useState(null);
  React.useEffect(() => {
    let c = false;
    if (!date) { setWx(null); return; }
    window.fetchWeather(place, date).then(w => { if (!c) setWx(w); });
    return () => { c = true; };
  }, [place, date]);
  if (!wx) return null;
  return (
    <span className="when-wx"><span className="e">{wx.emoji}</span>{wx.tmax}°<small>/{wx.tmin}°</small></span>
  );
}

/* ---------- 실시간 결과 못 불러올 때(영통 외 목적지) ---------- */
function SearchFallback({ dest }){
  return (
    <div className="search-fallback">
      <div className="sf-emoji">🔎</div>
      <h4>{dest} 주변 실시간 결과를<br/>지금은 못 불러왔어</h4>
      <p>잠깐 길이 막혔나 봐 🥲 아래로 바로 찾아볼 수 있어!</p>
      <div className="sf-btns">
        <a className="btn btn-sm btn-map" href={window.gmSearch(dest + ' 맛집')} target="_blank" rel="noopener"><RI name="pin" />구글에서 보기</a>
        <a className="btn btn-sm btn-route" href={window.naverSearch(dest + ' 맛집')} target="_blank" rel="noopener"><RI name="nav" />네이버에서 보기</a>
      </div>
    </div>
  );
}

/* ---------- RESULT SCREEN ---------- */
function ResultScreen({ state, onPatch, onSave, onSavePlan, onSend }){
  const { people, conditions, meet, picks, memo, photos } = state;
  const together = state.tripMode === 'together';
  const [openR, setOpenR] = React.useState(null);
  const [provider, setProvider] = React.useState('google');
  const destQuery = (together ? state.trip.dest : (people.j.dest || people.s.dest)) || '영통역';
  const _t = new Date();
  const todayStr = _t.getFullYear() + '-' + String(_t.getMonth()+1).padStart(2,'0') + '-' + String(_t.getDate()).padStart(2,'0');
  const [now, setNow] = React.useState(new Date());
  React.useEffect(() => { const t = setInterval(() => setNow(new Date()), 1000); return () => clearInterval(t); }, []);
  let _h = now.getHours(); const _ampm = _h < 12 ? '오전' : '오후'; const _hh = (_h % 12) || 12;
  const nowDate = `오늘 ${now.getFullYear()}년 ${now.getMonth()+1}월 ${now.getDate()}일`;
  const nowTime = `${_ampm} ${_hh}시 ${String(now.getMinutes()).padStart(2,'0')}분 ${String(now.getSeconds()).padStart(2,'0')}초`;

  const ranked = window.RESTAURANTS
    .filter(r => r.cat === 'cond' && r.rating >= conditions.rating)
    .map(r => ({ r, s: window.scoreRestaurant(r, conditions.presets) }))
    .sort((a, b) => b.s - a.s)
    .slice(0, 4).map(x => x.r);

  const pocha = window.RESTAURANTS
    .filter(r => r.cat === 'pocha' && r.rating >= conditions.rating)
    .sort((a, b) => b.rating - a.rating)
    .slice(0, 4);

  const isYeongtong = /영통/.test(destQuery);
  const wantPocha = (conditions.extras || []).includes('pocha');

  // ----- 구글 실시간 검색 (키 있으면) · 8초 타임아웃 -----
  // status: 'idle' | 'loading' | 'ok' | 'fail' | 'nokey'
  const [live, setLive] = React.useState({ status:'idle', cond:[], pocha:[] });
  React.useEffect(() => {
    if (!window.GMAPS_KEY) { setLive({ status:'nokey', cond:[], pocha:[] }); return; }
    let cancelled = false;
    setLive({ status:'loading', cond:[], pocha:[] });
    const whenISO = meet.date ? (meet.date + 'T' + (meet.time || '19:00')) : null;
    const run = Promise.all([
      window.searchNear(destQuery, '술집 맛집', conditions.rating, 4, whenISO),
      wantPocha ? window.searchNear(destQuery, '실내포차 포장마차', conditions.rating, 4, whenISO) : Promise.resolve([])
    ]).then(([c, p]) => ({ c: Array.isArray(c) ? c : [], p: Array.isArray(p) ? p : [] }));
    const timeout = new Promise(r => setTimeout(() => r(null), 8000));
    Promise.race([run, timeout]).then(res => {
      if (cancelled) return;
      if (!res) { setLive({ status:'fail', cond:[], pocha:[] }); return; }
      setLive({ status:'ok', cond:res.c, pocha:res.p });
    }).catch(() => { if (!cancelled) setLive({ status:'fail', cond:[], pocha:[] }); });
    return () => { cancelled = true; };
  }, [destQuery, conditions.rating, wantPocha, meet.date, meet.time]);

  // ----- 네이버 탭: Netlify/CF 함수로 실데이터 -----
  // null = 로딩, {cond,pocha} = 응답(빈 배열 가능)
  const [naver, setNaver] = React.useState(null);
  React.useEffect(() => {
    if (provider !== 'naver') return;
    let cancelled = false;
    setNaver(null);
    Promise.all([
      window.searchNaver(destQuery + ' 술집 맛집', 4),
      wantPocha ? window.searchNaver(destQuery + ' 포차', 4) : Promise.resolve([])
    ]).then(([c, p]) => { if (!cancelled) setNaver({ cond:c || [], pocha:p || [] }); })
      .catch(() => { if (!cancelled) setNaver({ cond:[], pocha:[] }); });
    return () => { cancelled = true; };
  }, [provider, destQuery, wantPocha]);

  const naverActive = provider === 'naver';
  // 실제 위치 기반(실시간) 결과
  const naverCond  = naverActive && naver && naver.cond.length  ? naver.cond  : null;
  const naverPocha = naverActive && naver && naver.pocha.length ? naver.pocha : null;
  const liveCond  = (!naverActive && live.status === 'ok' && live.cond.length)  ? live.cond  : null;
  const livePocha = (!naverActive && live.status === 'ok' && live.pocha.length) ? live.pocha : null;

  const realCond  = naverCond  || liveCond;
  const realPocha = naverPocha || livePocha;
  const srcLabel  = naverCond ? '네이버' : (liveCond ? '구글 지도' : null);

  // 로딩 / 실패 판정
  const condLoading = naverActive ? (naver === null) : (live.status === 'loading' || live.status === 'idle');
  // 실시간이 없을 때: 영통이면 큐레이션, 아니면 직접검색 안내
  const showCurated = !realCond && !condLoading && isYeongtong;
  const showFallback = !realCond && !condLoading && !isYeongtong;

  const Grid = ({ list }) => (
    <div className="rest-grid">
      {list.map((r, i) => (
        <RestMini key={r.id} r={r} n={i+1} picked={picks.includes(r.id)} onOpen={(rr, n) => setOpenR({ r:rr, n })} onPick={togglePick} />
      ))}
    </div>
  );

  const fmtWhen = () => {
    if (!meet.date) return '날짜 미정';
    const dt = new Date(meet.date + 'T00:00:00');
    const days = ['일','월','화','수','목','금','토'];
    return `${dt.getMonth()+1}월 ${dt.getDate()}일 (${days[dt.getDay()]})` + (meet.time ? ' · ' + meet.time : '');
  };

  const togglePick = (id) => {
    const has = picks.includes(id);
    onPatch({ picks: has ? picks.filter(p => p !== id) : [...picks, id] });
  };

  return (
    <div className="fadein">
      <div className="result-hero">
        <MonsteraLeaf className="leaf" />
        <Weather place={destQuery} date={todayStr} tag="오늘" />
        <div className="hero-head">
          <CoupleMark size={46} />
          <div className="hero-now">
            <span className="hn-date">{nowDate}</span>
            <span className="hn-time">{nowTime}</span>
          </div>
        </div>
        <div className="script" style={{ fontSize:'1.5rem' }}>우리, 여기 어때?</div>
        <h2>{destQuery}에서 보낼<br/>오늘 데이트를 골라봤어 💚</h2>
        <div className="when-row">
          <div className="when"><RI name="calendar" />{fmtWhen()}</div>
          <WeatherInline place={destQuery} date={meet.date} />
        </div>
      </div>

      {/* 경로 */}
      <div className="block-title">
        <span className="ic"><RI name="route" /></span>
        <h3>우리 가는 길</h3>
        <span className="count">{together ? '한 차로 함께' : '둘이'}</span>
      </div>
      {together ? (
        <RouteCard person={{ key:'couple', name:'우리', start:state.trip.start, waypoint:state.trip.waypoint, waypointNone:state.trip.waypointNone, dest:state.trip.dest, home:'', mode:state.trip.mode }}
          onModeChange={(m) => onPatch({ trip: { ...state.trip, mode:m } })} />
      ) : (
        <React.Fragment>
          <RouteCard person={people.j} onModeChange={(m) => onPatch({ people: { ...people, j: { ...people.j, mode:m } } })} />
          <RouteCard person={people.s} onModeChange={(m) => onPatch({ people: { ...people, s: { ...people.s, mode:m } } })} />
        </React.Fragment>
      )}

      {/* 지도 */}
      <div className="block-title">
        <span className="ic"><RI name="map" /></span>
        <h3>우리 만나는 곳</h3>
      </div>
      <div className="map-embed">
        <iframe loading="lazy" referrerPolicy="no-referrer-when-downgrade" src={window.gmEmbed(destQuery)}></iframe>
      </div>

      <div className="prov-row">
        <div className="prov-tabs">
          <button className={provider === 'google' ? 'on' : ''} onClick={() => setProvider('google')}>구글</button>
          <button className={provider === 'naver' ? 'on' : ''} onClick={() => setProvider('naver')}>네이버</button>
        </div>
        <a className="prov-search" href={provider === 'naver' ? window.naverSearch(destQuery + ' 맛집') : window.gmSearch(destQuery + ' 맛집')} target="_blank" rel="noopener">
          {provider === 'naver' ? '네이버' : '구글'}에서 전체 검색<RI name="arrowR" />
        </a>
      </div>

      {/* 조건 맞춤 맛집 */}
      <div className="block-title">
        <span className="ic"><RI name="utensils" /></span>
        <h3>우리 취향 맛집</h3>
        {realCond && <span className="count">{realCond.length}곳 · {conditions.rating.toFixed(1)}★+</span>}
      </div>
      {condLoading ? (
        <p className="live-note"><RI name="pin" />{destQuery} 주변을 찾는 중이야…</p>
      ) : realCond ? (
        <React.Fragment>
          <p className="live-note"><RI name="pin" />{srcLabel} 실시간 검색 결과예요</p>
          <Grid list={realCond} />
        </React.Fragment>
      ) : showCurated ? (
        <React.Fragment>
          <p className="live-note"><RI name="pin" />영통 추천 (오프라인 샘플)</p>
          <Grid list={ranked} />
        </React.Fragment>
      ) : (
        <SearchFallback dest={destQuery} />
      )}

      {/* 실내 포차 */}
      {wantPocha && (realPocha || showCurated) && (
        <React.Fragment>
          <div className="block-title">
            <span className="ic"><RI name="sparkle" /></span>
            <h3>분위기 실내 포차</h3>
            <span className="count">{(realPocha || pocha).length}곳</span>
          </div>
          <Grid list={realPocha || pocha} />
        </React.Fragment>
      )}

      {/* 메모 */}
      <div className="block-title">
        <span className="ic"><RI name="edit" /></span>
        <h3>우리 메모</h3>
      </div>
      <div className="memo">
        <textarea placeholder="예) 7시 1번 출구에서 만나기 💕 / 2차는 포차 / 소정이 매운 거 잘 못 먹음"
          value={memo} onChange={e => onPatch({ memo:e.target.value })}></textarea>
      </div>

      {/* 사진 */}
      <div className="block-title">
        <span className="ic"><RI name="camera" /></span>
        <h3>추억 사진</h3>
        <span className="count">{photos.length}장</span>
      </div>
      <PhotoUploader photos={photos}
        onAdd={src => onPatch({ photos:[...photos, { src, cap:'' }] })}
        onRemove={i => onPatch({ photos: photos.filter((_, idx) => idx !== i) })}
        onCaption={(i, text) => onPatch({ photos: photos.map((p, idx) => idx === i ? { src:window.photoSrc(p), cap:text } : p) })} />
      {photos.length > 0 && <p className="map-note" style={{ marginTop:8 }}>사진마다 캡션을 달면 추억 상세에서 슬라이드로 보여요 📸</p>}

      {/* API 안내 */}
      <ApiGuide />

      {/* 저장 */}
      <div className="save-strip">
        {onSend && (
          <button className="btn btn-ghost btn-full" style={{ marginBottom:9 }} onClick={onSend}>
            <RI name="nav" />상대에게 “여기 어때?” 보내기 💌
          </button>
        )}
        <div style={{ display:'flex', gap:9 }}>
          <button className="btn btn-ghost" style={{ flex:1 }} onClick={onSavePlan}>
            <RI name="calendar" />플랜 저장 📅
          </button>
          <button className="btn btn-primary" style={{ flex:1 }} onClick={onSave}>
            <RI name="bookmark" />추억 저장 💕
          </button>
        </div>
        <p className="map-note" style={{ marginTop:10 }}>
          <b>플랜</b>은 다가올 약속으로, <b>추억</b>은 다녀온 날로 달력에 콕 찍혀 :)
        </p>
      </div>

      <RestDetailSheet item={openR} provider={provider} picked={openR ? picks.includes(openR.r.id) : false}
        onClose={() => setOpenR(null)} onPick={togglePick} />
    </div>
  );
}

Object.assign(window, { RouteCard, RestaurantCard, ApiGuide, ResultScreen });
