/* farmstands.jsx — Farm Stands: Leaflet map + list, live from /api/farmstands */

const STAND_ICON_SVG = (color) => `
  <svg xmlns="http://www.w3.org/2000/svg" width="32" height="40" viewBox="0 0 32 40">
    <path d="M16 39C10 31 4 26 4 16a12 12 0 0 1 24 0c0 10-6 15-12 23z"
      fill="${color}" stroke="#fff" stroke-width="2"/>
    <circle cx="16" cy="15" r="6" fill="#fff8ee"/>
    <text x="16" y="19" text-anchor="middle" font-size="9" fill="${color}" font-family="system-ui" font-weight="700">🌱</text>
  </svg>`;

const DAYS = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];

function isMarket(s) { return !!s.date; }

function isOpenToday(stand) {
  if (!stand.openDays) return false;
  const today = DAYS[new Date().getDay()];
  return stand.openDays.toLowerCase().includes(today.toLowerCase());
}

function todayStr() {
  const n = new Date();
  return [n.getFullYear(), String(n.getMonth()+1).padStart(2,'0'), String(n.getDate()).padStart(2,'0')].join('-');
}

// Sort key: open/happening today → -1, everything else by days until next occurrence
function sortKey(s) {
  if (isMarket(s)) {
    if (s.date === todayStr()) return -1;
    const d = new Date(s.date + 'T12:00:00');
    const t = new Date(); t.setHours(0,0,0,0);
    return (d - t) / 86400000;
  }
  if (isOpenToday(s)) return -1;
  const dayIdx = new Date().getDay();
  const indices = DAYS.map((d,i) => s.openDays && s.openDays.toLowerCase().includes(d.toLowerCase()) ? i : -1).filter(i => i >= 0);
  if (!indices.length) return 999;
  let min = 7;
  indices.forEach(d => { const diff = (d - dayIdx + 7) % 7 || 7; if (diff < min) min = diff; });
  return min;
}

function isFutureOrStand(s) {
  if (!isMarket(s)) return true;
  return new Date(s.date + 'T12:00:00') >= new Date(new Date().toDateString());
}

function fmtMarketDate(dateStr) {
  const d = new Date(dateStr + 'T12:00:00');
  return d.toLocaleDateString('en-CA', { weekday:'short', month:'short', day:'numeric' });
}

