// =====================================================================
// FieldMap — top-level component.
// Composes the topographic basemap, pins, hover lens, and the detail
// panel that appears below the map.
// =====================================================================

function FieldMap() {
  const pins = window.FieldMapPins || [];
  const [activeId, setActiveId] = React.useState(null);
  const [hoverId, setHoverId] = React.useState(null);
  const [touchStartX, setTouchStartX] = React.useState(null);
  const stageRef = React.useRef(null);

  const active = pins.find((p) => p.id === activeId) || null;
  const hover = pins.find((p) => p.id === hoverId) || null;

  function navTo(dir) {
    const i = activeId ? pins.findIndex(p => p.id === activeId) : -1;
    const next = (i + dir + pins.length) % pins.length;
    setActiveId(pins[next].id);
  }

  // Keyboard nav: ←/→ jump between pins, Esc closes.
  React.useEffect(() => {
    function onKey(e) {
      if (document.querySelector('.map-lightbox')) return;
      if (e.key === 'Escape') {setActiveId(null);return;}
      if (!active) return;
      if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') {
        e.preventDefault();
        navTo(e.key === 'ArrowRight' ? 1 : -1);
      }
    }
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [active, pins]);

  // Scroll panel into view when opening a pin.
  React.useEffect(() => {
    if (!active) return;
    const panel = document.querySelector('.field-map-panel');
    if (!panel) return;
    const r = panel.getBoundingClientRect();
    if (r.bottom > window.innerHeight) {
      window.scrollBy({ top: r.bottom - window.innerHeight + 32, behavior: 'smooth' });
    }
  }, [active && active.id]);

  // Swipe handlers on the map stage.
  function onTouchStart(e) { setTouchStartX(e.touches[0].clientX); }
  function onTouchEnd(e) {
    if (touchStartX === null) return;
    const diff = e.changedTouches[0].clientX - touchStartX;
    setTouchStartX(null);
    if (Math.abs(diff) < 40) return;
    navTo(diff < 0 ? 1 : -1);
  }

  return (
    <div className="field-map">
      <div className="field-map-head">
        <h3 data-i18n="map.title">Field, <span className="it">beyond the research.</span></h3>
        <div className="legend">
          <span className="swatch"><span className="dot"></span> <span data-i18n="map.legend.site">Village / Site</span></span>
          <span className="swatch"><span className="tri"></span> <span data-i18n="map.legend.pass">Mountain Pass</span></span>
        </div>
      </div>

      <div className="field-map-stage" ref={stageRef}
        onTouchStart={onTouchStart}
        onTouchEnd={onTouchEnd}>
        <window.FieldMapBasemap />

        <div className="field-map-overlay">
          {pins.map((p) => {
            const { left, top } = window.projectToPercent(p.lat, p.lon);
            return (
              <button key={p.id}
              className={`field-map-pin ${active && active.id === p.id ? 'is-active' : ''}`}
              style={{ left: `${left}%`, top: `${top}%` }}
              data-kind={p.kind}
              data-name-align={p.nameAlign || 'right'}
              aria-label={`${p.name} — ${p.kind === 'pass' ? 'mountain pass' : 'field site'} at ${p.altitude}`}
              aria-pressed={active && active.id === p.id}
              onMouseEnter={() => setHoverId(p.id)}
              onMouseLeave={() => setHoverId((h) => h === p.id ? null : h)}
              onFocus={() => setHoverId(p.id)}
              onBlur={() => setHoverId((h) => h === p.id ? null : h)}
              onClick={() => setActiveId((id) => id === p.id ? null : p.id)}>
                <span className="glyph" aria-hidden="true">
                  {p.kind === 'pass' ?
                  <span className="tri"></span> :
                  <span className="dot"></span>}
                </span>
                <span className="name">{p.name}</span>
              </button>);
          })}

          {hover && (!active || active.id !== hover.id) &&
          <HoverLens pin={hover} />
          }
        </div>

        <div className="field-map-cartouche">
          <span className="t">Ladakh</span>
          Fieldwork Atlas
          <span className="l">N 33°30′ — 35°00′<br />E 76°30′ — 79°30′</span>
        </div>
      </div>

      {/* Mobile prev/next arrows — hidden on desktop */}
      <div className="field-map-mobile-nav">
        <button className="fm-arrow" onClick={() => navTo(-1)} aria-label="Previous site">←</button>
        <span className="fm-current">{active ? active.name : 'Tap a pin or swipe'}</span>
        <button className="fm-arrow" onClick={() => navTo(1)} aria-label="Next site">→</button>
      </div>

      {/* Pin navigator strip — desktop only */}
      <div className="field-map-nav" role="tablist">
        {pins.map((p) =>
        <button key={p.id}
        role="tab"
        data-kind={p.kind}
        aria-selected={active && active.id === p.id}
        className={active && active.id === p.id ? 'is-active' : ''}
        onClick={() => setActiveId((id) => id === p.id ? null : p.id)}>
            <span className="marker" aria-hidden="true"></span>
            {p.name}
          </button>
        )}
      </div>

      {/* Detail panel */}
      <DetailPanel pin={active} onClose={() => setActiveId(null)} />
    </div>);
}

