const { useState } = React;

/* Mobile-first — single column, ≤420px content width.
   Bottom tab bar instead of top nav. Sticky bottom CTAs.
   Tap targets ≥48px; primary CTA 56px. */

function TopBar({ title, onBack }) {
  return (
    <header style={{
      background: '#fff', borderBottom: '1px solid #d4c4a8',
      position: 'sticky', top: 0, zIndex: 10,
      display: 'flex', alignItems: 'center', gap: 8,
      padding: '10px 12px', minHeight: 56, boxSizing: 'border-box',
    }}>
      {onBack ? (
        <button onClick={onBack} aria-label="Zpět" style={{
          width: 44, height: 44, borderRadius: 12, background: 'transparent',
          border: 'none', fontSize: 22, color: 'var(--zk-brown)', cursor: 'pointer',
          fontFamily: 'inherit', display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>←</button>
      ) : (
        <img src={(window.__resources && window.__resources.logo) || "../../assets/logo-llama.jpeg"} width="40" height="40" alt="" style={{ borderRadius: 8, objectFit: 'cover', marginLeft: 4 }} />
      )}
      <div style={{ flex: 1, minWidth: 0 }}>
        {onBack ? (
          <div style={{ fontSize: 17, fontWeight: 800, color: 'var(--zk-brown)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{title}</div>
        ) : (
          <>
            <div style={{ fontSize: 16, fontWeight: 800, color: 'var(--zk-brown)', lineHeight: 1.1 }}>Zookoutek</div>
            <div style={{ fontSize: 12, color: 'var(--zk-brown-soft)', lineHeight: 1.1, marginTop: 1 }}>u Nováčků</div>
          </>
        )}
      </div>
    </header>
  );
}

function TabBar({ view, setView }) {
  const tabs = [
    ['catalog', '🧭', 'Trasy'],
    ['shop', '🛒', 'Obchod'],
    ['about', '🏡', 'O nás'],
  ];
  return (
    <nav style={{
      position: 'absolute', left: 0, right: 0, bottom: 0,
      background: '#fff', borderTop: '1px solid #d4c4a8',
      display: 'flex', zIndex: 20,
      paddingBottom: 'env(safe-area-inset-bottom)',
    }}>
      {tabs.map(([k, e, l]) => (
        <button key={k} onClick={() => setView(k)} style={{
          flex: 1, minHeight: 56, background: 'transparent', border: 'none',
          display: 'flex', flexDirection: 'column', alignItems: 'center',
          gap: 2, padding: '8px 4px', cursor: 'pointer', fontFamily: 'inherit',
          color: view === k ? 'var(--zk-brown)' : 'var(--zk-brown-soft)',
        }}>
          <div style={{ fontSize: 22, lineHeight: 1 }}>{e}</div>
          <div style={{ fontSize: 12, fontWeight: view === k ? 800 : 700 }}>{l}</div>
        </button>
      ))}
    </nav>
  );
}

/* Strukturované filtry — 4 dimenze odpovídající backend modelu:
     x_region | x_age (small/big/adult) | x_theme | x_difficulty
   Mobilně: kompaktní řádek s počtem aktivních + sheet pro detailní výběr.
   Stavem je objekt { region, age, theme, difficulty, sort }. */

const REGIONS = [
  ['jihomoravsky','Jihomoravský'], ['praha','Praha'], ['stredocesky','Středočeský'],
  ['vysocina','Vysočina'], ['moravskoslezsky','Moravskoslezský'], ['plzensky','Plzeňský'],
  ['karlovarsky','Karlovarský'], ['ustecky','Ústecký'], ['liberecky','Liberecký'],
  ['kralovehradecky','Královéhradecký'], ['pardubicky','Pardubický'], ['jihocesky','Jihočeský'],
  ['olomoucky','Olomoucký'], ['zlinsky','Zlínský'],
];
const AGES = [['small','3–6'], ['big','6–12'], ['adult','12+']];
const THEMES = [
  ['priroda','🌿 Příroda'], ['pohadka','🧚 Pohádka'], ['dobrodruzstvi','🗺️ Dobrodružství'],
  ['vzdelavani','📖 Vzdělávání'], ['historie','🏰 Historie'], ['mesto','🏙️ Město'], ['sport','🏃 Sport'],
];
const DIFFS = [['easy','🟢 Lehká'], ['medium','🟡 Střední'], ['hard','🔴 Těžká']];
const SORTS = [['nearby','📍 Nejbližší'], ['newest','🆕 Nejnovější'], ['rated','⭐ Nejlépe hodnocené'], ['short','🚶 Nejkratší']];

function countActive(f) {
  return (f.region ? 1 : 0) + (f.age ? 1 : 0) + (f.theme ? 1 : 0) + (f.difficulty ? 1 : 0);
}

function FilterBar({ filter, setFilter, onOpenSheet, onOpenMap, mapMode }) {
  const n = countActive(filter);
  const pillBase = {
    flex: '0 0 auto', height: 38, padding: '0 14px', borderRadius: 999,
    fontSize: 13, fontWeight: 700, cursor: 'pointer', fontFamily: 'inherit',
    whiteSpace: 'nowrap', display: 'inline-flex', alignItems: 'center', gap: 6,
  };
  const sortLabel = (SORTS.find(s => s[0] === filter.sort) || SORTS[0])[1];
  return (
    <div style={{
      display: 'flex', gap: 8, overflowX: 'auto', WebkitOverflowScrolling: 'touch',
      padding: '0 16px 4px', margin: '0 -16px 14px', scrollbarWidth: 'none',
    }}>
      <button onClick={onOpenSheet} style={{
        ...pillBase, background: n ? 'var(--zk-brown)' : '#fff',
        color: n ? '#fff' : 'var(--zk-brown)', border: `1px solid ${n ? 'var(--zk-brown)' : 'var(--zk-border)'}`,
      }}>⚙️ Filtry{n > 0 && <span style={{
        background: 'var(--zk-orange)', color: '#fff', borderRadius: 999, padding: '1px 7px', fontSize: 11, fontWeight: 800,
      }}>{n}</span>}</button>
      <button onClick={onOpenMap} style={{
        ...pillBase, background: mapMode ? 'var(--zk-orange)' : '#fff', color: mapMode ? '#fff' : 'var(--zk-brown)',
        border: `1px solid ${mapMode ? 'var(--zk-orange)' : 'var(--zk-border)'}`,
      }}>🗺️ Mapa</button>
      <div style={{ flex: '0 0 1px', background: 'var(--zk-border)', margin: '6px 4px' }}/>
      <button onClick={() => setFilter({ ...filter, sort: filter.sort === 'rated' ? 'nearby' : 'rated' })}
        style={{ ...pillBase, background: '#fff', color: 'var(--zk-brown)', border: '1px solid #d4c4a8' }}>
        ↕️ {sortLabel}
      </button>
      {AGES.map(([k, l]) => (
        <button key={k} onClick={() => setFilter({ ...filter, age: filter.age === k ? null : k })} style={{
          ...pillBase, background: filter.age === k ? 'var(--zk-orange)' : '#fff',
          color: filter.age === k ? '#fff' : 'var(--zk-brown)',
          border: `1px solid ${filter.age === k ? 'var(--zk-orange)' : 'var(--zk-border)'}`,
        }}>👶 {l}</button>
      ))}
    </div>
  );
}

function FilterSheet({ filter, setFilter, onClose }) {
  const [draft, setDraft] = useState(filter);
  const set = (k, v) => setDraft(p => ({ ...p, [k]: p[k] === v ? null : v }));
  return (
    <div onClick={onClose} style={{
      position: 'fixed', inset: 0, background: 'rgba(90,58,30,0.45)', zIndex: 50,
      display: 'flex', alignItems: 'flex-end',
    }}>
      <div onClick={(e) => e.stopPropagation()} style={{
        background: 'var(--zk-cream)', width: '100%', maxWidth: 480, margin: '0 auto',
        borderTopLeftRadius: 22, borderTopRightRadius: 22,
        padding: 18, paddingBottom: 'calc(18px + env(safe-area-inset-bottom))',
        maxHeight: '85vh', overflowY: 'auto', boxShadow: '0 -8px 24px rgba(90,58,30,.18)',
      }}>
        <div style={{ width: 40, height: 4, background: 'var(--zk-border)', borderRadius: 4, margin: '0 auto 14px' }}/>
        <div style={{ display: 'flex', alignItems: 'center', marginBottom: 14 }}>
          <h2 style={{ fontSize: 20, fontWeight: 800, color: 'var(--zk-brown)', margin: 0, letterSpacing: '-0.01em' }}>Filtry</h2>
          <button onClick={() => setDraft({ region: null, age: null, theme: null, difficulty: null, sort: draft.sort })}
            style={{ marginLeft: 'auto', background: 'transparent', border: 'none', color: 'var(--zk-brown-soft)', fontSize: 13, fontWeight: 700, fontFamily: 'inherit', cursor: 'pointer' }}>Zrušit vše</button>
        </div>

        <FilterGroup title="Kraj" hint="x_region">
          {REGIONS.map(([k, l]) => (
            <ChipBtn key={k} active={draft.region === k} onClick={() => set('region', k)}>📍 {l}</ChipBtn>
          ))}
        </FilterGroup>

        <FilterGroup title="Věk dítěte" hint="x_age_*_on">
          {AGES.map(([k, l]) => (
            <ChipBtn key={k} active={draft.age === k} onClick={() => set('age', k)}>👶 {l} let</ChipBtn>
          ))}
        </FilterGroup>

        <FilterGroup title="Téma" hint="x_theme">
          {THEMES.map(([k, l]) => (
            <ChipBtn key={k} active={draft.theme === k} onClick={() => set('theme', k)}>{l}</ChipBtn>
          ))}
        </FilterGroup>

        <FilterGroup title="Obtížnost" hint="x_difficulty">
          {DIFFS.map(([k, l]) => (
            <ChipBtn key={k} active={draft.difficulty === k} onClick={() => set('difficulty', k)}>{l}</ChipBtn>
          ))}
        </FilterGroup>

        <FilterGroup title="Řadit podle">
          {SORTS.map(([k, l]) => (
            <ChipBtn key={k} active={draft.sort === k} onClick={() => setDraft(p => ({ ...p, sort: k }))}>{l}</ChipBtn>
          ))}
        </FilterGroup>

        <div style={{ height: 12 }}/>
        <div style={{ display: 'flex', gap: 8, position: 'sticky', bottom: 0, background: 'var(--zk-cream)', paddingTop: 8 }}>
          <button onClick={onClose} style={{
            flex: '0 0 110px', height: 52, background: '#fff', color: 'var(--zk-brown)',
            border: '1px solid #d4c4a8', borderRadius: 16, fontSize: 15, fontWeight: 700, fontFamily: 'inherit', cursor: 'pointer',
          }}>Zavřít</button>
          <button onClick={() => { setFilter(draft); onClose(); }} style={{
            flex: 1, height: 52, background: 'var(--zk-orange)', color: '#fff',
            border: 'none', borderRadius: 16, fontSize: 16, fontWeight: 800, fontFamily: 'inherit', cursor: 'pointer',
          }}>Použít{countActive(draft) > 0 && ` (${countActive(draft)})`}</button>
        </div>
      </div>
    </div>
  );
}

function FilterGroup({ title, hint, children }) {
  return (
    <div style={{ marginBottom: 18 }}>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginBottom: 8 }}>
        <h3 style={{ fontSize: 14, fontWeight: 800, color: 'var(--zk-brown)', margin: 0, textTransform: 'uppercase', letterSpacing: '.04em' }}>{title}</h3>
        {hint && <code style={{ fontFamily: 'ui-monospace, Menlo, monospace', fontSize: 11, color: 'var(--zk-brown-soft)' }}>{hint}</code>}
      </div>
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>{children}</div>
    </div>
  );
}

function ChipBtn({ active, onClick, children }) {
  return (
    <button onClick={onClick} style={{
      height: 38, padding: '0 14px', borderRadius: 999,
      background: active ? 'var(--zk-orange)' : '#fff',
      color: active ? '#fff' : 'var(--zk-brown)',
      border: `1px solid ${active ? 'var(--zk-orange)' : 'var(--zk-border)'}`,
      fontSize: 13, fontWeight: 700, cursor: 'pointer',
      fontFamily: 'inherit', whiteSpace: 'nowrap',
    }}>{children}</button>
  );
}

function MapView({ trails, onPick, onClose }) {
  // Leaflet + Mapy.cz outdoor (same tiles as engine.js)
  const containerRef = React.useRef(null);
  const mapRef = React.useRef(null);

  React.useEffect(() => {
    if (!containerRef.current) return;
    if (mapRef.current) { try { mapRef.current.remove(); } catch(e){} mapRef.current = null; }

    function init() {
      if (!window.L) { setTimeout(init, 200); return; }
      const points = trails.filter(t => t.lat && t.lng);
      const m = window.L.map(containerRef.current, { zoomControl: true, scrollWheelZoom: true })
        .setView([49.5, 16.5], 7);
      window.L.tileLayer(
        'https://api.mapy.cz/v1/maptiles/outdoor/256/{z}/{x}/{y}?apikey=nyEN0DoYhZat_CdtIHZ0jnCBq2vqvxOKd0lepCZpPjA',
        { attribution: '\u00a9 Mapy.cz', maxZoom: 19 }
      ).addTo(m);

      const bounds = [];
      points.forEach(t => {
        const html = '<div style="background:' + (t.locked ? 'var(--zk-border)' : 'var(--zk-orange)') + ';width:46px;height:46px;border-radius:50% 50% 50% 0;transform:rotate(-45deg);border:3px solid #fff;box-shadow:0 2px 8px rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;cursor:pointer"><span style="transform:rotate(45deg);font-size:22px">' + (t.locked ? '🔒' : t.emoji) + '</span></div>';
        const icon = window.L.divIcon({ html, className: '', iconSize: [52, 52], iconAnchor: [23, 46] });
        const marker = window.L.marker([t.lat, t.lng], { icon }).addTo(m);
        const safe = (s) => String(s || '').replace(/[<>"']/g, c => ({ '<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;' }[c]));
        marker.bindPopup(
          '<div style="font-weight:800;color:#5a3a1e;margin-bottom:4px">' + safe(t.emoji + ' ' + t.title) + '</div>' +
          '<div style="font-size:12px;color:#8a6a4a;margin-bottom:8px">' + safe(t.place || '') + '</div>' +
          '<a href="' + safe(t.url) + '" style="display:block;background:#ff8c42;color:#fff;text-align:center;padding:8px;border-radius:10px;text-decoration:none;font-weight:700">' + (t.locked ? '🔒 Detail' : '▶ Otevřít') + '</a>'
        );
        marker.on('click', () => onPick(t));
        bounds.push([t.lat, t.lng]);
      });
      if (bounds.length > 1) m.fitBounds(bounds, { padding: [30, 30] });
      else if (bounds.length === 1) m.setView(bounds[0], 13);
      mapRef.current = m;
    }
    init();
    return () => { if (mapRef.current) { try { mapRef.current.remove(); } catch(e){} mapRef.current = null; } };
  }, [trails]);

  return (
    <div style={{ position: 'relative' }}>
      <div ref={containerRef} style={{ height: 460, borderRadius: 14, border: '1px solid #d4c4a8', overflow: 'hidden' }}/>
      <div style={{ marginTop: 12, fontSize: 13, color: 'var(--zk-brown-soft)', textAlign: 'center' }}>
        Klepněte na pin pro detail trasy
      </div>
    </div>
  );
}
function TrailCard({ trail, onOpen }) {
  return (
    <article onClick={() => !trail.locked && onOpen()}
      style={{
        background: '#fff', border: '1px solid #d4c4a8', borderRadius: 14,
        overflow: 'hidden', boxShadow: '0 1px 2px rgba(90,58,30,.06)',
        cursor: trail.locked ? 'default' : 'pointer',
        opacity: trail.locked ? 0.6 : 1,
      }}>
      <div style={{ height: 120, background: trail.bg, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 60 }}>
        {trail.locked ? '🔒' : trail.emoji}
      </div>
      <div style={{ padding: 14 }}>
        <h3 style={{ fontSize: 18, fontWeight: 800, color: 'var(--zk-brown)', margin: '0 0 4px' }}>{trail.title}</h3>
        <div style={{ fontSize: 14, color: 'var(--zk-brown-soft)', marginBottom: 10 }}>{trail.place}</div>
        <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
          {trail.locked
            ? <span style={pillStyle('var(--zk-cream-deep)')}>🔒 Brzy</span>
            : trail.meta.map((m, i) => <span key={i} style={pillStyle('var(--zk-cream)')}>{m}</span>)}
        </div>
      </div>
    </article>
  );
}

const pillStyle = (bg) => ({
  display: 'inline-flex', alignItems: 'center', gap: 4,
  height: 26, padding: '0 10px', background: bg,
  border: '1px solid #d4c4a8', borderRadius: 999,
  fontSize: 12, fontWeight: 700, color: 'var(--zk-brown-soft)',
});

function CatalogView({ onOpenTrail }) {
  const [filter, setFilter] = useState({ region: null, age: null, theme: null, difficulty: null, sort: 'nearby' });
  const [sheetOpen, setSheetOpen] = useState(false);
  const [mapMode, setMapMode] = useState(false);

  // Live data from Odoo backend (window.__zooTrails is set by QWeb template)
  const REGION_LABELS = { jihomoravsky:'Jihomoravský', vysocina:'Vysočina', stredocesky:'Středočeský', praha:'Praha', moravskoslezsky:'Moravskoslezský', plzensky:'Plzeňský', karlovarsky:'Karlovarský', ustecky:'Ústecký', liberecky:'Liberecký', kralovehradecky:'Královéhradecký', pardubicky:'Pardubický', jihocesky:'Jihočeský', olomoucky:'Olomoucký', zlinsky:'Zlínský' };
  const _src = (window.__zooTrails && window.__zooTrails.length) ? window.__zooTrails : [
    { id: 'demo', slug: 'demo', emoji: '🦙', bg: 'var(--zk-theme-llama)', title: 'Demo trasa', place: 'Bosonohy · 1,8 km',
      region: null, ages: ['small','big'], theme: 'priroda', difficulty: 'easy',
      meta: ['🚶 1,8 km', '⏱️ 45 min', '🏁 6'], state: 'published', lat: 49.19, lng: 16.52, url: '/za-cecilem' },
  ];
  const trails = _src.map(t => ({
    id: t.id,
    slug: t.slug || ('g' + t.id),
    emoji: t.emoji || '🧭',
    bg: t.bg || t.color_bg || 'var(--zk-theme-llama)',
    title: t.title || t.name || 'Bez názvu',
    place: t.place || ((t.location || '') + (t.distance_km ? ' · ' + t.distance_km + ' km' : '')),
    region_label: REGION_LABELS[t.region] || t.region || '',
    region_key: t.region || '',
    ages: t.ages || [],
    theme: t.theme || '',
    difficulty: t.difficulty || '',
    meta: (t.meta && t.meta.length) ? t.meta : [
      t.distance_km ? ('🚶 ' + t.distance_km + ' km') : null,
      t.time_min ? ('⏱️ ' + t.time_min + ' min') : null,
      t.station_count ? ('🏁 ' + t.station_count) : null,
      (t.rating && t.rating_count) ? ('⭐ ' + (typeof t.rating === 'number' ? t.rating.toFixed(1) : t.rating)) : null,
    ].filter(Boolean),
    locked: t.state === 'draft' || !!t.locked,
    state: t.state || 'published',
    lat: t.lat || t.center_lat || 0,
    lng: t.lng || t.center_lng || 0,
    url: t.url || ('/' + (t.slug || ('g' + t.id))),
  }));

  const matches = (t) => {
    if (t.locked) return true;
    if (filter.region && t.region_key !== filter.region) return false;
    if (filter.age && !t.ages.includes(filter.age)) return false;
    if (filter.theme && t.theme !== filter.theme) return false;
    if (filter.difficulty && t.difficulty !== filter.difficulty) return false;
    return true;
  };
  const visible = trails.filter(matches);
  const count = visible.filter(t => !t.locked).length;

  return (
    <section>
      <h1 style={{ fontSize: 26, fontWeight: 800, color: 'var(--zk-brown)', margin: '0 0 4px', letterSpacing: '-0.01em' }}>Trasy</h1>
      <p style={{ fontSize: 15, color: 'var(--zk-brown)', margin: '0 0 14px', lineHeight: 1.5 }}>
        Najděte trasu pro vaši rodinu. U každého stanoviště krátký příběh a jeden úkol.
      </p>
      <FilterBar filter={filter} setFilter={setFilter}
        onOpenSheet={() => setSheetOpen(true)}
        onOpenMap={() => setMapMode(m => !m)} mapMode={mapMode}/>

      {!mapMode && (
        <div style={{ fontSize: 13, color: 'var(--zk-brown-soft)', marginBottom: 10 }}>
          {count} {count === 1 ? 'trasa' : count < 5 ? 'trasy' : 'tras'} {filter.region && `· ${REGION_LABELS[filter.region] || filter.region}`}
        </div>
      )}

      {mapMode
        ? <MapView trails={visible} onPick={onOpenTrail} onClose={() => setMapMode(false)}/>
        : (
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: 14 }}>
            {visible.length === 0 && (
              <div style={{ padding: 24, textAlign: 'center', background: '#fff', border: '1px dashed #d4c4a8', borderRadius: 14 }}>
                <div style={{ fontSize: 36, marginBottom: 8 }}>🦙</div>
                <div style={{ fontSize: 15, fontWeight: 700, color: 'var(--zk-brown)' }}>Žádná trasa neodpovídá</div>
                <div style={{ fontSize: 13, color: 'var(--zk-brown-soft)', marginTop: 4 }}>Zkuste uvolnit filtry.</div>
              </div>
            )}
            {visible.map(t => <TrailCard key={t.id} trail={t} onOpen={() => onOpenTrail(t)} />)}
          </div>
        )}

      {sheetOpen && <FilterSheet filter={filter} setFilter={setFilter} onClose={() => setSheetOpen(false)}/>}
    </section>
  );
}

function TrailDetailView({ trail, onBack, onStart }) {
  return (
    <section style={{ paddingBottom: 96 }}>
      <div style={{ background: trail.bg, borderRadius: 14, height: 180, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 88, border: '1px solid #d4c4a8', marginBottom: 14 }}>{trail.emoji}</div>
      <h1 style={{ fontSize: 26, fontWeight: 800, color: 'var(--zk-brown)', margin: '0 0 4px', letterSpacing: '-0.01em' }}>{trail.title}</h1>
      <div style={{ fontSize: 14, color: 'var(--zk-brown-soft)', marginBottom: 12 }}>{trail.place}</div>
      <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 14 }}>
        {(trail.meta && trail.meta.length ? trail.meta : ['🚶 1,8 km', '⏱️ 45 min', '🏁 6', '⭐ 4,8', '👶 3–12']).map((m, i) => (
          <span key={i} style={pillStyle('var(--zk-cream)')}>{m}</span>
        ))}
      </div>
      {trail.description ? (
        <p style={{ fontSize: 15, color: 'var(--zk-brown)', lineHeight: 1.55, margin: '0 0 16px' }}>
          {trail.description}
        </p>
      ) : null}
      <h2 style={{ fontSize: 18, fontWeight: 800, color: 'var(--zk-brown)', margin: '0 0 8px' }}>Stanoviště</h2>
      {(() => {
        const allStations = window.__zooStations || {};
        const stations = (allStations[trail.id] || []).slice().sort((a, b) => (a.num || 0) - (b.num || 0));
        const active = stations.filter(s => s.active !== false);
        const drafts = stations.filter(s => s.active === false);

        if (stations.length === 0) {
          return (
            <div style={{ background: '#fff', border: '1px dashed #d4c4a8', borderRadius: 14, padding: 20, textAlign: 'center', color: 'var(--zk-brown-soft)' }}>
              <div style={{ fontSize: 32, marginBottom: 6 }}>🌱</div>
              <div style={{ fontSize: 15, fontWeight: 700, color: 'var(--zk-brown)', marginBottom: 4 }}>Tato trasa zatím nemá stanoviště</div>
              <div style={{ fontSize: 13 }}>{trail.locked ? 'Připravujeme.' : 'Přidejte první stanoviště v gps-admin režimu.'}</div>
            </div>
          );
        }

        return (
          <>
            {active.length > 0 && (
              <ol style={{ listStyle: 'none', padding: 0, margin: '0 0 14px', display: 'flex', flexDirection: 'column', gap: 8 }}>
                {active.map((s, i) => (
                  <li key={s.id} style={{ display: 'flex', gap: 12, alignItems: 'center', background: '#fff', border: '1px solid #d4c4a8', borderRadius: 12, padding: '10px 12px' }}>
                    <div style={{ width: 32, height: 32, borderRadius: 999, background: 'var(--zk-theme-fox)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 14, fontWeight: 800, color: 'var(--zk-brown)', flex: '0 0 32px' }}>{s.num || (i + 1)}</div>
                    <div style={{ flex: 1, fontSize: 15, fontWeight: 700, color: 'var(--zk-brown)', overflow: 'hidden', textOverflow: 'ellipsis' }}>
                      {s.emoji ? <span style={{ marginRight: 6 }}>{s.emoji}</span> : null}
                      {s.title || ('Stanoviště ' + s.num)}
                    </div>
                    <div style={{ fontSize: 18 }}>🎧</div>
                  </li>
                ))}
              </ol>
            )}

            {drafts.length > 0 && (
              <div style={{ background: 'var(--zk-theme-llama)', border: '1px dashed #f39c12', borderRadius: 12, padding: 14, marginBottom: 14 }}>
                <div style={{ fontSize: 13, fontWeight: 800, color: 'var(--zk-brown-deep)', marginBottom: 8, textTransform: 'uppercase', letterSpacing: '.04em' }}>
                  📝 Surové body z průzkumu ({drafts.length})
                </div>
                <div style={{ fontSize: 12, color: 'var(--zk-brown-soft)', marginBottom: 10, lineHeight: 1.5 }}>
                  Tyto body teprve čekají na zpracování. Editor z nich vytvoří finální stanoviště s příběhem a úkoly.
                </div>
                <ol style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: 6 }}>
                  {drafts.slice(0, 12).map((s) => (
                    <li key={s.id} style={{ display: 'flex', gap: 10, alignItems: 'flex-start', background: '#fff', border: '1px solid #f5e0c0', borderRadius: 10, padding: '8px 10px' }}>
                      <div style={{ width: 24, height: 24, borderRadius: 999, background: 'var(--zk-orange)', color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 11, fontWeight: 800, flex: '0 0 24px' }}>{s.num}</div>
                      <div style={{ flex: 1, fontSize: 13, color: 'var(--zk-brown)', lineHeight: 1.4 }}>
                        {s.note ? s.note.substring(0, 140) + (s.note.length > 140 ? '…' : '') : (s.title || ('Bod ' + s.num))}
                      </div>
                    </li>
                  ))}
                  {drafts.length > 12 && (
                    <li style={{ fontSize: 12, color: 'var(--zk-brown-soft)', textAlign: 'center', padding: '6px 0' }}>… a dalších {drafts.length - 12}</li>
                  )}
                </ol>
              </div>
            )}
          </>
        );
      })()}
      <div style={{
        position: 'absolute', left: 0, right: 0, bottom: 0,
        background: '#fff', borderTop: '1px solid #d4c4a8',
        padding: '10px 12px', paddingBottom: 'calc(10px + env(safe-area-inset-bottom))',
        zIndex: 30, display: 'flex', gap: 8,
      }}>
        <button style={{
          width: 52, height: 56, background: '#fff', color: 'var(--zk-brown)',
          border: '1px solid #d4c4a8', borderRadius: 16, fontSize: 20,
          fontFamily: 'inherit', cursor: 'pointer', flex: '0 0 52px',
        }} aria-label="Poslat na telefon">🔗</button>
        {trail.locked ? (
          trail.survey_url ? (
            <a href={trail.survey_url} style={{
              flex: 1, height: 56, background: '#5dade2', color: '#fff',
              border: 'none', borderRadius: 16, fontSize: 16, fontWeight: 800,
              fontFamily: 'inherit', cursor: 'pointer', display: 'flex',
              alignItems: 'center', justifyContent: 'center', textDecoration: 'none',
            }}>🧭 Pomoci s průzkumem</a>
          ) : (
            <button disabled style={{
              flex: 1, height: 56, background: 'var(--zk-border)', color: '#fff',
              border: 'none', borderRadius: 16, fontSize: 16, fontWeight: 800,
              fontFamily: 'inherit', cursor: 'not-allowed',
            }}>🔒 Brzy k dispozici</button>
          )
        ) : (
          <button onClick={onStart} style={{
            flex: 1, height: 56, background: 'var(--zk-orange)', color: '#fff',
            border: 'none', borderRadius: 16, fontSize: 18, fontWeight: 800,
            fontFamily: 'inherit', cursor: 'pointer',
          }}>▶ Začít hrát</button>
        )}
      </div>
    </section>
  );
}