function FarmStands() {
  const { go } = useFF();
  const [stands,   setStands]   = React.useState(null);
  const [selected, setSelected] = React.useState(null);
  const [filter,   setFilter]   = React.useState('All');
  const mapRef     = React.useRef(null);
  const leafletRef = React.useRef(null);
  const markersRef = React.useRef([]);

  /* ── Fetch data ── */
  React.useEffect(() => {
    fetch('/api/farmstands')
      .then(r => r.ok ? r.json() : [])
      .then(data => setStands(Array.isArray(data) ? data.filter(isFutureOrStand) : []))
      .catch(() => setStands([]));
  }, []);

  /* ── Init Leaflet once component mounts ── */
  React.useEffect(() => {
    if (!mapRef.current || leafletRef.current) return;
    const L = window.L;
    if (!L) return;
    const map = L.map(mapRef.current, { zoomControl: false }).setView([53.9171, -122.7497], 11);
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '© OpenStreetMap contributors', maxZoom: 19
    }).addTo(map);
    L.control.zoom({ position:'bottomright' }).addTo(map);
    leafletRef.current = map;
    return () => { map.remove(); leafletRef.current = null; };
  }, []);

  /* ── Sync markers when data or filter changes ── */
  React.useEffect(() => {
    const map = leafletRef.current;
    const L = window.L;
    if (!map || !L || !stands) return;

    markersRef.current.forEach(m => m.remove());
    markersRef.current = [];

    const visible = getVisible(stands, filter);
    let selectedMarker = null;
    visible.forEach(s => {
      if (!s.lat || !s.lng) return;
      const isSel = selected?.id === s.id;
      const color = isSel ? '#c4612e' : '#5c7461';
      const icon = L.divIcon({
        html: STAND_ICON_SVG(color),
        className: '', iconSize:[32,40], iconAnchor:[16,40], popupAnchor:[0,-44]
      });
      const marker = L.marker([s.lat, s.lng], { icon })
        .addTo(map)
        .on('click', () => setSelected(s));
      markersRef.current.push(marker);
      if (isSel) selectedMarker = marker;
    });
    if (selectedMarker) selectedMarker.setZIndexOffset(1000);

    const withCoords = visible.filter(s => s.lat && s.lng);
    if (withCoords.length > 0) {
      const bounds = L.latLngBounds(withCoords.map(s => [s.lat, s.lng]));
      map.fitBounds(bounds, { padding:[40,40], maxZoom:14 });
    }
  }, [stands, selected, filter]);

  function getVisible(list, f) {
    if (!list) return [];
    let result;
    if (f === 'All') result = list.slice();
    else if (f === 'Open today') result = list.filter(s => isMarket(s) ? s.date === todayStr() : isOpenToday(s));
    else if (f === 'Markets') result = list.filter(isMarket);
    else result = list.filter(s => (s.available || '').toLowerCase().includes(f.toLowerCase()));
    return result.sort((a, b) => sortKey(a) - sortKey(b));
  }

  const hasMarkets = stands && stands.some(isMarket);
  const allItems = stands
    ? Array.from(new Set(stands.flatMap(s => (s.available || '').split(',').map(x => x.trim()).filter(Boolean))))
    : [];

  const filterOpts = ['All', 'Open today', ...(hasMarkets ? ['Markets'] : []), ...allItems];
  const visible = getVisible(stands, filter);
  const loading = stands === null;

  const openNow  = visible.filter(s => sortKey(s) === -1);
  const upcoming = visible.filter(s => sortKey(s) !== -1);
  const hasBothGroups = openNow.length > 0 && upcoming.length > 0;

  function renderStandCard(s) {
    const sel    = selected?.id === s.id;
    const open   = isOpenToday(s);
    const market = isMarket(s);
    return (
      <button key={s.id || s.name} onClick={() => setSelected(sel ? null : s)} className="card"
        style={{ textAlign:'left', padding:'16px 18px', cursor:'pointer', border:'none', width:'100%',
          outline: sel ? '2px solid var(--accent)' : undefined,
          borderLeft: market ? '4px solid var(--accent)' : undefined }}>
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', gap:12 }}>
          <div style={{ fontFamily:'var(--display)', fontWeight:700, fontSize:19 }}>{s.name}</div>
          {market
            ? <span className="chip" style={{ flexShrink:0, borderColor:'var(--accent)', color:'var(--accent)' }}>
                Market
              </span>
            : <span className="chip" style={{ flexShrink:0, borderColor: open?'#5c7461':'var(--line)', color: open?'#5c7461':'var(--ink-faint)' }}>
                {open ? '● Open today' : 'Closed today'}
              </span>}
        </div>
        {market && s.date && (
          <div style={{ display:'flex', gap:5, alignItems:'center', color:'var(--accent)', fontSize:13, fontWeight:600, marginTop:6 }}>
            <IconClock size={14}/>{fmtMarketDate(s.date)}{s.start ? ` · ${s.start}${s.end ? `–${s.end}` : ''}` : ''}
          </div>
        )}
        {s.address && <div style={{ display:'flex', gap:5, alignItems:'center', color:'var(--ink-faint)', fontSize:13, marginTop:6 }}><IconPin size={14}/>{s.address}</div>}
        {!market && s.hours && (
          <div style={{ display:'flex', gap:5, alignItems:'flex-start', color:'var(--ink-soft)', fontSize:13, marginTop:4 }}>
            <IconClock size={14} style={{ flexShrink:0, marginTop:2 }}/>
            <span style={{ whiteSpace:'pre-line' }}>{s.hours}</span>
          </div>
        )}
        {s.available && (
          <div style={{ display:'flex', gap:5, flexWrap:'wrap', marginTop:10 }}>
            {s.available.split(',').map(a => a.trim()).filter(Boolean).map(a => (
              <span key={a} className="chip" style={{ fontSize:12 }}>{a}</span>
            ))}
          </div>
        )}
        {s.description && <p style={{ color:'var(--ink-soft)', fontSize:14, margin:'10px 0 0' }}>{s.description}</p>}
        {s.photos && s.photos.length > 0 && <PhotoCarousel photos={s.photos} height={180} />}
        <div style={{ display:'flex', gap:10, marginTop:10, flexWrap:'wrap' }}>
          {s.address && (
            <a href={`https://www.google.com/maps/dir/?api=1&destination=${encodeURIComponent(s.address + ', Prince George, BC')}`}
              target="_blank" rel="noopener" onClick={e => { e.stopPropagation(); window.ffTrack && window.ffTrack('directions', s.address); }}
              style={{ display:'inline-flex', gap:5, alignItems:'center', color:'var(--accent)', fontSize:13, fontWeight:600 }}>
              <IconRoute size={14}/> Directions
            </a>
          )}
          {market && s.website && (
            <a href={s.website} target="_blank" rel="noopener" onClick={e => { e.stopPropagation(); window.ffTrack && window.ffTrack('more_info', s.name); }}
              style={{ display:'inline-flex', gap:5, alignItems:'center', color:'var(--river)', fontSize:13, fontWeight:600 }}>
              <IconGlobe size={14}/> Event details
            </a>
          )}
          {!market && s.website && (
            <a href={s.website.startsWith('http') ? s.website : `https://${s.website}`}
              target="_blank" rel="noopener" onClick={e => { e.stopPropagation(); window.ffTrack && window.ffTrack('more_info', s.name); }}
              style={{ display:'inline-flex', gap:5, alignItems:'center', color:'var(--river)', fontSize:13, fontWeight:600 }}>
              <IconGlobe size={14}/> Website
            </a>
          )}
        </div>
      </button>
    );
  }

  return (
    <div>
      <PageBanner eyebrow="Local food" title="Local Markets & Stands"
        sub="Farm stands, farmers markets, seed swaps, and seasonal produce — straight from Prince George growers." />

      <window.SponsorStrip/>

      {/* filter chips */}
      <div className="page-wrap" style={{ padding:'18px 28px 0', display:'flex', gap:8, flexWrap:'wrap' }}>
        {filterOpts.map(f => (
          <button key={f} onClick={() => setFilter(f)} className="chip"
            style={{ cursor:'pointer', fontSize:13.5, padding:'7px 14px',
              background: filter===f ? 'var(--spruce)' : 'var(--paper-3)',
              color: filter===f ? 'var(--paper)' : 'var(--ink-soft)', borderColor:'transparent' }}>{f}</button>
        ))}
        <button className="btn btn-primary" onClick={() => go('submit')} style={{ marginLeft:'auto', padding:'6px 14px', fontSize:13.5, borderRadius:100 }}>
          <IconPlus size={15}/> Add a stand
        </button>
      </div>

      <div className="page-wrap" style={{ padding:'26px 28px 0' }}>
        <div className="explorer" style={{ display:'grid', gridTemplateColumns:'minmax(340px,440px) 1fr', gap:26, alignItems:'start' }}>

          {/* list */}
          <div style={{ display:'flex', flexDirection:'column', gap:12 }}>
            {loading && (
              <p style={{ color:'var(--ink-faint)', fontFamily:'var(--serif)', fontStyle:'italic', fontSize:18, margin:0 }}>
                Loading listings…
              </p>
            )}
            {!loading && visible.length === 0 && (
              <div className="card" style={{ padding:'32px 28px', textAlign:'center' }}>
                <IconSprout size={40} style={{ color:'var(--ink-faint)', margin:'0 auto 12px' }}/>
                <h3 style={{ fontSize:20, marginBottom:8 }}>No listings yet</h3>
                <p style={{ color:'var(--ink-soft)', marginBottom:16, fontSize:15 }}>
                  {filter !== 'All' ? `No listings match "${filter}".` : 'Know a local farm stand or market? Get it on the map.'}
                </p>
                {filter !== 'All'
                  ? <button className="btn btn-ghost" onClick={() => setFilter('All')}>Show all stands</button>
                  : <button className="btn btn-primary" onClick={() => go('submit')}><IconPlus size={16}/> Add a stand</button>}
              </div>
            )}
            {!loading && hasBothGroups && (
              <div style={{ display:'flex', alignItems:'center', gap:10, margin:'4px 0 2px' }}>
                <span style={{ fontSize:11, fontWeight:700, letterSpacing:'0.08em', textTransform:'uppercase', color:'#5c7461' }}>Open today</span>
                <div style={{ flex:1, height:1, background:'#5c746140' }}/>
              </div>
            )}
            {!loading && openNow.map(renderStandCard)}
            {!loading && hasBothGroups && (
              <div style={{ display:'flex', alignItems:'center', gap:10, margin:'8px 0 2px' }}>
                <span style={{ fontSize:11, fontWeight:700, letterSpacing:'0.08em', textTransform:'uppercase', color:'var(--ink-faint)' }}>Coming up</span>
                <div style={{ flex:1, height:1, background:'var(--line)' }}/>
              </div>
            )}
            {!loading && upcoming.map(renderStandCard)}
          </div>

          {/* map — always visible */}
          <div className="explorer-map" style={{ position:'sticky', top:92, height:'calc(100vh - 120px)', minHeight:460 }}>
            <div className="card" style={{ height:'100%', overflow:'hidden', padding:0 }}>
              <div ref={mapRef} style={{ width:'100%', height:'100%' }}/>
            </div>
          </div>

        </div>
      </div>
      <div style={{ height:40 }}/>
    </div>
  );
}

window.Pages = window.Pages || {};
window.Pages.FarmStands = FarmStands;
