/* ============================================================
   EventsMap — where Primo sells tickets.
   Renders a stylized US map with dots for each city.
   Click a dot → opens the event list for that city.
   Data: assets/events-map-data.json (generated from HubSpot export)
   ============================================================ */
function EventsMap() {
  const [data, setData] = React.useState(null);
  const [activeCity, setActiveCity] = React.useState(null);
  const [hoverCity, setHoverCity] = React.useState(null);
  const [sport, setSport] = React.useState('All');
  const svgRef = React.useRef(null);

  React.useEffect(() => {
    fetch(window.__resources && window.__resources.mapData || 'assets/events-map-data.json').
    then((r) => r.json()).
    then((d) => setData(d)).
    catch((e) => console.error('Failed to load map data', e));
  }, []);

  if (!data) {
    return (
      <section className="events-map-section">
        <div className="wrap" style={{ textAlign: 'center', padding: '80px 0' }}>
          <div style={{ color: 'var(--muted, #64748B)', fontSize: 14 }}>Loading map…</div>
        </div>
      </section>);

  }

  // Filter cities by sport
  const filteredCities = data.cities.map((c) => {
    const events = sport === 'All' ? c.events : c.events.filter((e) => e.sport === sport);
    return { ...c, events };
  }).filter((c) => c.events.length > 0);

  const totalEvents = filteredCities.reduce((s, c) => s + c.events.length, 0);
  const states = new Set(filteredCities.map((c) => c.state));
  const maxEvents = Math.max(...filteredCities.map((c) => c.events.length));

  // Logarithmic-ish radius so Durango (40) doesn't dominate but is clearly biggest
  function dotRadius(n) {
    if (n <= 1) return 4.5;
    return Math.min(4.5 + Math.sqrt(n - 1) * 2.2, 16);
  }

  const sportFilters = ['All', ...data.totals.sports];

  // Color a dot by primary sport (most common at that city) — feels alive when filtered too
  const sportColor = {
    Cheer: '#FF6B5B',
    Rodeo: '#F59F00',
    Soccer: '#16A878',
    Football: '#7B5CFF',
    Basketball: '#F97316',
    Volleyball: '#EC4899',
    Wrestling: '#0EA5E9',
    Lacrosse: '#8B5CF6',
    'Non-Sport': '#64748B'
  };
  function dominantSport(city) {
    const counts = {};
    city.events.forEach((e) => counts[e.sport] = (counts[e.sport] || 0) + 1);
    return Object.entries(counts).sort((a, b) => b[1] - a[1])[0][0];
  }

  const active = activeCity ? filteredCities.find((c) => c.name === activeCity) : null;

  return (
    <section className="events-map-section" id="events-map">
      <div className="wrap">
        <div className="emap-head">
          <span className="eyebrow"><span className="dot"></span>Where we sell</span>
          <h2>Powering events <span className="accent">coast to coast.</span></h2>
          <p className="emap-lede">From local end-of-season showcases to multi-day cheer &amp; dance nationals in Orlando — Primo is the ticketing partner for cheer events large and small. Click a city to see what we've sold there.

          </p>
        </div>

        <div className="emap-stats">
          <div><strong>772</strong><span>cheer events ticketed</span></div>
          <div><strong>{data.totals.cities}</strong><span>cities</span></div>
          <div><strong>{data.totals.states}</strong><span>states</span></div>
        </div>

        {data.totals.sports.length > 1 &&
        <div className="emap-filters" role="tablist">
          {sportFilters.map((s) =>
          <button
            key={s}
            role="tab"
            aria-selected={sport === s}
            className={"emap-chip" + (sport === s ? " active" : "")}
            onClick={() => {setSport(s);setActiveCity(null);}}>
            
              {s !== 'All' &&
            <span className="emap-chip-dot" style={{ background: sportColor[s] }}></span>
            }
              {s}
            </button>
          )}
        </div>
        }

        <div className="emap-board">
          <div className="emap-canvas">
            <svg
              ref={svgRef}
              viewBox={data.viewBox}
              preserveAspectRatio="xMidYMid meet"
              role="img"
              aria-label="Map of US cities where Primo sells tickets">
              
              <defs>
                <radialGradient id="emap-bg" cx="50%" cy="40%" r="60%">
                  <stop offset="0%" stopColor="#F7FBFF" />
                  <stop offset="100%" stopColor="#EEF3F8" />
                </radialGradient>
                <filter id="emap-glow" x="-50%" y="-50%" width="200%" height="200%">
                  <feGaussianBlur stdDeviation="3" result="blur" />
                  <feMerge><feMergeNode in="blur" /><feMergeNode in="SourceGraphic" /></feMerge>
                </filter>
              </defs>

              <rect x="0" y="0" width="1000" height="620" fill="url(#emap-bg)" />

              {/* State fills */}
              <g className="emap-states">
                {data.states.map((s) =>
                <path
                  key={s.id}
                  d={s.d}
                  fill={states.has(stateAbbrev(s.name)) ? '#D9E6F2' : '#E8EDF3'}
                  stroke="#FFFFFF"
                  strokeWidth="1.2" />

                )}
              </g>

              {/* Cities */}
              <g className="emap-cities">
                {filteredCities.map((c) => {
                  const r = dotRadius(c.events.length);
                  const color = sportColor[dominantSport(c)] || '#00B5E2';
                  const isActive = activeCity === c.name;
                  const isHover = hoverCity === c.name;
                  return (
                    <g key={c.name} className={"emap-city" + (isActive ? " active" : "")}>
                      {/* Outer halo */}
                      <circle
                        cx={c.x} cy={c.y}
                        r={r + 6}
                        fill={color}
                        opacity={isActive ? 0.22 : 0.0}
                        style={{ transition: 'opacity 200ms' }} />
                      
                      {/* Pulse for biggest dot */}
                      {c.events.length === maxEvents &&
                      <circle
                        cx={c.x} cy={c.y} r={r}
                        fill="none"
                        stroke={color}
                        strokeWidth="2"
                        opacity="0.65">
                        
                          <animate attributeName="r" from={r} to={r + 14} dur="2s" repeatCount="indefinite" />
                          <animate attributeName="opacity" from="0.65" to="0" dur="2s" repeatCount="indefinite" />
                        </circle>
                      }
                      <circle
                        cx={c.x} cy={c.y} r={r}
                        fill={color}
                        stroke="white"
                        strokeWidth="1.6"
                        style={{ cursor: 'pointer', transition: 'transform 150ms', transformOrigin: `${c.x}px ${c.y}px`, transform: isHover || isActive ? 'scale(1.18)' : 'scale(1)' }}
                        onClick={() => setActiveCity(c.name)}
                        onMouseEnter={() => setHoverCity(c.name)}
                        onMouseLeave={() => setHoverCity(null)} />
                      
                    </g>);

                })}
              </g>
            </svg>

            {/* Hover tooltip */}
            {hoverCity && !activeCity && (() => {
              const c = filteredCities.find((x) => x.name === hoverCity);
              if (!c) return null;
              return (
                <div className="emap-tooltip" style={{ left: `${c.x / 1000 * 100}%`, top: `${c.y / 620 * 100}%` }}>
                  <div className="emap-tt-name">{c.name}, {c.state}</div>
                  <div className="emap-tt-meta">{c.events.length} event{c.events.length !== 1 ? 's' : ''}</div>
                </div>);

            })()}
          </div>

          {/* Side panel */}
          <aside className={"emap-panel" + (active ? " open" : "")}>
            {!active &&
            <div className="emap-panel-empty">
                <div className="emap-panel-empty-icon">
                  <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" /><circle cx="12" cy="10" r="3" />
                  </svg>
                </div>
                <h3>Click any city</h3>
                <p>Dots are sized by how many cheer events we've ticketed there. Click any city to see the full lineup.</p>
                <div className="emap-top">
                  <div className="emap-top-head">Top 10 cities by events</div>
                  {[...filteredCities].sort((a, b) => b.events.length - a.events.length).slice(0, 10).map((c, i) =>
                <button key={c.name} className="emap-top-row" onClick={() => setActiveCity(c.name)}>
                      <span className="emap-top-rank">{i + 1}</span>
                      <span className="emap-top-city">{c.name}, {c.state}</span>
                      <span className="emap-top-count">{c.events.length}</span>
                    </button>
                )}
                </div>
              </div>
            }
            {active &&
            <div className="emap-panel-active">
                <div className="emap-panel-head">
                  <div>
                    <div className="emap-panel-state">{active.state}</div>
                    <h3>{active.name}</h3>
                    <div className="emap-panel-count">{active.events.length} event{active.events.length !== 1 ? 's' : ''}</div>
                  </div>
                  <button className="emap-panel-close" onClick={() => setActiveCity(null)} aria-label="Close">
                    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"><line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" /></svg>
                  </button>
                </div>
                <ul className="emap-event-list">
                  {active.events.map((e, i) =>
                <li key={i} className="emap-event">
                      <div className="emap-event-row">
                        <span className="emap-event-sport" style={{ background: sportColor[e.sport] || '#00B5E2' }}>{e.sport}</span>
                      </div>
                      <div className="emap-event-name">{e.name}</div>
                    </li>
                )}
                </ul>
              </div>
            }
          </aside>
        </div>

        <div className="emap-totals">
          <div><strong>$27M+</strong><span>in ticket sales</span></div>
          <div><strong>1M+</strong><span>tickets sold</span></div>
        </div>
      </div>
    </section>);

}

