// Trip Planner — date entry → drag/drop schedule → AI taste prompt → globe path

const RECOS_INITIAL = [
{ id: 'r1', name: 'Achaia Clauss Winery', kind: 'Vineyard', dist: '14 km', dur: '2 hrs', tone: 'olive', icon: '◐', lat: 38.1925, lng: 21.7717 },
{ id: 'r2', name: 'Kalogria Beach', kind: 'Beach', dist: '32 km', dur: '½ day', tone: 'aegean', icon: '≈', lat: 38.1599, lng: 21.3736 },
{ id: 'r3', name: 'Ancient Olympia', kind: 'Ruins', dist: '85 km', dur: 'Full day', tone: 'ochre', icon: '◊', lat: 37.6386, lng: 21.6300 },
{ id: 'r4', name: 'Rio-Antirrio Bridge', kind: 'Vista', dist: '8 km', dur: '1 hr', tone: 'aegean', icon: '⌒', lat: 38.3222, lng: 21.7733 },
{ id: 'r5', name: 'Mega Spilaio', kind: 'Monastery', dist: '54 km', dur: '½ day', tone: 'olive', icon: '△', lat: 38.0750, lng: 22.1817 },
{ id: 'r6', name: 'Psarofagos Taverna', kind: 'Seafood', dist: '6 km', dur: '2 hrs', tone: 'terracotta', icon: '✦', lat: 38.2500, lng: 21.7350 }];


const VENUE = { lat: 38.2828, lng: 21.8983, name: 'Ktima Panagiotopoulou', address: 'Palea EO Korinthou Patron, Lampiri 250 09' };
const ATH = { lat: 37.9364, lng: 23.9445, name: 'Athens Airport (ATH)' };
const RECO_BY_NAME = (name, recos) => (recos || RECOS_INITIAL).find(r => r.name === name);

// time helpers
const addMinutes = (hhmm, mins) => {
  const [h, m] = hhmm.split(':').map(Number);
  const total = h * 60 + m + mins;
  const nh = Math.floor((total % (24 * 60) + 24 * 60) % (24 * 60) / 60);
  const nm = ((total % 60) + 60) % 60;
  return `${String(nh).padStart(2, '0')}:${String(nm).padStart(2, '0')}`;
};
const subtractMinutes = (hhmm, mins) => addMinutes(hhmm, -mins);
const kindIcon = (k) => ({
  flight: '✈',
  car: '⌖',
  checkin: '⌂',
  checkout: '⌂',
}[k] || '·');
const haversine = (lat1, lon1, lat2, lon2) => {
  const R = 6371;
  const dLat = (lat2 - lat1) * Math.PI / 180;
  const dLon = (lon2 - lon1) * Math.PI / 180;
  const a = Math.sin(dLat/2)**2 + Math.cos(lat1*Math.PI/180) * Math.cos(lat2*Math.PI/180) * Math.sin(dLon/2)**2;
  return 2 * R * Math.asin(Math.sqrt(a));
};


