/* eslint-disable */
const { useState, useEffect, useMemo, useCallback } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "showGantt": true,
  "showAds": false,
  "mapStyle": "light",
  "accentColor": "#c84a1a",
  "sidebarWidth": 460,
  "detailWidth": 520
}/*EDITMODE-END*/;

function App() {
  const [data, setData] = useState(null);
  const [selectedId, setSelectedId] = useState(null);
  const [filterTypes, setFilterTypes] = useState([]);
  const [weekendOnly, setWeekendOnly] = useState(false);
  const [sortBy, setSortBy] = useState('date');
  const [cityFilter, setCityFilter] = useState(null);
  const [likes, setLikes] = useState({});
  const [showMapAd, setShowMapAd] = useState(true);
  const [cookieConsent, setCookieConsent] = useState(() => localStorage.getItem('cookie_consent'));

  const acceptCookies = useCallback(() => {
    localStorage.setItem('cookie_consent', 'accepted');
    setCookieConsent('accepted');
  }, []);
  const declineCookies = useCallback(() => {
    localStorage.setItem('cookie_consent', 'declined');
    setCookieConsent('declined');
  }, []);

  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [isMobile, setIsMobile] = useState(() => window.matchMedia('(max-width: 768px)').matches);
  useEffect(() => {
    const mq = window.matchMedia('(max-width: 768px)');
    const handler = e => setIsMobile(e.matches);
    mq.addEventListener('change', handler);
    return () => mq.removeEventListener('change', handler);
  }, []);

  // Load data
  useEffect(() => {
    fetch('data/mostre.json?v=20260512')
      .then(r => r.json())
      .then(d => {
        const enriched = d.mostre.map((m, i) => ({
          ...m,
          _id: i + 1,
          _baseLikes: 12 + ((i * 37) % 180), // deterministic pseudo-random
        }));
        setData({ ...d, mostre: enriched });
      });
  }, []);

  // JSON-LD eventi
  useEffect(() => {
    if (!data) return;
    const existing = document.getElementById('ld-events');
    if (existing) existing.remove();
    const script = document.createElement('script');
    script.id = 'ld-events';
    script.type = 'application/ld+json';
    script.text = JSON.stringify({
      '@context': 'https://schema.org',
      '@type': 'ItemList',
      'name': 'Mostre di fotografia in Italia 2026',
      'itemListElement': data.mostre.map((m, i) => ({
        '@type': 'ListItem',
        'position': i + 1,
        'item': {
          '@type': 'ExhibitionEvent',
          'name': m.titolo,
          'startDate': m.data_inizio,
          'endDate': m.data_fine,
          'description': m.descrizione,
          'url': m.url_riferimento,
          'image': m.url_immagine || undefined,
          'location': {
            '@type': 'Place',
            'name': m.sede,
            'address': { '@type': 'PostalAddress', 'streetAddress': m.indirizzo, 'addressLocality': m.citta, 'addressCountry': 'IT' },
            'geo': { '@type': 'GeoCoordinates', 'latitude': m.latitudine, 'longitude': m.longitudine }
          },
          ...(m.curatori && { 'organizer': m.curatori.map(c => ({ '@type': 'Person', 'name': c })) })
        }
      }))
    });
    document.head.appendChild(script);
  }, [data]);

  // Apply accent color tweak
  useEffect(() => {
    document.documentElement.style.setProperty('--accent', tweaks.accentColor);
    // also recompute soft & current tint
    const c = tweaks.accentColor;
    document.documentElement.style.setProperty('--accent-soft', `${c}14`);
  }, [tweaks.accentColor]);
  useEffect(() => {
    document.documentElement.style.setProperty('--sidebar-w', `${tweaks.sidebarWidth}px`);
    document.documentElement.style.setProperty('--detail-w', `${tweaks.detailWidth}px`);
  }, [tweaks.sidebarWidth, tweaks.detailWidth]);

  const filtered = useMemo(() => {
    if (!data) return [];
    let list = data.mostre.slice();
    if (filterTypes.length > 0) list = list.filter(m => filterTypes.includes(m.tipo));
    if (cityFilter) list = list.filter(m => m.citta === cityFilter);
    if (weekendOnly) list = list.filter(m => {
      const s = window.dateUtils.parseDate(m.data_inizio);
      const e = window.dateUtils.parseDate(m.data_fine);
      // active during Sat May 16 or Sun May 17 2026
      const sat = new Date('2026-05-16T12:00:00');
      const sun = new Date('2026-05-17T12:00:00');
      return (s <= sun && e >= sat);
    });
    if (sortBy === 'date') list.sort((a,b) => a.data_inizio.localeCompare(b.data_inizio));
    if (sortBy === 'city') list.sort((a,b) => a.citta.localeCompare(b.citta) || a.data_inizio.localeCompare(b.data_inizio));
    if (sortBy === 'popular') list.sort((a,b) => {
      const al = likes[a._id] !== undefined ? likes[a._id] : a._baseLikes;
      const bl = likes[b._id] !== undefined ? likes[b._id] : b._baseLikes;
      return bl - al;
    });
    return list;
  }, [data, filterTypes, weekendOnly, sortBy, cityFilter, likes]);

  const onLike = useCallback((id) => {
    setLikes(prev => {
      if (prev[id] !== undefined) {
        const { [id]: _, ...rest } = prev;
        return rest;
      }
      const base = data.mostre.find(m => m._id === id)._baseLikes;
      return { ...prev, [id]: base + 1 };
    });
  }, [data]);

  const selectedEvent = useMemo(
    () => data ? data.mostre.find(m => m._id === selectedId) : null,
    [data, selectedId]
  );

  if (!data) {
    return (
      <div className="app-loading">CARICAMENTO…</div>
    );
  }

  const likedCount = Object.keys(likes).length;

  return (
    <div className={`app ${selectedId ? 'has-detail' : ''}`}>
      <Header totalCount={filtered.length} likedCount={likedCount} />
      <FilterBar
        filterTypes={filterTypes}
        setFilterTypes={setFilterTypes}
        weekendOnly={weekendOnly}
        setWeekendOnly={setWeekendOnly}
        sortBy={sortBy}
        setSortBy={setSortBy}
        count={filtered.length}
      />
      <div className={`app-body ${selectedId ? 'with-detail' : ''}`}>
        <Sidebar
          events={filtered}
          selectedId={selectedId}
          onSelect={setSelectedId}
          likes={likes}
          onLike={onLike}
          showGantt={tweaks.showGantt}
          showAds={tweaks.showAds && cookieConsent === 'accepted'}
        />
        {selectedEvent && (
          <DetailPanel
            event={selectedEvent}
            onClose={() => setSelectedId(null)}
            likes={likes}
            onLike={onLike}
          />
        )}
        {!isMobile && (
          <MapPanel
            events={filtered}
            selectedId={selectedId}
            onSelect={setSelectedId}
            cityFilter={cityFilter}
            setCityFilter={setCityFilter}
            showMapAd={tweaks.showAds && showMapAd && cookieConsent === 'accepted'}
            dismissMapAd={() => setShowMapAd(false)}
            mapStyle={tweaks.mapStyle}
          />
        )}
      </div>
      {cookieConsent === null && (
        <CookieBanner onAccept={acceptCookies} onDecline={declineCookies} />
      )}
      <TweaksPanel title="Tweaks">
        <TweakSection label="Layout">
          <TweakToggle label="Mostra calendario Gantt" value={tweaks.showGantt} onChange={v => setTweak('showGantt', v)} />
          <TweakToggle label="Banner pubblicitari" value={tweaks.showAds} onChange={v => setTweak('showAds', v)} />
        </TweakSection>
        <TweakSection label="Mappa">
          <TweakRadio
            label="Stile mappa"
            value={tweaks.mapStyle}
            options={[{value:'light', label:'Chiara'}, {value:'dark', label:'Scura'}]}
            onChange={v => setTweak('mapStyle', v)}
          />
        </TweakSection>
        <TweakSection label="Accento">
          <TweakColor
            label="Colore accento"
            value={tweaks.accentColor}
            options={['#c84a1a','#1a1a1a','#3a5a40','#1c5078','#9b2c2c']}
            onChange={v => setTweak('accentColor', v)}
          />
        </TweakSection>
        <TweakSection label="Dimensioni">
          <TweakSlider label="Larghezza lista" min={380} max={560} step={10} value={tweaks.sidebarWidth} onChange={v => setTweak('sidebarWidth', v)} />
          <TweakSlider label="Larghezza dettaglio" min={420} max={640} step={10} value={tweaks.detailWidth} onChange={v => setTweak('detailWidth', v)} />
        </TweakSection>
      </TweaksPanel>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
