/* ============================================================
   VLF 2026 · BẢN ĐỒ SỰ KIỆN — Leaflet trên ảnh vệ tinh thật
   Montgomerie Links Golf Club (Đà Nẵng). Nền địa hình = ảnh vệ tinh
   Esri (chuẩn xác, không bịa). Lớp điểm sự kiện do BTC đặt (VLF.zones,
   VLF.holes) — có thể tinh chỉnh toạ độ khi khảo sát thực địa.
   ============================================================ */

/* path icon cần cho marker (bản sao gọn — file babel không share scope) */
const VM_ICON = {
  flag: 'M5 21V4M5 4c3-1.5 6 1.5 9 0s5 .5 5 .5v9s-2-1.5-5 0-6-1.5-9 0',
  gala: 'M5 22h14M7 10a5 5 0 0 0 10 0M7 10V4h10v6M9 22v-3a3 3 0 0 1 6 0v3',
  star: 'M12 3.5l2.6 5.3 5.9.9-4.2 4.1 1 5.8L12 17.1 6.7 19.6l1-5.8L3.5 9.7l5.9-.9z',
  fb: 'M6 3v8a2 2 0 0 0 4 0V3M8 11v10M17 3c-1.6 0-2.6 2-2.6 5s1.1 4 2.6 4 2.6-1 2.6-4-1-5-2.6-5zM17 12v9',
  cup: 'M5 8h11v5a5 5 0 0 1-10 0zM16 9h2a2 2 0 0 1 0 4h-2M5 21h12',
  info: 'M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18zM12 11v5M12 8h.01',
  village: 'M3 21h18M5 21v-9l7-5 7 5v9M9 21v-5h6v5',
  golfer: 'M12 4a2 2 0 1 0 0 4 2 2 0 0 0 0-4zM10 21v-6l-2-3 3-3 3 1 2 3M14 21v-5',
  car: 'M6 16l1-5a2 2 0 0 1 2-1.6h6a2 2 0 0 1 2 1.6l1 5M5 16h14v3H5zM8 19v2M16 19v2M8 13h8',
  medical: 'M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18zM12 8v8M8 12h8',
  shield: 'M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6z',
  calendar: 'M4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v13H4zM4 9h16M8 3v4M16 3v4'
};
function vmSvg(name, sw) {
  return '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="' + (sw || 1.9) +
  '" stroke-linecap="round" stroke-linejoin="round"><path d="' + (VM_ICON[name] || VM_ICON.info) + '"/></svg>';
}