const Plan = () => {
  const [arrival, setArrival] = React.useState('');
  const [departure, setDeparture] = React.useState('');
  const [arrivalTime, setArrivalTime] = React.useState('14:00');
  const [departureTime, setDepartureTime] = React.useState('11:00');
  const [confirmed, setConfirmed] = React.useState(false);
  const [days, setDays] = React.useState([]);
  const [itinerary, setItinerary] = React.useState({});
  const [recos, setRecos] = React.useState(RECOS_INITIAL);
  const [tastePrompt, setTastePrompt] = React.useState('');
  const [aiLoading, setAiLoading] = React.useState(false);
  const [aiError, setAiError] = React.useState(null);
  const [dragData, setDragData] = React.useState(null);
  const [overDay, setOverDay] = React.useState(null);
  const [showGlobe, setShowGlobe] = React.useState(false);
  const [expanded, setExpanded] = React.useState(null);   // currently-expanded reco

  const buildDays = () => {
    if (!arrival || !departure) return;
    const start = new Date(arrival);
    const end = new Date(departure);
    if (end < start) return;
    const list = [];
    const init = {};
    let cur = new Date(start);
    const arrivalKey = new Date(start).toISOString().slice(0, 10);
    const departureKey = new Date(end).toISOString().slice(0, 10);

    while (cur <= end) {
      const key = cur.toISOString().slice(0, 10);
      const dt = new Date(cur);
      const isWedding = key === '2026-08-28';
      const isArrival = key === arrivalKey;
      const isDeparture = key === departureKey;
      const labels = [];
      if (isArrival) labels.push('Arrive');
      if (isDeparture) labels.push('Depart');
      if (isWedding) labels.push('Wedding');
      list.push({
        date: key,
        label: dt.toLocaleDateString('en', { weekday: 'short', day: 'numeric' }),
        sub: labels.length ? labels.join(' · ') : dt.toLocaleDateString('en', { month: 'short' }),
        highlight: isWedding,
        isArrival, isDeparture,
      });

      const items = [];
      if (isArrival) {
        const arrTime = arrivalTime || '14:00';
        const pickupTime = addMinutes(arrTime, 60);
        const checkinTime = addMinutes(arrTime, 220);
        items.push({ id: `arr-fly-${key}`, label: 'Land at Athens Airport (ATH)', time: arrTime, tag: 'travel', locked: false, kind: 'flight', editable: true });
        items.push({ id: `arr-car-${key}`, label: 'Rental car pickup · drive to Patras (~2h 15)', time: pickupTime, tag: 'travel', locked: false, kind: 'car', editable: true });
        items.push({ id: `arr-in-${key}`, label: 'Hotel check-in', time: checkinTime, tag: 'stay', locked: false, kind: 'checkin', editable: true });
      }
      if (isWedding) {
        items.push({ id: 'lock1', label: 'Ceremony — Ktima Panagiotopoulou', time: '19:00', tag: 'event', locked: true });
        items.push({ id: 'lock2', label: 'Cocktail hour', time: '19:30', tag: 'event', locked: true });
        items.push({ id: 'lock3', label: 'Reception & dinner', time: '21:30', tag: 'event', locked: true });
        items.push({ id: 'lock4', label: 'Dancing under the olive trees', time: '23:30', tag: 'event', locked: true });
      }
      // Thursday before the wedding — pre-populated group beach day.
      if (key === '2026-08-27') {
        items.push({
          id: `pre-beach-${key}`,
          label: 'Beach day · La Mer, Kalogria Beach',
          time: '13:00',
          tag: 'plan',
          tone: 'aegean',
          editable: true,
          lat: 38.1599,
          lng: 21.3736,
        });
      }
      if (isDeparture) {
        const depTime = departureTime || '11:00';
        const checkoutTime = subtractMinutes(depTime, 240);
        const driveTime = subtractMinutes(depTime, 210);
        items.push({ id: `dep-out-${key}`, label: 'Hotel check-out', time: checkoutTime, tag: 'stay', locked: false, kind: 'checkout', editable: true });
        items.push({ id: `dep-car-${key}`, label: 'Drive to Athens Airport (~2h 15)', time: driveTime, tag: 'travel', locked: false, kind: 'car', editable: true });
        items.push({ id: `dep-fly-${key}`, label: 'Departure flight from ATH', time: depTime, tag: 'travel', locked: false, kind: 'flight', editable: true });
      }
      init[key] = items;
      cur.setDate(cur.getDate() + 1);
    }
    setDays(list);
    setItinerary(init);
    setConfirmed(true);
  };

  const onDragStart = (r) => setDragData(r);
  const onDrop = (e, day) => {
    e.preventDefault();
    if (!dragData) return;
    setItinerary((p) => ({
      ...p,
      [day]: [...(p[day] || []), {
        id: `${dragData.id}-${Date.now()}`,
        label: dragData.name, time: 'flex', tag: 'plan', tone: dragData.tone,
        editable: true,
        lat: dragData.lat, lng: dragData.lng,
      }]
    }));
    setDragData(null);
    setOverDay(null);
  };
  const removeItem = (day, id) => {
    setItinerary((p) => ({ ...p, [day]: p[day].filter((i) => i.id !== id || i.locked) }));
  };
  const updateItemTime = (day, id, time) => {
    setItinerary((p) => ({
      ...p,
      [day]: p[day].map(i => i.id === id ? { ...i, time } : i),
    }));
  };

  const askAI = async () => {
    const query = tastePrompt.trim();
    if (!query || aiLoading) return;
    setAiLoading(true);
    setAiError(null);
    try {
      const res = await fetch('/api/plan/search', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({ query }),
      });
      const payload = await res.json().catch(() => ({}));
      if (!res.ok || !payload.ok) throw new Error(payload.error || `Server error (${res.status})`);
      const places = (payload.places || []).map((p, i) => ({
        ...p,
        id: `ai-${Date.now()}-${i}`,
        ai: true,
      }));
      if (!places.length) {
        setAiError('No matches found — try a different angle (e.g. "natural wine bars", "ancient ruins half-day").');
      } else {
        setRecos(places);
      }
    } catch (e) {
      setAiError(e.message || 'Search failed — please try again.');
    } finally {
      setAiLoading(false);
    }
  };

  const totalStops = Object.values(itinerary).reduce((s, a) => s + a.length, 0);
  const allRecos = recos;

  return (
    <section className="section plan-section" id="plan" style={{ textAlign: "center" }}>
      <div className="section-head">
        <div>
          <div className="eyebrow" style={{ marginBottom: 12 }}>03 — Trip Planner</div>
          <h2 className="title">Build Your <em>Journey</em></h2>
        </div>
        <div className="meta">{confirmed ? `${days.length} days · ${totalStops} stops` : 'Pick your dates to begin'}</div>
      </div>

      {!confirmed ?
      <div className="plan-dates glass" style={{ padding: "40px", maxWidth: "600px", width: "100%", margin: "0 auto", fontWeight: "300", textAlign: "center" }}>
          <div style={{ textAlign: "center" }}>
            <span className="eyebrow">When are you with us?</span>
            <h3 className="serif" style={{ fontSize: 32, fontStyle: 'italic', margin: '8px 0 18px' }}>
              Tell us your travel window
            </h3>
            <p style={{ color: 'var(--ink-soft)', maxWidth: 460, margin: 0, textAlign: "justify" }}>
              We'll build a draggable schedule for those exact days, then you can fill it
              with curated places — or describe your taste and let our AI concierge propose a fresh set.
            </p>
          </div>
          <div className="date-fields">
            <div className="date-row">
              <label>
                <span className="field-label">Arrival date</span>
                <input type="date" className="field-input" value={arrival} onChange={(e) => setArrival(e.target.value)} min="2026-08-22" max="2026-09-05" />
              </label>
              <label>
                <span className="field-label">Flight lands at ATH</span>
                <input type="time" className="field-input" value={arrivalTime} onChange={(e) => setArrivalTime(e.target.value)} />
              </label>
            </div>
            <div className="date-row">
              <label>
                <span className="field-label">Departure date</span>
                <input type="date" className="field-input" value={departure} onChange={(e) => setDeparture(e.target.value)} min="2026-08-22" max="2026-09-05" />
              </label>
              <label>
                <span className="field-label">Flight leaves ATH</span>
                <input type="time" className="field-input" value={departureTime} onChange={(e) => setDepartureTime(e.target.value)} />
              </label>
            </div>
            <div className="date-hint mono">
              Check-in / check-out and the ~2h 15min drive between Athens and Patras will be auto-scheduled. You can edit any time after.
            </div>
            <button className="btn" onClick={buildDays} disabled={!arrival || !departure}>Build my schedule →</button>
          </div>
        </div> :

      <>
          <div className="plan-grid">
            {/* Recos + AI prompt */}
            <div className="bento">
              <div className="bento-header">
                <span className="eyebrow">{recos[0]?.ai ? 'Curated for you' : 'Around Patras'}</span>
                <button className="link-btn" onClick={() => {setRecos(RECOS_INITIAL);setTastePrompt('');}}>
                  {recos[0]?.ai ? '← back to defaults' : ''}
                </button>
              </div>

              <div className="ai-prompt">
                <span className="eyebrow">AI Concierge</span>
                <p className="ai-intro">Describe what you love — a quiet beach, a natural-wine bar, ancient ruins, a specific place by name — and Haiku will search the web and surface real spots near Patras.
              </p>
                <div className="ai-row">
                  <input
                  className="field-input"
                  placeholder="e.g. quiet beach, Mostra Cafe Patras, natural wine, Voidokilia"
                  value={tastePrompt}
                  onChange={(e) => setTastePrompt(e.target.value)}
                  onKeyDown={(e) => e.key === 'Enter' && askAI()} style={{ margin: "0px 0px 4px" }} />

                  <button className="btn" onClick={askAI} disabled={aiLoading || !tastePrompt.trim()}>
                    {aiLoading ? 'Searching…' : 'Search →'}
                  </button>
                </div>
                {aiError && (
                  <p className="mono" style={{ fontSize: 10, color: '#b13b3b', letterSpacing: '0.08em', marginTop: 8 }}>
                    {aiError}
                  </p>
                )}
              </div>

              <div className="bento-cards">
                {allRecos.map((r, i) =>
              <div
                key={r.id}
                className={`reco reco-${r.tone || 'olive'}`}
                draggable
                onDragStart={() => onDragStart(r)}
                onDragEnd={() => {setDragData(null);setOverDay(null);}}
                onClick={() => setExpanded(r)}>

                    <div className="reco-top">
                      <div className="reco-glyph">{r.icon}</div>
                      <div className="reco-kind eyebrow">{r.kind}</div>
                      {r.ai && <span className="ai-tag mono">AI</span>}
                      {r.custom && <span className="ai-tag mono custom-tag">YOURS</span>}
                      <button
                        type="button"
                        className="reco-expand"
                        aria-label={`More about ${r.name}`}
                        onClick={(e) => { e.stopPropagation(); setExpanded(r); }}
                        title="Details"
                      >ⓘ</button>
                    </div>
                    <h3 className="reco-name">{r.name}</h3>
                    <div className="reco-foot">
                      <span className="mono">{r.dist}</span>
                      <span className="reco-dot">·</span>
                      <span className="mono">{r.dur}</span>
                      <span className="drag-hint">⋮⋮ drag</span>
                    </div>
                  </div>
              )}
              </div>
            </div>

            <div className="calendar">
              <div className="cal-header">
                <span className="eyebrow">Your Itinerary</span>
                <span className="mono" style={{ fontSize: 10, color: 'var(--ink-mute)' }}>
                  {arrival} → {departure}
                </span>
              </div>

              <div className="cal-days">
                {days.map((d) =>
              <div
                key={d.date}
                className={`cal-day ${d.highlight ? 'cal-day-highlight' : ''} ${overDay === d.date ? 'cal-day-over' : ''}`}
                onDragOver={(e) => {e.preventDefault();setOverDay(d.date);}}
                onDragLeave={() => setOverDay(null)}
                onDrop={(e) => onDrop(e, d.date)}>
                
                    <div className="cal-day-head">
                      <div>
                        <div className="cal-day-num">{d.label}</div>
                        <div className="cal-day-sub">{d.sub}</div>
                      </div>
                      {d.highlight && <span className="cal-pin">✶</span>}
                    </div>
                    <div className="cal-items">
                      {(itinerary[d.date] || []).map((item) =>
                  <div key={item.id} className={`cal-item cal-item-${item.tag} cal-kind-${item.kind || 'std'} ${item.locked ? 'locked' : ''}`}>
                          {item.kind && <span className="ci-icon">{kindIcon(item.kind)}</span>}
                          {item.editable && !item.locked ? (
                            <input
                              type="time"
                              className="ci-time-input mono"
                              value={item.time}
                              onChange={(e) => updateItemTime(d.date, item.id, e.target.value)}
                            />
                          ) : (
                            <span className="ci-time mono">{item.time}</span>
                          )}
                          <span className="ci-label">{item.label}</span>
                          {!item.locked &&
                    <button className="ci-rm" onClick={() => removeItem(d.date, item.id)}>×</button>
                    }
                        </div>
                  )}
                      {(!itinerary[d.date] || itinerary[d.date].length === 0) &&
                  <div className="cal-empty">— drop here —</div>
                  }
                    </div>
                  </div>
              )}
              </div>

              <div className="cal-summary">
                <div>
                  <span className="eyebrow">Total stops</span>
                  <div className="serif" style={{ fontSize: 28 }}>{totalStops}</div>
                </div>
                <button className="btn btn-soft" onClick={() => setConfirmed(false)}>← Edit dates</button>
                <button className="btn" onClick={() => setShowGlobe(true)}>Confirm trip →</button>
              </div>
            </div>
          </div>

          {showGlobe && <Globe days={days} itinerary={itinerary} allRecos={allRecos} onClose={() => setShowGlobe(false)} />}
        </>
      }
      {expanded && <RecoExpand reco={expanded} onClose={() => setExpanded(null)} />}
    </section>);

};