function HoverLens({ pin }) {
  const { left, top } = window.projectToPercent(pin.lat, pin.lon);
  // Position the lens above the pin; flip below when near the top edge.
  const flipBelow = top < 22;
  return (
    <div className="field-map-lens"
    style={{
      left: `${left}%`,
      top: `${top}%`,
      transform: flipBelow ?
      'translate(-50%, 28px)' :
      'translate(-50%, calc(-100% - 18px))'
    }}>
      <div className="lens-name">{pin.name}</div>
      <div className="lens-meta">
        {pin.kind === 'pass' ? 'Mountain Pass' : 'Field Site'} · {pin.altitude}
      </div>
      <div className="lens-icons">
        <span className="ic">
          <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.2">
            <rect x="1" y="3.5" width="14" height="10" rx="0.5" />
            <circle cx="8" cy="8.5" r="2.6" />
            <path d="M11 3.5l0.7-1.2h2.6l0.7 1.2" />
          </svg>
          Photo
        </span>
        <span className="ic">
          <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.2">
            <rect x="5" y="2" width="6" height="9" rx="3" />
            <path d="M3 8.5a5 5 0 0010 0M8 13.5v1.5M5.5 15h5" />
          </svg>
          Audio
        </span>
        <span className="ic">
          <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.2">
            <path d="M3 2.5h10v11H3z" />
            <path d="M5.5 6h5M5.5 8.5h5M5.5 11h3" />
          </svg>
          Note
        </span>
      </div>
    </div>);

}

function PhotoLightbox({ photos, index, onClose, onNav }) {
  React.useEffect(function() {
    function onKey(e) {
      if (e.key === 'Escape') onClose();
      if (e.key === 'ArrowRight') onNav(1);
      if (e.key === 'ArrowLeft') onNav(-1);
    }
    window.addEventListener('keydown', onKey);
    return function() { window.removeEventListener('keydown', onKey); };
  }, [onClose, onNav]);

  const src = photos[index];
  return (
    <div className="map-lightbox" onClick={onClose} role="dialog" aria-modal="true">
      <button className="lb-close" onClick={onClose} aria-label="Close">×</button>
      {index > 0 && (
        <button className="lb-nav lb-prev" onClick={function(e){ e.stopPropagation(); onNav(-1); }} aria-label="Previous">‹</button>
      )}
      <img
        className="lb-img"
        src={src}
        alt=""
        onClick={function(e){ e.stopPropagation(); }}
      />
      {index < photos.length - 1 && (
        <button className="lb-nav lb-next" onClick={function(e){ e.stopPropagation(); onNav(1); }} aria-label="Next">›</button>
      )}
      <div className="lb-counter">{index + 1} / {photos.length}</div>
    </div>
  );
}