function EventMap({ nav, focus, persona }) {
  const t = useT();const lang = t.lang;
  const T = (vi, en) => lang === 'en' ? en : vi;
  // Khán giả / khách mời / VIP không thi đấu → không có "nhóm của tôi".
  // Người chơi (golfer) tìm nhóm CỦA MÌNH; người xem tìm golfer/nhóm để theo dõi.
  const isPlayer = persona === 'golfer' || persona === 'golfer_intl';
  const findLabel = isPlayer ? T('Tìm nhóm của tôi', 'Find my group') : T('Tìm nhóm thi đấu', 'Find a group');
  const findSub = isPlayer ?
    T('Các bảng xuất phát ở những tee khác nhau (shotgun). Chọn bảng hoặc nhập BIB để xem bạn bắt đầu ở hố nào.', 'Divisions tee off at different holes (shotgun). Pick your division or enter your BIB to see where you start.') :
    T('Chọn bảng đấu hoặc nhập tên golfer để xem nhóm xuất phát ở hố nào — tiện theo dõi tại sân.', 'Pick a division or enter a golfer’s name to see where a group tees off — handy for watching on course.');
  const findPh = isPlayer ? T('Nhập BIB hoặc tên của bạn…', 'Enter your BIB or name…') : T('Nhập tên golfer hoặc bảng đấu…', 'Enter a golfer name or division…');
  const M = window.VLF.mapMeta;
  const GROUPS = window.VLF.mapGroups;
  const ZONES = window.VLF.zones;
  const HOLES = window.VLF.holes;
  const DIVS = window.VLF.divisions.filter((d) => !d.side);
  const groupById = {};GROUPS.forEach((g) => {groupById[g.id] = g;});
  const divColor = {};window.VLF.divisions.forEach((d) => {divColor[d.id] = d.accent;});
  const divName = {};window.VLF.divisions.forEach((d) => {divName[d.id] = d.name;});

  const wrapRef = React.useRef(null);
  const mapRef = React.useRef(null);
  const layRef = React.useRef({}); // { zones, holes, me, route }
  const [ready, setReady] = useState(false);

  const [active, setActive] = useState(() => Object.fromEntries(GROUPS.map((g) => [g.id, true])));
  const [showHoles, setShowHoles] = useState(true);
  const [sel, setSel] = useState(null); // { kind:'zone'|'hole', id }
  const [findOpen, setFindOpen] = useState(false);
  const [findDiv, setFindDiv] = useState(null);
  const [bib, setBib] = useState('');
  const [locating, setLocating] = useState(false);
  const focusedRef = React.useRef(false);

  // tee time thật theo hố (quét toàn bộ ngày)
  function teesAtHole(n) {
    const out = [];
    Object.entries(window.VLF.teeTimes).forEach(([dayId, gs]) => {
      gs.forEach((g) => {if (String(g.hole) === String(n)) out.push({ dayId, ...g });});
    });
    return out;
  }

  /* ---------- init Leaflet once ---------- */
  React.useEffect(() => {
    if (!wrapRef.current || mapRef.current || !window.L) return;
    const L = window.L;
    const map = L.map(wrapRef.current, {
      center: M.center, zoom: M.zoom, minZoom: M.minZoom, maxZoom: M.maxZoom,
      zoomControl: false, attributionControl: true,
      maxBounds: M.bounds, maxBoundsViscosity: 0.9,
      zoomSnap: 0.25, wheelPxPerZoomLevel: 120
    });
    map.attributionControl.setPrefix('');
    L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
      maxZoom: 20, maxNativeZoom: 19, attribution: 'Ảnh vệ tinh © Esri'
    }).addTo(map);
    L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer/tile/{z}/{y}/{x}', {
      maxZoom: 20, maxNativeZoom: 19, opacity: 0.85
    }).addTo(map);

    layRef.current.zones = L.layerGroup().addTo(map);
    layRef.current.holes = L.layerGroup().addTo(map);

    // vị trí của khách (demo · gần tee Hố 7)
    const me = L.marker([M.me.lat, M.me.lng], {
      icon: L.divIcon({ className: 'vm-me-wrap', html: '<div class="vm-me"><span class="ring"></span><span class="dot"></span></div>', iconSize: [22, 22], iconAnchor: [11, 11] }),
      zIndexOffset: 1000, interactive: false
    }).addTo(map);
    layRef.current.me = me;

    mapRef.current = map;
    setReady(true);
    const ro = new ResizeObserver(() => map.invalidateSize());
    ro.observe(wrapRef.current);
    setTimeout(() => map.invalidateSize(), 80);
    setTimeout(() => map.invalidateSize(), 400);
    return () => {ro.disconnect();map.remove();mapRef.current = null;};
  }, []);

  /* ---------- (re)draw zone markers ---------- */
  React.useEffect(() => {
    if (!ready) return;
    const L = window.L;const lg = layRef.current.zones;lg.clearLayers();
    ZONES.forEach((z) => {
      if (!active[z.group]) return;
      const g = groupById[z.group];
      const on = sel && sel.kind === 'zone' && sel.id === z.id;
      const cls = 'vm-mk' + (z.big ? ' lg' : '') + (on ? ' on' : '');
      const html = '<div class="' + cls + '" style="--c:' + g.color + '">' + vmSvg(z.ic) + '</div>';
      const mk = L.marker([z.lat, z.lng], {
        icon: L.divIcon({ className: 'vm-mk-wrap', html, iconSize: z.big ? [40, 40] : [32, 32], iconAnchor: z.big ? [20, 20] : [16, 16] }),
        zIndexOffset: on ? 800 : z.big ? 400 : 200
      });
      mk.on('click', () => {clearRoute();setSel({ kind: 'zone', id: z.id });mapRef.current.panTo([z.lat, z.lng], { animate: true });});
      mk.addTo(lg);
    });
  }, [ready, active, sel, lang]);

  /* ---------- (re)draw hole markers ---------- */
  React.useEffect(() => {
    if (!ready) return;
    const L = window.L;const lg = layRef.current.holes;lg.clearLayers();
    if (!showHoles) return;
    HOLES.forEach((h) => {
      const dimmed = findDiv && h.div !== findDiv;
      const on = sel && sel.kind === 'hole' && sel.id === h.n;
      const c = findDiv ? h.div === findDiv ? divColor[h.div] : '#6b6b6b' : '#2A2230';
      const cls = 'vm-hole' + (h.hl ? ' hl' : '') + (dimmed ? ' dim' : '') + (on ? ' on' : '');
      const html = '<div class="' + cls + '" style="--c:' + c + '">' + h.n + '</div>';
      const mk = L.marker([h.lat, h.lng], {
        icon: L.divIcon({ className: 'vm-hole-wrap', html, iconSize: [26, 26], iconAnchor: [13, 13] }),
        zIndexOffset: on ? 700 : h.hl ? 120 : 60
      });
      mk.on('click', () => {clearRoute();setSel({ kind: 'hole', id: h.n });mapRef.current.panTo([h.lat, h.lng], { animate: true });});
      mk.addTo(lg);
    });
  }, [ready, showHoles, sel, findDiv, lang]);

  /* ---------- focus từ tee time (deep-link) ---------- */
  React.useEffect(() => {
    if (!ready || focusedRef.current || !focus || !focus.focusHole && !focus.focusZone) return;
    focusedRef.current = true;
    if (focus.focusZone) {// deep-link tới 1 khu cụ thể
      const z = ZONES.find((x) => x.id === focus.focusZone);
      if (z) {
        setActive((s) => ({ ...s, [z.group]: true }));
        setSel({ kind: 'zone', id: z.id });
        mapRef.current.flyTo([z.lat, z.lng], 17.5, { duration: 0.9 });
      }
      return;
    }
    const hv = String(focus.focusHole);
    if (hv.charAt(0) === 'T') {// trạm kỹ thuật → driving range
      const z = ZONES.find((x) => x.id === 'range');
      setSel({ kind: 'zone', id: 'range' });
      if (z) mapRef.current.flyTo([z.lat, z.lng], 17.5, { duration: 0.8 });
    } else {
      const n = parseInt(hv, 10);
      const h = HOLES.find((x) => x.n === n);
      if (h) {
        setShowHoles(true);
        if (focus.focusDiv) setFindDiv(focus.focusDiv);
        setSel({ kind: 'hole', id: n });
        mapRef.current.flyTo([h.lat, h.lng], 17.5, { duration: 0.9 });
      }
    }
  }, [ready]);

  /* ---------- helpers ---------- */
  function clearRoute() {
    if (layRef.current.route) {mapRef.current.removeLayer(layRef.current.route);layRef.current.route = null;}
  }
  function drawDirections(to) {
    const L = window.L;clearRoute();
    const line = L.polyline([[M.me.lat, M.me.lng], to], { color: '#fff', weight: 4, opacity: 0.95, dashArray: '2 9', lineCap: 'round' }).addTo(mapRef.current);
    L.polyline([[M.me.lat, M.me.lng], to], { color: '#522367', weight: 7, opacity: 0.35, lineCap: 'round' }).addTo(mapRef.current).bringToBack();
    layRef.current.route = L.layerGroup([line]).addTo(mapRef.current);
    mapRef.current.fitBounds([[M.me.lat, M.me.lng], to], { padding: [70, 90], maxZoom: 17.5 });
  }
  function locate() {
    setLocating(true);
    const done = (ll) => {setLocating(false);mapRef.current.flyTo(ll, 17, { duration: 0.8 });};
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(
        (p) => done([p.coords.latitude, p.coords.longitude]),
        () => done([M.me.lat, M.me.lng]), // Zalo cần API riêng → fallback vị trí nội bộ
        { enableHighAccuracy: true, timeout: 4000 });
    } else {done([M.me.lat, M.me.lng]);}
  }
  function zoom(d) {const m = mapRef.current;if (m) m.setZoom(m.getZoom() + d);}
  function pickDiv(id) {
    setFindDiv(id);setFindOpen(false);setSel(null);setShowHoles(true);
    const tees = HOLES.filter((h) => h.div === id).map((h) => [h.lat, h.lng]);
    if (tees.length && mapRef.current) mapRef.current.flyToBounds(tees, { padding: [80, 90], maxZoom: 17.2, duration: 0.8 });
  }
  function findByBib() {
    const q = bib.trim();if (!q) return;
    let s = 0;for (let i = 0; i < q.length; i++) s += q.charCodeAt(i);
    const h = HOLES[s % HOLES.length];
    setFindDiv(h.div);setFindOpen(false);setShowHoles(true);
    setSel({ kind: 'hole', id: h.n });
    if (mapRef.current) mapRef.current.flyTo([h.lat, h.lng], 17.5, { duration: 0.8 });
  }

  /* ---------- selected object for detail card ---------- */
  let card = null;
  let holeTees = [];
  if (sel && sel.kind === 'zone') {
    const z = ZONES.find((x) => x.id === sel.id);const g = groupById[z.group];
    card = {
      color: g.color, ic: z.ic, tag: T(g.vi, g.en),
      title: T(z.name, z.nameEn), sub: T(z.s, z.sEn), to: [z.lat, z.lng]
    };
  } else if (sel && sel.kind === 'hole') {
    const h = HOLES.find((x) => x.n === sel.id);
    card = {
      color: divColor[h.div], ic: 'flag', tag: 'Par ' + h.par,
      title: T('Hố ' + h.n, 'Hole ' + h.n),
      sub: h.hl ? T(h.hl, h.hlEn) : T('Tee xuất phát: bảng ', 'Tee-off division: ') + divName[h.div],
      note: T('Bảng ', 'Division: ') + divName[h.div] + ' · tee-off',
      to: [h.lat, h.lng]
    };
    holeTees = teesAtHole(h.n);
  }

  return (
    <div className="v-map">
      <div className="vm-leaf" ref={wrapRef} />

      {/* top bar: back + tiêu đề sân */}
      <button className="vm-back" onClick={() => nav('back')} aria-label="Quay lại"><Icon name="back" size={22} sw={2.2} /></button>
      <div className="vm-title">
        <div className="nm">{M.venue}</div>
        <div className="sub">{T(M.venueSub, M.venueSubEn)}</div>
      </div>

      {/* lọc lớp (chips) */}
      <div className="vm-chips">
        {GROUPS.map((g) =>
        <React.Fragment key={g.id}>
          <button className={'vm-chip' + (active[g.id] ? ' on' : '')} style={{ '--c': g.color }}
          onClick={() => setActive((s) => ({ ...s, [g.id]: !s[g.id] }))}>
            <span className="dot" /><Icon name={g.ic} size={13} sw={2} />{T(g.vi, g.en)}
          </button>
          {g.id === 'thidau' &&
          <button className={'vm-chip' + (showHoles ? ' on' : '')} style={{ '--c': '#2A2230' }} onClick={() => setShowHoles((v) => !v)}>
            <span className="dot" />18 hố
          </button>}
        </React.Fragment>
        )}
      </div>

      {/* điều khiển bên phải */}
      <div className="vm-ctrls">
        <button className={'vm-ctrl' + (locating ? ' busy' : '')} onClick={locate} aria-label="Vị trí của tôi"><Icon name="locate" size={20} sw={2} /></button>
        <div className="vm-zoom">
          <button onClick={() => zoom(1)} aria-label="Phóng to"><Icon name="plus" size={18} sw={2.2} /></button>
          <span />
          <button onClick={() => zoom(-1)} aria-label="Thu nhỏ"><Icon name="minus" size={18} sw={2.2} /></button>
        </div>
      </div>

      {/* banner đang lọc theo bảng */}
      {findDiv &&
      <div className="vm-filterbar" style={{ '--c': divColor[findDiv] }}>
          <span className="dot" />
          <b>{T('Đang xem ', 'Showing ')}{divName[findDiv]}</b>
          <button onClick={() => {setFindDiv(null);}}>{T('Xoá lọc', 'Clear')}</button>
        </div>
      }

      {/* định vị nội bộ */}
      <div className="vm-meloc"><span className="d" />{T('Bạn · Hố ', 'You · Hole ')}{M.me.hole}<em>GPS</em></div>

      {/* FAB tìm nhóm — ẩn khi đang mở card hoặc sheet */}
      {!card && !findOpen &&
      <button className="vm-find-fab" onClick={() => setFindOpen(true)}><Icon name="route" size={18} sw={2} />{findLabel}</button>
      }

      {/* card chi tiết */}
      {card &&
      <div className="v-map-card vm-card">
          <button className="vm-card-x" onClick={() => {setSel(null);clearRoute();}} aria-label="Đóng"><Icon name="x" size={16} sw={2.2} /></button>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
            <div className="vm-card-ic" style={{ '--c': card.color }}><Icon name={card.ic} size={22} sw={1.8} /></div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div className="vm-card-tag" style={{ color: card.color }}>{card.tag}</div>
              <div className="t">{card.title}</div>
            </div>
          </div>
          <div className="s">{card.sub}</div>
          {sel.kind === 'hole' && (holeTees.length ?
        <div className="vm-tee-list">
              <div className="vm-tee-list-h"><Icon name="clock" size={13} sw={2} />{T('Xuất phát tại hố này', 'Tee-off at this hole')}</div>
              {holeTees.slice(0, 4).map((g, i) => {
            const dd = window.VLF.divById(g.div);const day = window.VLF.teeDays.find((x) => x.id === g.dayId);
            return (
              <button className="vm-tee-row" key={i} onClick={() => nav('compete', { sub: 'teetime', teeDay: g.dayId })}>
                    <span className="tm v-num">{g.time}</span>
                    <span className="dy">{day.dow} {day.date}</span>
                    <span className="dv" style={{ color: dd.accent }}>{dd.shortName}</span>
                    <Icon name="chev" size={15} sw={2} />
                  </button>);

          })}
              {holeTees.length > 4 &&
          <button className="vm-tee-allbtn" onClick={() => nav('compete', { sub: 'teetime', teeDay: holeTees[0].dayId })}>
                  +{holeTees.length - 4} {T('nhóm khác · mở lịch Tee Time', 'more · open tee time')}
                </button>
          }
            </div> :

        <div className="vm-tee-empty">{T('Hố này không có nhóm xuất phát (theo lịch hiện tại).', 'No groups tee off at this hole in the current schedule.')}</div>)
        }
          <div className="vm-card-acts">
            <button className="v-btn v-btn-primary" style={{ height: 46, flex: 1 }} onClick={() => drawDirections(card.to)}>
              <Icon name="route" size={18} sw={1.9} />{T('Chỉ đường từ Hố ', 'Directions from Hole ') + M.me.hole}
            </button>
            {sel.kind === 'hole' &&
          <button className="vm-card-2nd" onClick={() => setFindOpen(true)} aria-label={findLabel}><Icon name="search" size={19} sw={2} /></button>
          }
          </div>
        </div>
      }

      {/* sheet tìm nhóm */}
      {findOpen &&
      <>
          <div className="vm-scrim" onClick={() => setFindOpen(false)} />
          <div className="vm-sheet">
            <div className="vm-sheet-grab" />
            <div className="vm-sheet-h">
              <div>
                <div className="tt">{findLabel}</div>
                <div className="ss">{findSub}</div>
              </div>
              <button className="vm-sheet-x" onClick={() => setFindOpen(false)} aria-label="Đóng"><Icon name="x" size={18} sw={2.2} /></button>
            </div>

            <div className="vm-bibrow">
              <input value={bib} onChange={(e) => setBib(e.target.value)} placeholder={findPh}
            onKeyDown={(e) => {if (e.key === 'Enter') findByBib();}} />
              <button onClick={findByBib}><Icon name="search" size={18} sw={2.1} /></button>
            </div>

            <div className="vm-divlist">
              {DIVS.map((d) => {
              const tees = HOLES.filter((h) => h.div === d.id);
              return (
                <button key={d.id} className="vm-divrow" onClick={() => pickDiv(d.id)}>
                    <span className="cdot" style={{ background: d.accent }} />
                    <div className="tx">
                      <b>{d.name}</b>
                      <span>{tees.length} {T('tee xuất phát', 'starting tees')} · {tees.map((h) => h.n).join(', ')}</span>
                    </div>
                    <Icon name="chev" size={18} sw={2} />
                  </button>);

            })}
            </div>
          </div>
        </>
      }
    </div>);

}

Object.assign(window, { EventMap });