const RecoExpand = ({ reco, onClose }) => {
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [onClose]);

  const contact = reco.contact || '';
  const isUrl = /^https?:\/\//i.test(contact);
  const mapsUrl = `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(reco.name + ' Patras Greece')}`;

  return (
    <div className="reco-overlay" onClick={onClose}>
      <div className={`reco-modal reco-${reco.tone || 'olive'}`} onClick={(e) => e.stopPropagation()}>
        <button className="reco-close" onClick={onClose} aria-label="Close">×</button>

        {reco.image_url ? (
          <div className="reco-hero">
            <img src={reco.image_url} alt={reco.name} onError={(e) => { e.currentTarget.parentNode.style.display = 'none'; }} />
          </div>
        ) : null}

        <div className="reco-modal-body">
          <div className="reco-modal-top">
            <span className="reco-glyph">{reco.icon}</span>
            <span className="eyebrow">{reco.kind}</span>
            {reco.ai && <span className="ai-tag mono">AI</span>}
          </div>
          <h2 className="serif" style={{ fontStyle: 'italic', fontSize: 38, lineHeight: 1.1, color: 'var(--accent)', margin: '8px 0 14px' }}>
            {reco.name}
          </h2>

          {reco.description && (
            <p style={{ fontSize: 15, color: 'var(--ink-soft)', lineHeight: 1.6, margin: '0 0 18px' }}>
              {reco.description}
            </p>
          )}

          <dl className="reco-facts">
            <div><dt>Distance to venue</dt><dd className="mono">{reco.dist}</dd></div>
            {reco.opening_hours && <div><dt>Hours</dt><dd>{reco.opening_hours}</dd></div>}
            {contact && (
              <div>
                <dt>Contact</dt>
                <dd>{isUrl
                  ? <a href={contact} target="_blank" rel="noopener noreferrer">{contact.replace(/^https?:\/\//, '').replace(/\/$/, '')}</a>
                  : <a href={`tel:${contact.replace(/\s+/g, '')}`}>{contact}</a>}
                </dd>
              </div>
            )}
          </dl>

          <div className="reco-modal-actions">
            <a className="btn btn-soft" href={mapsUrl} target="_blank" rel="noopener noreferrer">Open in Maps ↗</a>
            {reco.url && (
              <a className="btn btn-soft" href={reco.url} target="_blank" rel="noopener noreferrer">Source ↗</a>
            )}
            <p className="mono" style={{ fontSize: 10, letterSpacing: '0.18em', color: 'var(--ink-mute)', margin: 0, alignSelf: 'center' }}>
              ⋮⋮ Drag the card into a day to add
            </p>
          </div>
        </div>
      </div>
    </div>
  );
};

const Globe = ({ days, itinerary, allRecos, onClose }) => {
  const mapRef = React.useRef(null);
  const mapInst = React.useRef(null);

  const stops = [];
  days.forEach((d) => {
    (itinerary[d.date] || []).forEach((item) => {
      const reco = RECO_BY_NAME(item.label, allRecos);
      let lat = reco?.lat ?? item.lat ?? VENUE.lat;
      let lng = reco?.lng ?? item.lng ?? VENUE.lng;
      // Travel items pinned to ATH if mentioned
      if (item.kind === 'flight' || (item.label && item.label.includes('Athens Airport'))) {
        lat = ATH.lat; lng = ATH.lng;
      } else if (item.kind === 'checkin' || item.kind === 'checkout' || item.locked || item.kind === 'car') {
        lat = VENUE.lat; lng = VENUE.lng;
      }
      stops.push({
        day: d.label,
        label: item.label,
        time: item.time,
        locked: !!item.locked,
        kind: item.kind,
        lat, lng,
        isVenue: item.kind === 'checkin' || item.kind === 'checkout' || !!item.locked,
        isATH: item.kind === 'flight' || (item.label && item.label.includes('Athens Airport')),
      });
    });
  });

  const realStops = stops.filter(s => !s.isVenue && !s.isATH);
  const hasATH = stops.some(s => s.isATH);

  // Build the path: ATH (if arriving) → venue → stops → venue → ATH (if departing)
  const pathPoints = [];
  if (hasATH) pathPoints.push({ ...ATH, label: ATH.name, isATH: true });
  pathPoints.push({ ...VENUE, label: VENUE.name, isVenue: true });
  realStops.forEach(s => pathPoints.push(s));
  pathPoints.push({ ...VENUE, label: VENUE.name, isVenue: true });
  if (hasATH) pathPoints.push({ ...ATH, label: ATH.name, isATH: true });

  React.useEffect(() => {
    if (!window.L || !mapRef.current) return;
    if (mapInst.current) return;

    const L = window.L;
    const map = L.map(mapRef.current, {
      zoomControl: true,
      scrollWheelZoom: false,
      attributionControl: true,
    });
    mapInst.current = map;

    // Stadia Stamen Watercolor-like; fallback to clean CartoDB Voyager (works without key, matches palette)
    L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png', {
      attribution: '&copy; OpenStreetMap &copy; CARTO',
      subdomains: 'abcd',
      maxZoom: 19,
    }).addTo(map);

    // Venue marker — distinct
    const venueIcon = L.divIcon({
      className: 'map-venue-pin',
      html: '<div class="vp-ring"></div><div class="vp-dot">✶</div>',
      iconSize: [44, 44],
      iconAnchor: [22, 22],
    });
    L.marker([VENUE.lat, VENUE.lng], { icon: venueIcon, zIndexOffset: 1000 })
      .addTo(map)
      .bindPopup(`<strong>${VENUE.name}</strong><br/><span style="font-size:11px;letter-spacing:0.12em;text-transform:uppercase;color:#888;">Wedding venue</span>`);

    // ATH marker — distinct
    if (hasATH) {
      const athIcon = L.divIcon({
        className: 'map-ath-pin',
        html: '<div class="ath-dot">✈</div>',
        iconSize: [36, 36],
        iconAnchor: [18, 18],
      });
      L.marker([ATH.lat, ATH.lng], { icon: athIcon, zIndexOffset: 900 })
        .addTo(map)
        .bindPopup(`<strong>${ATH.name}</strong><br/><span style="font-size:11px;letter-spacing:0.12em;text-transform:uppercase;color:#888;">Arrival / departure</span>`);
    }

    // Stop markers — only real stops (not venue / not ATH)
    realStops.forEach((s, i) => {
      const icon = L.divIcon({
        className: 'map-stop-pin',
        html: `<div class="sp-num">${i + 1}</div>`,
        iconSize: [32, 32],
        iconAnchor: [16, 16],
      });
      L.marker([s.lat, s.lng], { icon })
        .addTo(map)
        .bindPopup(`<strong>${s.label}</strong><br/><span style="font-size:11px;letter-spacing:0.12em;text-transform:uppercase;color:#888;">${s.day} · ${s.time}</span>`);
    });

    // Path connecting them
    if (pathPoints.length > 1) {
      const latlngs = pathPoints.map(p => [p.lat, p.lng]);
      L.polyline(latlngs, {
        color: '#7a8a5c',
        weight: 3,
        opacity: 0.85,
        dashArray: '6 8',
        lineCap: 'round',
        lineJoin: 'round',
      }).addTo(map);
    }

    // Fit bounds
    const allPoints = [[VENUE.lat, VENUE.lng], ...realStops.map(s => [s.lat, s.lng])];
    if (hasATH) allPoints.push([ATH.lat, ATH.lng]);
    if (allPoints.length > 1) {
      map.fitBounds(allPoints, { padding: [60, 60] });
    } else {
      map.setView([VENUE.lat, VENUE.lng], 11);
    }

    // Fix sizing after modal animation
    setTimeout(() => map.invalidateSize(), 250);

    return () => { map.remove(); mapInst.current = null; };
  }, []);

  return (
    <div className="globe-overlay" onClick={onClose}>
      <div className="map-shell" onClick={(e) => e.stopPropagation()}>
        <button className="reco-close" onClick={onClose} aria-label="Close">×</button>

        <div className="map-head">
          <span className="eyebrow">Your Confirmed Journey</span>
          <h3 className="map-title">
            {realStops.length} {realStops.length === 1 ? 'stop' : 'stops'} around <em>Patras</em>
          </h3>
          <div className="map-meta mono">
            {days[0]?.label} → {days[days.length - 1]?.label} · {days.length} days
          </div>
        </div>

        <div className="map-body">
          <div ref={mapRef} className="map-canvas" />

          <aside className="map-list">
            <div className="map-list-head">
              <span className="eyebrow">Itinerary</span>
              <span className="mono" style={{ fontSize: 10, color: 'var(--ink-mute)' }}>
                {pathPoints.length} pins
              </span>
            </div>

            {hasATH && (
              <div className="map-stop map-stop-ath">
                <span className="ms-pin ms-pin-ath">✈</span>
                <div className="ms-info">
                  <span className="ms-label">{ATH.name}</span>
                  <span className="ms-sub mono">Arrival / departure point</span>
                </div>
              </div>
            )}

            <div className="map-stop map-stop-venue">
              <span className="ms-pin">✶</span>
              <div className="ms-info">
                <span className="ms-label">{VENUE.name}</span>
                <span className="ms-sub mono">Wedding venue · base</span>
              </div>
            </div>

            {realStops.map((s, i) => (
              <div key={i} className="map-stop">
                <span className="ms-pin ms-pin-num">{i + 1}</span>
                <div className="ms-info">
                  <span className="ms-label">{s.label}</span>
                  <span className="ms-sub mono">{s.day} · {s.time}</span>
                </div>
              </div>
            ))}

            {realStops.length === 0 && (
              <div className="map-empty">
                <span>Your map is the airport, venue and back — add stops from the panel and they'll appear here.</span>
              </div>
            )}
          </aside>
        </div>
      </div>
    </div>);

};

window.Plan = Plan;