function formatDateRange(start, end) {
  if (!start) return '';
  const s = new Date(start + 'T00:00:00');
  const e = end ? new Date(end + 'T00:00:00') : null;
  const opts = { month: 'short', day: 'numeric', year: 'numeric' };
  if (!e || start === end) return s.toLocaleDateString('en-US', opts);
  // Same month/year → "Apr 12–14, 2025"
  if (s.getFullYear() === e.getFullYear() && s.getMonth() === e.getMonth()) {
    return `${s.toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}–${e.getDate()}, ${e.getFullYear()}`;
  }
  return `${s.toLocaleDateString('en-US', opts)} – ${e.toLocaleDateString('en-US', opts)}`;
}

// us-atlas state names → 2-letter (subset of states represented)
function stateAbbrev(name) {
  const map = {
    Alabama: 'AL', Alaska: 'AK', Arizona: 'AZ', Arkansas: 'AR', California: 'CA', Colorado: 'CO', Connecticut: 'CT',
    Delaware: 'DE', Florida: 'FL', Georgia: 'GA', Hawaii: 'HI', Idaho: 'ID', Illinois: 'IL', Indiana: 'IN', Iowa: 'IA',
    Kansas: 'KS', Kentucky: 'KY', Louisiana: 'LA', Maine: 'ME', Maryland: 'MD', Massachusetts: 'MA', Michigan: 'MI',
    Minnesota: 'MN', Mississippi: 'MS', Missouri: 'MO', Montana: 'MT', Nebraska: 'NE', Nevada: 'NV', 'New Hampshire': 'NH',
    'New Jersey': 'NJ', 'New Mexico': 'NM', 'New York': 'NY', 'North Carolina': 'NC', 'North Dakota': 'ND', Ohio: 'OH',
    Oklahoma: 'OK', Oregon: 'OR', Pennsylvania: 'PA', 'Rhode Island': 'RI', 'South Carolina': 'SC', 'South Dakota': 'SD',
    Tennessee: 'TN', Texas: 'TX', Utah: 'UT', Vermont: 'VT', Virginia: 'VA', Washington: 'WA', 'West Virginia': 'WV',
    Wisconsin: 'WI', Wyoming: 'WY', 'District of Columbia': 'DC'
  };
  return map[name] || '';
}