function ShopView() {
  const products = [
    { emoji: '🍯', title: 'Med z Bosonoh', price: '180 Kč', sub: '450 g · lipový' },
    { emoji: '🧀', title: 'Kozí sýr', price: '140 Kč', sub: '200 g · čerstvý' },
    { emoji: '🥚', title: 'Vejce z farmy', price: '90 Kč', sub: '10 ks · domácí' },
    { emoji: '🧴', title: 'Mýdlo s mlékem', price: '120 Kč', sub: '100 g · ručně' },
  ];
  return (
    <section>
      <h1 style={{ fontSize: 26, fontWeight: 800, color: 'var(--zk-brown)', margin: '0 0 4px', letterSpacing: '-0.01em' }}>Obchod</h1>
      <p style={{ fontSize: 15, color: 'var(--zk-brown)', margin: '0 0 16px', lineHeight: 1.5 }}>
        Pár věcí přímo z našeho zookoutku. Sběrné místo v Bosonohách, zasíláme i poštou.
      </p>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(180px, 1fr))', gap: 12 }}>
        {products.map((p, i) => (
          <article key={i} style={{ background: '#fff', border: '1px solid #d4c4a8', borderRadius: 14, overflow: 'hidden' }}>
            <div style={{ height: 100, background: 'var(--zk-cream-deep)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 48 }}>{p.emoji}</div>
            <div style={{ padding: 12 }}>
              <div style={{ fontSize: 15, fontWeight: 800, color: 'var(--zk-brown)', lineHeight: 1.2 }}>{p.title}</div>
              <div style={{ fontSize: 12, color: 'var(--zk-brown-soft)', marginTop: 2 }}>{p.sub}</div>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 10, gap: 6 }}>
                <div style={{ fontSize: 16, fontWeight: 800, color: 'var(--zk-brown)' }}>{p.price}</div>
                <button style={{ height: 36, padding: '0 12px', background: 'var(--zk-orange)', color: '#fff', border: 'none', borderRadius: 12, fontWeight: 800, fontSize: 13, cursor: 'pointer', fontFamily: 'inherit' }}>+ Košík</button>
              </div>
            </div>
          </article>
        ))}
      </div>
    </section>
  );
}