function DetailPanel({ pin, onClose }) {
  const [lightboxIdx, setLightboxIdx] = React.useState(null);

  React.useEffect(function() { setLightboxIdx(null); }, [pin]);

  if (!pin) {
    return (
      <div className="field-map-panel is-empty">
        <div className="panel-empty">
          Click any marker to open photographs, audio, and a field note.
        </div>
      </div>);
  }

  // Normalise photo entries — each can be a string or {src, position}
  function photoSrc(p) { return (p && typeof p === 'object') ? p.src : (p || ''); }
  function photoPos(p) { return (p && typeof p === 'object') ? (p.position || '50% 50%') : '50% 50%'; }

  const rawPhotos = (pin.photos && pin.photos.length > 0) ? pin.photos : [];
  const hasPhotos = rawPhotos.length > 0;
  const [main, ...thumbs] = hasPhotos ? rawPhotos : [null, null, null, null];

  // For the lightbox we just need src strings
  const photoSrcs = rawPhotos.map(photoSrc);

  return (
    <div className="field-map-panel">
      {lightboxIdx !== null && hasPhotos && (
        <PhotoLightbox
          photos={photoSrcs}
          index={lightboxIdx}
          onClose={function(){ setLightboxIdx(null); }}
          onNav={function(dir){ setLightboxIdx(function(i){ return Math.max(0, Math.min(photoSrcs.length - 1, i + dir)); }); }}
        />
      )}
      <div className="panel-left">
        <button className="panel-close" onClick={onClose} aria-label="Close">×</button>
        <div className="panel-head">
          <div>
            <div className="label">
              {pin.kind === 'pass' ? 'Mountain Pass' : 'Field Site'}
            </div>
            <h4 className="name">
              {pin.name}
            </h4>
          </div>
          <div className="coords">
            {window.fmtCoord(pin.lat, pin.lon)}
            <span className="alt">elev. {pin.altitude}</span>
          </div>
        </div>
        <p className="panel-note">{pin.note}</p>
        <window.FieldRecorderPlayer pin={pin} />
      </div>

      <div className="panel-right">
        <div className="panel-photos">
          <div
            className={'photo-main' + (hasPhotos ? ' is-clickable' : '')}
            onClick={hasPhotos ? function(){ setLightboxIdx(0); } : undefined}
            title={hasPhotos ? 'Click to enlarge' : undefined}
          >
            <image-slot
              id={`map-${pin.id}-1`}
              shape="rect"
              src={photoSrc(main)}
              position={photoPos(main)}
              placeholder={`Drop a photograph of ${pin.name}`}
              style={{ width: '100%', height: '100%' }}
            ></image-slot>
          </div>
          {thumbs.length > 0 && (
            <div className="photo-thumbs">
              {thumbs.map(function(photo, i) {
                const src = photoSrc(photo);
                return React.createElement('div', {
                  key: i,
                  className: 'thumb-wrap' + (src ? ' is-clickable' : ''),
                  onClick: src ? function(){ setLightboxIdx(i + 1); } : undefined,
                  title: src ? 'Click to enlarge' : undefined,
                },
                  React.createElement('image-slot', {
                    id: `map-${pin.id}-${i + 2}`,
                    shape: 'rect',
                    src: src,
                    position: photoPos(photo),
                    placeholder: ' ',
                    style: { width: '100%', height: '100%' }
                  })
                );
              })}
            </div>
          )}
        </div>
      </div>
    </div>);
}

// =====================================================================
// FieldMapPreview — a non-interactive, link-wrapped thumbnail of the
// atlas. Used on the main page to invite visitors into the full
// version, which lives on the Ladakh field-site sub-page.
// =====================================================================
function FieldMapPreview({ target }) {
  const pins = window.FieldMapPins || [];
  return (
    <a className="field-map field-map-preview" href={target || '#'} aria-label="Open the Ladakh field atlas">
      <div className="field-map-head">
        <h3 data-i18n="map.title">Field, <span className="it">beyond the research.</span></h3>
        <div className="legend">
          <span className="swatch"><span className="dot"></span> <span data-i18n="map.legend.site">Village / Site</span></span>
          <span className="swatch"><span className="tri"></span> <span data-i18n="map.legend.pass">Mountain Pass</span></span>
        </div>
      </div>
      <div className="field-map-stage is-preview">
        <window.FieldMapBasemap />
        <div className="field-map-overlay">
          {pins.map((p) => {
            const { left, top } = window.projectToPercent(p.lat, p.lon);
            return (
              <span key={p.id}
                    className="field-map-pin is-static"
                    style={{ left: `${left}%`, top: `${top}%` }}
                    data-kind={p.kind}
                    data-name-align={p.nameAlign || 'right'}>
                <span className="glyph" aria-hidden="true">
                  {p.kind === 'pass'
                    ? <span className="tri"></span>
                    : <span className="dot"></span>}
                </span>
                <span className="name">{p.name}</span>
              </span>
            );
          })}
        </div>
        <div className="field-map-cartouche">
          <span className="t">Ladakh</span>
          <span data-i18n="map.preview.atlas">Fieldwork Atlas</span>
          <span className="l">N 33°30′ — 35°00′<br />E 76°30′ — 79°30′</span>
        </div>
        <div className="field-map-preview-cta" aria-hidden="true">
          <span data-i18n="map.preview.cta">Open the field atlas</span>
          <span className="arrow">→</span>
        </div>
      </div>
    </a>
  );
}

// Mount.
function mountFieldMap() {
  const root = document.getElementById('field-map-root');
  if (!root) return;
  const isPreview = root.getAttribute('data-preview') === 'true';
  const target = root.getAttribute('data-target') || '';
  ReactDOM.createRoot(root).render(
    isPreview ? <FieldMapPreview target={target} /> : <FieldMap />
  );
  // After React commits, re-apply current language so newly-rendered
  // [data-i18n] elements inside the map pick up their translations.
  requestAnimationFrame(() => {
    requestAnimationFrame(() => {
      const lang = document.body.getAttribute('data-lang') || 'en';
      if (typeof window.applyLang === 'function') window.applyLang(lang);
    });
  });
}

if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', mountFieldMap);
} else {
  mountFieldMap();
}