function AboutView() {
  return (
    <section>
      <h1 style={{ fontSize: 26, fontWeight: 800, color: 'var(--zk-brown)', margin: '0 0 12px', letterSpacing: '-0.01em' }}>O nás</h1>
      <p style={{ fontSize: 16, color: 'var(--zk-brown)', lineHeight: 1.6, margin: '0 0 14px' }}>
        Zookoutek u Nováčků je malý rodinný zookoutek v Brně-Bosonohách. Staráme se o pár kravek, kozy, slepice, lamu a další zvířata. Děláme také procházkové trasy pro rodiny s dětmi.
      </p>
      <p style={{ fontSize: 15, color: 'var(--zk-brown)', lineHeight: 1.6, margin: '0 0 14px' }}>
        Jsme dobrovolnický projekt. Když něco funguje divně, napište nám.
      </p>
      <div style={{ background: '#fff', border: '1px solid #d4c4a8', borderRadius: 14, padding: 14 }}>
        <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--zk-brown-soft)', textTransform: 'uppercase', letterSpacing: '.04em', marginBottom: 6 }}>Kontakt</div>
        <div style={{ fontSize: 15, color: 'var(--zk-brown)', lineHeight: 1.6 }}>
          📍 Bosonohy, Brno<br/>
          ✉️ ahoj@zookoutekunovacku.cz<br/>
          🌐 zookoutekunovacku.cz
        </div>
      </div>
    </section>
  );
}

function CatalogApp() {
  // Klik na trasu: navigace na /hrat?game=<slug> (rich detail page v QWeb).
  // TopBar a TabBar odstraněny — Odoo header + footer (website.layout) jsou nadřazené.
  const openTrail = (t) => {
    const slug = t.slug || t.url.split('=').pop();
    window.location.href = '/hrat?game=' + slug;
  };
  return (
    <div style={{ background: 'var(--zk-cream)', fontFamily: 'system-ui, -apple-system, "Segoe UI", Roboto, sans-serif', color: 'var(--zk-brown)' }}>
      <main style={{ padding: '16px 16px 80px', maxWidth: 1100, margin: '0 auto' }}>
        <CatalogView onOpenTrail={openTrail} />
      </main>
    </div>
  );
}

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