// Main app — likovne-delavnice.si
const { useState, useEffect, useMemo, useRef } = React;

const API = typeof window.getApiBase === "function" ? window.getApiBase() : "http://127.0.0.1:8001/api";

function normaliseTags(raw) {
  if (Array.isArray(raw)) return raw.map(String);
  if (typeof raw === "string") {
    try {
      const p = JSON.parse(raw);
      return Array.isArray(p) ? p.map(String) : [];
    } catch {
      return [];
    }
  }
  return [];
}

// Normalise DB row → shape the rest of the app expects
function normaliseWorkshop(w) {
  if (!w || typeof w !== "object") return null;
  const revN = Math.max(0, parseInt(w.reviews, 10) || 0);
  const rating = revN > 0 ? (Number(w.rating) || 0) : 0;
  return {
    ...w,
    title:       w.title != null ? String(w.title) : "",
    host:        w.host != null ? String(w.host) : "",
    city:        w.city != null ? String(w.city) : "",
    blurb:       w.blurb != null ? String(w.blurb) : "",
    category:    w.category != null ? String(w.category) : "mixed",
    tags:        normaliseTags(w.tags),
    featured:    !!w.featured,
    hostBio:     w.host_bio || w.hostBio || "",
    sourceUrl:   w.source_url || w.sourceUrl || "",
    imageUrl:    w.image_url || w.imageUrl || null,
    lastCrawled:   w.last_crawled || w.lastCrawled || "",
    scheduleType:  w.schedule_type || w.scheduleType || "recurring",
    nextDate:      w.next_date || w.nextDate || null,
    forKids:       !!(w.for_kids || w.forKids),
    forAdults:     !(w.for_kids || w.forKids),
    teamBuilding:  !!(w.team_building || w.teamBuilding),
    capacity:      (() => {
      const c = w.capacity;
      if (c == null || c === "") return null;
      const n = parseInt(c, 10);
      return Number.isFinite(n) && n > 0 ? n : null;
    })(),
    reviews:       revN,
    rating,
  };
}

const TWEAKS_DEFAULTS = {
  palette: "default", fonts: "editorial", cardStyle: "mixed",
  density: "normal", hero: "editorial",
};

const PALETTES  = [
  { id: "default", label: "Cream", sw: "#f4efe6" },
  { id: "gallery", label: "Gallery", sw: "#fafaf7" },
  { id: "earth",   label: "Earth",   sw: "#efe8dc" },
  { id: "alpine",  label: "Alpine",  sw: "#eef1ea" },
  { id: "electric",label: "Electric",sw: "#ff6030" },
];
const FONT_SETS = [
  { id: "editorial", label: "Editorial" }, { id: "modern",    label: "Modern" },
  { id: "classical", label: "Classical" }, { id: "bold",      label: "Bold" },
];
const CARD_STYLES = [
  { id: "mixed", label: "Mixed" }, { id: "grid",   label: "Grid" },
  { id: "rows",  label: "Rows" },  { id: "poster", label: "Poster" },
];
const DENSITIES = [
  { id: "compact", label: "Compact" }, { id: "normal",   label: "Normal" },
  { id: "spacious",label: "Spacious" },
];
const HEROES = [
  { id: "editorial", label: "Editorial" }, { id: "block",  label: "Block" },
  { id: "poster",    label: "Poster" },
];

// ─── App ────────────────────────────────────────────────────────────────────
function App() {
  const [workshops, setWorkshops] = useState([]);
  const [loading, setLoading] = useState(true);

  const refreshWorkshop = () => {
    fetch(`${API}/workshops`)
      .then(r => r.ok ? r.json() : null)
      .then(data => {
        if (!Array.isArray(data)) return;
        setWorkshops(data.map(normaliseWorkshop).filter(Boolean));
      })
      .catch(() => {});
  };

  useEffect(() => {
    fetch(`${API}/workshops`)
      .then(r => {
        if (!r.ok) throw new Error(String(r.status));
        return r.json();
      })
      .then(data => {
        const list = Array.isArray(data) ? data : [];
        setWorkshops(list.map(normaliseWorkshop).filter(Boolean));
        setLoading(false);
      })
      .catch(() => {
        setLoading(false);
      });
  }, []);

  const [lang, setLang] = useState("sl");
  const [tweaks, setTweaks] = useState(TWEAKS_DEFAULTS);
  const [showTweaks, setShowTweaks] = useState(false);
  const [query, setQuery] = useState("");
  const [activeCategory, setActiveCategory] = useState(null);
  const [activeCity, setActiveCity] = useState(null);
  const [priceMax, setPriceMax] = useState(150);
  const [minRating, setMinRating] = useState(0);
  const [scheduleFilter, setScheduleFilter] = useState("all");
  const [audienceFilter, setAudienceFilter] = useState("all");
  const [showFavsOnly, setShowFavsOnly] = useState(false);
  const [view, setView] = useState("list");
  const [sort, setSort] = useState("featured");
  const [filtersOpen, setFiltersOpen] = useState(false);
  const feedRef = useRef(null);

  const [favs, setFavs] = useState(() => {
    try { return JSON.parse(localStorage.getItem("ld_favs") || "[]"); } catch { return []; }
  });
  const [userRatings, setUserRatings] = useState(() => {
    try { return JSON.parse(localStorage.getItem("ld_ratings") || "{}"); } catch { return {}; }
  });
  const [modalId, setModalId] = useState(null);
  const [user, setUser] = useState(() => {
    try { return JSON.parse(localStorage.getItem("ld_user") || "null"); } catch { return null; }
  });
  const [authOpen, setAuthOpen] = useState(false);
  const [submitOpen, setSubmitOpen] = useState(false);
  const [userMenu, setUserMenu] = useState(false);
  const [reviews, setReviews] = useState(() => {
    try { return JSON.parse(localStorage.getItem("ld_reviews") || "{}"); } catch { return {}; }
  });
  const [userSubmissions, setUserSubmissions] = useState(() => {
    try { return JSON.parse(localStorage.getItem("ld_submissions") || "[]"); } catch { return []; }
  });

  useEffect(() => { localStorage.setItem("ld_favs", JSON.stringify(favs)); }, [favs]);
  useEffect(() => { localStorage.setItem("ld_ratings", JSON.stringify(userRatings)); }, [userRatings]);
  useEffect(() => { localStorage.setItem("ld_user", JSON.stringify(user)); }, [user]);
  useEffect(() => { localStorage.setItem("ld_reviews", JSON.stringify(reviews)); }, [reviews]);
  useEffect(() => { localStorage.setItem("ld_submissions", JSON.stringify(userSubmissions)); }, [userSubmissions]);

  useEffect(() => {
    document.body.className = `palette-${tweaks.palette} fonts-${tweaks.fonts} hero-${tweaks.hero}`;
  }, [tweaks]);

  useEffect(() => {
    const onMsg = e => {
      const d = e.data || {};
      if (d.type === "__activate_edit_mode") setShowTweaks(true);
      if (d.type === "__deactivate_edit_mode") setShowTweaks(false);
    };
    window.addEventListener("message", onMsg);
    window.parent.postMessage({ type: "__edit_mode_available" }, "*");
    return () => window.removeEventListener("message", onMsg);
  }, []);

  const t = STRINGS[lang];
  const activeFilterCount = (activeCategory ? 1 : 0) + (activeCity ? 1 : 0) + (priceMax < 150 ? 1 : 0) + (minRating > 0 ? 1 : 0) + (scheduleFilter !== "all" ? 1 : 0) + (audienceFilter !== "all" ? 1 : 0) + (showFavsOnly ? 1 : 0);

  const clearAllFilters = () => {
    setActiveCategory(null); setActiveCity(null); setPriceMax(150);
    setMinRating(0); setScheduleFilter("all"); setAudienceFilter("all"); setShowFavsOnly(false);
  };

  const renderFilters = () => (
    <>
      {activeFilterCount > 0 && (
        <div className="sidebar-section" style={{paddingBottom:0}}>
          <button className="clear-filters-btn" onClick={clearAllFilters}>
            ✕ {lang === "en" ? `Clear ${activeFilterCount} filter${activeFilterCount > 1 ? "s" : ""}` : `Počisti filtre (${activeFilterCount})`}
          </button>
        </div>
      )}
      <div className="sidebar-section">
        <h4>{t.view}</h4>
        <div className="view-toggle">
          <button className={view === "list" ? "on" : ""} onClick={() => setView("list")}>{t.list}</button>
          <button className={view === "map"  ? "on" : ""} onClick={() => setView("map")}>{t.map}</button>
        </div>
      </div>
      <div className="sidebar-section">
        <h4>
          {t.mapSlovenia}
          {activeCity && (
            <a href="#" onClick={e => { e.preventDefault(); setActiveCity(null); }}
               style={{color:"var(--muted)",fontSize:"10px",marginLeft:"6px"}}>{t.clear}</a>
          )}
        </h4>
        <SloveniaMap workshops={workshops} activeCity={activeCity}
          onCityClick={c => setFilter(setActiveCity)(activeCity === c ? null : c)} mini />
      </div>
      <div className="sidebar-section">
        <h4>{t.price}</h4>
        <div className="price-slider">
          <div className="price-range-row">
            <span>0€</span>
            <span><b>{lang === "en" ? `up to €${priceMax}` : `do ${priceMax}€`}</b></span>
          </div>
          <input type="range" min="10" max="150" step="5" value={priceMax}
                 onChange={e => setFilter(setPriceMax)(+e.target.value)} />
        </div>
      </div>
      <div className="sidebar-section">
        <h4>{lang === "en" ? "Min. rating" : "Min. ocena"}</h4>
        <div className="rate-filter">
          {[0,1,2,3,4,5].map(r => (
            <button key={r}
              className={`rate-filter-btn ${minRating === r ? "on" : ""}`}
              onClick={() => setFilter(setMinRating)(r)}>
              {r === 0
                ? (lang === "en" ? "All" : "Vse")
                : ("★".repeat(r) + "☆".repeat(5 - r))}
            </button>
          ))}
        </div>
      </div>
      <div className="sidebar-section">
        <h4>{lang === "en" ? "Audience" : "Za koga"}</h4>
        <div className="rate-filter">
          {[
            { id: "all",    sl: "Vsi",        en: "Everyone" },
            { id: "kids",   sl: "Za otroke",  en: "Kids" },
            { id: "adults", sl: "Za odrasle", en: "Adults" },
          ].map(a => (
            <button key={a.id}
              className={`rate-filter-btn ${audienceFilter === a.id ? "on" : ""}`}
              onClick={() => setFilter(setAudienceFilter)(a.id)}>
              {lang === "en" ? a.en : a.sl}
            </button>
          ))}
        </div>
      </div>
      <div className="sidebar-section">
        <h4>{lang === "en" ? "Workshop type" : "Vrsta delavnice"}</h4>
        <div className="rate-filter">
          {[
            { id: "all",       sl: "Vse",        en: "All" },
            { id: "one-time",  sl: "Enkratno",   en: "One-time" },
            { id: "weekly",    sl: "Tedensko",   en: "Weekly" },
            { id: "monthly",   sl: "Mesečno",    en: "Monthly" },
            { id: "recurring", sl: "Redno",      en: "Regular" },
          ].map(s => (
            <button key={s.id}
              className={`rate-filter-btn ${scheduleFilter === s.id ? "on" : ""}`}
              onClick={() => setFilter(setScheduleFilter)(s.id)}>
              {lang === "en" ? s.en : s.sl}
            </button>
          ))}
        </div>
      </div>
      <div className="sidebar-section">
        <button
          className={`rate-filter-btn ${showFavsOnly ? "on" : ""}`}
          style={{width:"100%"}}
          onClick={() => setShowFavsOnly(f => !f)}>
          {showFavsOnly
            ? (lang === "en" ? "♥ Showing saved" : "♥ Prikazujem shranjene")
            : (lang === "en" ? "♥ Show saved only" : "♥ Samo shranjeni")}
          {favs.length > 0 && <span style={{marginLeft:"6px",opacity:0.6}}>({favs.length})</span>}
        </button>
      </div>
    </>
  );
  const updateTweak = (key, value) => {
    const next = { ...tweaks, [key]: value };
    setTweaks(next);
    window.parent.postMessage({ type: "__edit_mode_set_keys", edits: { [key]: value } }, "*");
  };

  const toggleFav = id => setFavs(f => f.includes(id) ? f.filter(x => x !== id) : [...f, id]);
  const setUserRating = (id, r) => setUserRatings(rs => ({ ...rs, [id]: r }));
  const addReview = (wid, review) => setReviews(rs => ({ ...rs, [wid]: [review, ...(rs[wid] || [])] }));
  const requireLogin = () => setAuthOpen(true);
  const tryOpenSubmit = () => { if (!user) { setAuthOpen(true); return; } setSubmitOpen(true); };
  const logout = () => { setUser(null); setUserMenu(false); };

  const scrollToFeed = () => {
    if (feedRef.current) feedRef.current.scrollIntoView({ behavior: "smooth", block: "start" });
  };
  const setFilter = (setter) => (val) => { setter(val); requestAnimationFrame(scrollToFeed); };

  const today = useMemo(() => new Date().toISOString().slice(0, 10), []);

  const filtered = useMemo(() => {
    let ws = workshops.filter(w => {
      // Hide one-time workshops whose date has passed
      if (w.nextDate && w.scheduleType === "one-time" && w.nextDate < today) return false;
      const tagStr = (Array.isArray(w.tags) ? w.tags : []).join(" ");
      if (query && !(`${w.title} ${w.host} ${w.city} ${w.blurb} ${tagStr}`.toLowerCase().includes(query.toLowerCase()))) return false;
      if (activeCategory && w.category !== activeCategory) return false;
      if (activeCity && w.city !== activeCity) return false;
      if (w.price > 0 && w.price > priceMax) return false;
      if (minRating > 0 && w.rating < minRating) return false;
      if (scheduleFilter !== "all" && w.scheduleType !== scheduleFilter) return false;
      if (audienceFilter === "kids" && !w.forKids) return false;
      if (audienceFilter === "adults" && w.forKids) return false;
      if (showFavsOnly && !favs.includes(w.id)) return false;
      return true;
    });
    if (sort === "price-asc")  ws = [...ws].sort((a, b) => a.price - b.price);
    if (sort === "price-desc") ws = [...ws].sort((a, b) => b.price - a.price);
    if (sort === "rating")     ws = [...ws].sort((a, b) => b.rating - a.rating);
    return ws;
  }, [workshops, query, activeCategory, activeCity, priceMax, minRating, scheduleFilter, audienceFilter, showFavsOnly, favs, sort, today]);

  const featured = workshops.find(w => w.featured);
  // Featured card always shown at top — exclude it from the filtered list
  const rest = filtered.filter(w => !(featured && w.id === featured.id));
  const showFeatured = !!featured;
  const modalWorkshop = workshops.find(w => w.id === modalId);

  const [hostRouteSlug, setHostRouteSlug] = useState(() =>
    typeof window.readHostSlugFromHash === "function" ? window.readHostSlugFromHash() : null
  );
  useEffect(() => {
    const onHash = () =>
      setHostRouteSlug(typeof window.readHostSlugFromHash === "function" ? window.readHostSlugFromHash() : null);
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);

  useEffect(() => {
    if (hostRouteSlug) window.scrollTo(0, 0);
  }, [hostRouteSlug]);

  const [staticPageSlug, setStaticPageSlug] = useState(() =>
    typeof window.readStaticPageFromHash === "function" ? window.readStaticPageFromHash() : null
  );
  useEffect(() => {
    const onHash = () =>
      setStaticPageSlug(
        typeof window.readStaticPageFromHash === "function" ? window.readStaticPageFromHash() : null
      );
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);
  useEffect(() => {
    if (staticPageSlug) window.scrollTo(0, 0);
  }, [staticPageSlug]);

  const [blogRoute, setBlogRoute] = useState(() =>
    typeof window.readBlogRouteFromHash === "function" ? window.readBlogRouteFromHash() : null
  );
  useEffect(() => {
    const onHash = () =>
      setBlogRoute(typeof window.readBlogRouteFromHash === "function" ? window.readBlogRouteFromHash() : null);
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);
  useEffect(() => {
    if (blogRoute) window.scrollTo(0, 0);
  }, [blogRoute]);

  useEffect(() => {
    const onNav = () => {
      if (typeof window.trackGaPageView === "function") window.trackGaPageView();
    };
    onNav();
    window.addEventListener("hashchange", onNav);
    return () => window.removeEventListener("hashchange", onNav);
  }, []);

  useEffect(() => {
    if (!modalId) return;
    if (typeof window.trackGaEvent === "function") {
      window.trackGaEvent("workshop_view", { workshop_id: String(modalId) });
    }
  }, [modalId]);

  const hostWorkshops = useMemo(() => {
    if (!hostRouteSlug || typeof window.hostSlug !== "function") return [];
    return workshops.filter(w => window.hostSlug(w.host) === hostRouteSlug);
  }, [workshops, hostRouteSlug]);

  const goHome = () => {
    window.location.hash = "";
    setModalId(null);
  };

  const openHostPage = hostName => {
    if (typeof window.hostSlug !== "function") return;
    window.location.hash = `#/izvajalec/${window.hostSlug(hostName)}`;
  };

  const goToExploreCategory = catId => {
    window.location.hash = "";
    setActiveCategory(catId);
    requestAnimationFrame(() => scrollToFeed());
  };
  const goToCityFilter = cityName => {
    window.location.hash = "";
    setActiveCity(cityName);
    requestAnimationFrame(() => scrollToFeed());
  };

  if (loading && workshops.length === 0) {
    return (
      <div style={{display:"flex",alignItems:"center",justifyContent:"center",minHeight:"100vh",
                   fontFamily:"var(--font-mono)",fontSize:"13px",color:"var(--muted)"}}>
        Nalagam delavnice…
      </div>
    );
  }

  const StaticPageCmp = typeof window.StaticPage === "function" ? window.StaticPage : null;
  const BlogListCmp   = typeof window.BlogListPage === "function" ? window.BlogListPage : null;
  const BlogPostCmp   = typeof window.BlogPostPage === "function" ? window.BlogPostPage : null;
  const CookieBannerCmp = typeof window.CookieBanner === "function" ? window.CookieBanner : null;

  return (
    <LangContext.Provider value={lang}>

    {/* ── TOPBAR ── */}
    <header className="topbar">
      <div
        className="brand"
        role="button"
        tabIndex={0}
        style={{ cursor: "pointer" }}
        onClick={goHome}
        onKeyDown={e => { if (e.key === "Enter") goHome(); }}
      >
        likovne<em>-</em>delavnice<span className="brand-dot" />si
      </div>
      <div className="topbar-right">
        <span><span className="status-dot" /> {t.live}</span>
        <span className="fav-count"><span className="heart">♥</span>{favs.length} {t.saved}</span>
        <button className="topbar-submit mono tiny" onClick={tryOpenSubmit}>{t.addWorkshop}</button>
        {user ? (
          <div className="user-chip-wrap">
            <button className="user-chip" onClick={() => setUserMenu(m => !m)}>
              <div className="avatar avatar-cobalt" style={{width:"28px",height:"28px",fontSize:"14px"}}>{user.initial}</div>
              <span>{user.name}</span>
            </button>
            {userMenu && (
              <div className="user-menu">
                <div className="user-menu-head">
                  <div className="host-name">{user.name}</div>
                  <div className="mono tiny muted">{user.email}</div>
                </div>
                <button className="user-menu-item" onClick={() => { setUserMenu(false); tryOpenSubmit(); }}>{t.myWorkshops}</button>
                <button className="user-menu-item" onClick={() => setUserMenu(false)}>{t.myFavourites} ({favs.length})</button>
                <button className="user-menu-item" onClick={() => setUserMenu(false)}>{t.myRatings}</button>
                <button className="user-menu-item logout" onClick={logout}>{t.signOut}</button>
              </div>
            )}
          </div>
        ) : (
          <button className="topbar-login" onClick={() => setAuthOpen(true)}>{t.signIn}</button>
        )}
        <button
          className="lang"
          style={{border:"1px solid var(--ink)", padding:"4px 10px", background:"transparent", cursor:"pointer", fontFamily:"var(--font-mono)", fontSize:"12px"}}
          onClick={() => setLang(l => l === "sl" ? "en" : "sl")}
        >
          {lang === "sl" ? "EN" : "SL"}
        </button>
      </div>
    </header>

    {blogRoute && blogRoute.view === "list" && BlogListCmp ? (
      <BlogListCmp lang={lang} onBack={goHome}
        onOpenPost={slug => { window.location.hash = `#/blog/${slug}`; window.scrollTo(0,0); }} />
    ) : blogRoute && blogRoute.view === "post" && BlogPostCmp ? (
      <BlogPostCmp slug={blogRoute.slug} lang={lang}
        onBack={() => { window.location.hash = "#/blog"; window.scrollTo(0,0); }}
        onOpenWorkshopsCategory={cat => { window.location.hash = ""; setActiveCategory(cat); requestAnimationFrame(scrollToFeed); }} />
    ) : staticPageSlug && StaticPageCmp ? (
      <StaticPageCmp slug={staticPageSlug} onBack={goHome} />
    ) : !hostRouteSlug ? (
    <>
    {/* ── HERO ── */}
    <section className="hero">
      <div className="hero-grid">
        <div>
          <h1 className="hero-title">
            {t.heroWord1} <span className="accent-word">{t.heroWord2}</span>{" "}
            <span className="accent-word b">{t.heroWord3}</span><br/>
            {t.heroLine2}<br/>
            <span className="accent-word c">{t.heroWord4}</span>{" "}
            <span className="accent-word d">{t.heroWord5}</span>
          </h1>
          <p className="hero-lede" dangerouslySetInnerHTML={{ __html: t.heroLede(317) }} />
          <div className="searchbar">
            <input
              type="text"
              placeholder={t.searchPlaceholder}
              value={query}
              onChange={e => setQuery(e.target.value)}
              onKeyDown={e => { if (e.key === "Enter") { scrollToFeed(); } }}
            />
            <button className="search-submit" onClick={scrollToFeed}>{t.searchBtn}</button>
          </div>
        </div>
        <div className="hero-right">
          <div className="hero-stats">
            <div className="hero-stat"><div className="n">{workshops.length}</div><div className="l">{t.statWorkshops}</div></div>
            <div className="hero-stat"><div className="n">{new Set(workshops.map(w => w.host)).size}</div><div className="l">{t.statHosts}</div></div>
            <div className="hero-stat"><div className="n">{new Set(workshops.map(w => w.city)).size}</div><div className="l">{t.statCities}</div></div>
            <div className="hero-stat"><div className="n">{CATEGORIES.length}</div><div className="l">{t.statCategories}</div></div>
          </div>
        </div>
      </div>
    </section>

    {/* ── CATEGORY STRIP ── */}
    <div className="cat-strip">
      <span className="cat-strip-label">{t.browseLbl}</span>
      <button className={`cat-chip ${activeCategory === null ? "active" : ""}`} onClick={() => setFilter(setActiveCategory)(null)}>
        {t.all}
      </button>
      {CATEGORIES.map(c => (
        <button key={c.id}
          className={`cat-chip ${activeCategory === c.id ? `active ${c.color}` : ""}`}
          onClick={() => setFilter(setActiveCategory)(activeCategory === c.id ? null : c.id)}>
          {lang === "en" ? c.en : c.label}
        </button>
      ))}
    </div>

    {/* ── MAIN LAYOUT ── */}
    <div className="main">
      {/* Desktop sidebar */}
      <aside className="sidebar">{renderFilters()}</aside>

      {/* Mobile filter bottom bar */}
      <div className="mobile-filter-bar">
        <button className="mobile-filter-btn" onClick={() => setFiltersOpen(true)}>
          <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
            <path d="M2 4h12M4 8h8M6 12h4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"/>
          </svg>
          {lang === "en" ? "Filters" : "Filtri"}
          {activeFilterCount > 0 && (
            <span className="filter-badge">{activeFilterCount}</span>
          )}
        </button>
        <div className="view-toggle mobile-view-toggle">
          <button className={view === "list" ? "on" : ""} onClick={() => setView("list")}>{t.list}</button>
          <button className={view === "map"  ? "on" : ""} onClick={() => setView("map")}>{t.map}</button>
        </div>
        <button className="mobile-filter-btn" onClick={tryOpenSubmit}>
          + {lang === "en" ? "Add" : "Dodaj"}
        </button>
      </div>

      {/* Mobile bottom sheet */}
      {filtersOpen && (
        <div className="sheet-backdrop" onClick={() => setFiltersOpen(false)}>
          <div className="filter-sheet" onClick={e => e.stopPropagation()}>
            <div className="sheet-handle" />
            <div className="sheet-header">
              <span style={{fontFamily:"var(--font-display)",fontSize:"22px",fontWeight:400}}>
                {lang === "en" ? "Filters" : "Filtri"}
                {activeFilterCount > 0 && <span className="filter-badge" style={{marginLeft:"8px"}}>{activeFilterCount}</span>}
              </span>
              <div style={{display:"flex",gap:"8px",alignItems:"center"}}>
                {activeFilterCount > 0 && (
                  <button className="sheet-clear mono tiny" onClick={() => {
                    clearAllFilters();
                  }}>
                    {lang === "en" ? "Clear all" : "Počisti vse"}
                  </button>
                )}
                <button className="sheet-close" onClick={() => setFiltersOpen(false)}>✕</button>
              </div>
            </div>
            <div className="sheet-body">
              {renderFilters()}
            </div>
          </div>
        </div>
      )}

      {/* FEED */}
      {view === "list" ? (
        <main className="feed" ref={feedRef}>
          <div className="feed-head">
            <div>
              <h2>{t.allWorkshops}</h2>
              <div className="count-info mono tiny">
                {t.results(filtered.length, activeCategory ? catLabel(activeCategory, lang) : null, activeCity, priceMax)}
              </div>
            </div>
            <select className="sort-select" value={sort} onChange={e => setFilter(setSort)(e.target.value)}>
              <option value="featured">{t.sortFeatured}</option>
              <option value="price-asc">{t.sortPriceAsc}</option>
              <option value="price-desc">{t.sortPriceDesc}</option>
              <option value="rating">{t.sortRating}</option>
            </select>
          </div>

          {filtered.length === 0 ? (
            <div className="empty-state">
              <div className="big">Ø</div>
              {t.noResults}
            </div>
          ) : (
            <>
              {tweaks.cardStyle !== "rows" && tweaks.cardStyle !== "poster" && showFeatured && (
                <FeatureCard workshop={featured} fav={favs.includes(featured.id)}
                  toggleFav={() => toggleFav(featured.id)} onOpen={() => setModalId(featured.id)} lang={lang}
                  onOpenHost={openHostPage} />
              )}
              {tweaks.cardStyle === "rows" ? (
                <div className="feed-rows">
                  {filtered.map(w => (
                    <RowCard key={w.id} workshop={w} fav={favs.includes(w.id)}
                      toggleFav={() => toggleFav(w.id)} onOpen={() => setModalId(w.id)} lang={lang}
                      onOpenHost={openHostPage} />
                  ))}
                </div>
              ) : tweaks.cardStyle === "poster" ? (
                <div className={`feed-grid density-${tweaks.density}`}>
                  {filtered.map(w => (
                    <PosterCard key={w.id} workshop={w} fav={favs.includes(w.id)}
                      toggleFav={() => toggleFav(w.id)} onOpen={() => setModalId(w.id)} lang={lang}
                      onOpenHost={openHostPage} />
                  ))}
                </div>
              ) : (
                <div className={`feed-grid density-${tweaks.density}`}>
                  {rest.map(w => (
                    <GridCard key={w.id} workshop={w} fav={favs.includes(w.id)}
                      toggleFav={() => toggleFav(w.id)} onOpen={() => setModalId(w.id)}
                      density={tweaks.density} lang={lang} onOpenHost={openHostPage} />
                  ))}
                </div>
              )}
            </>
          )}
        </main>
      ) : (
        <main className="map-view" ref={feedRef}>
          <div className="map-view-map">
            <div style={{marginBottom:"14px"}}>
              <div className="mono tiny muted">{t.mapViewTitle}</div>
              <h2 style={{fontFamily:"var(--font-display)",fontSize:"34px",margin:"4px 0 0",fontWeight:400,lineHeight:1}}>
                {activeCity || t.mapViewClick}
              </h2>
            </div>
            <SloveniaMap workshops={workshops} activeCity={activeCity}
              onCityClick={c => setActiveCity(activeCity === c ? null : c)} />
          </div>
          <div className="map-view-list">
            {filtered.length === 0 && <div className="empty-state">{t.noResults}</div>}
            {filtered.map(w => (
              <RowCard key={w.id} workshop={w} fav={favs.includes(w.id)}
                toggleFav={() => toggleFav(w.id)} onOpen={() => setModalId(w.id)} lang={lang}
                onOpenHost={openHostPage} />
            ))}
          </div>
        </main>
      )}
    </div>

    {/* ── BLOG ── */}
    <section className="blog-section">
      <div className="blog-head">
        <div>
          <span className="promo-badge mono tiny" style={{background:"var(--ink)",color:"var(--paper)",padding:"4px 10px",borderRadius:"999px",letterSpacing:"0.1em"}}>
            {lang === "en" ? "✏ BLOG · ARTICLES" : "✏ BLOG · ČLANKI"}
          </span>
          <h2 className="blog-title">
            {lang === "en" ? "From the world of art workshops" : "Iz sveta likovnih delavnic"}
          </h2>
        </div>
        <a className="btn-primary mono tiny" href="#/blog" style={{alignSelf:"flex-end"}}>
          {lang === "en" ? "All articles →" : "Vsi članki →"}
        </a>
      </div>
      <div className="blog-grid">
        {(window.BLOG_POSTS || []).map(post => (
          <article key={post.id} className={`blog-card card accent-${post.color}`}
                   style={{cursor:"pointer"}}
                   onClick={() => { window.location.hash = `#/blog/${post.slug}`; window.scrollTo(0,0); }}>
            <div className={`cover cover-${post.color}`} style={{aspectRatio:"16/9", borderBottom:"1px solid var(--ink)"}}>
              <svg width="100%" height="100%" viewBox="0 0 320 180" preserveAspectRatio="xMidYMid slice">
                <defs>
                  <linearGradient id={`bg-${post.id}`} x1="0" y1="0" x2="1" y2="1">
                    <stop offset="0" stopColor="currentColor" stopOpacity="0.28"/>
                    <stop offset="1" stopColor="currentColor" stopOpacity="0.06"/>
                  </linearGradient>
                </defs>
                <rect width="320" height="180" fill={`url(#bg-${post.id})`}/>
                <text x="16" y="170" fontSize="10" fontFamily="var(--font-mono)" fill="currentColor" opacity="0.55" letterSpacing="1">{post.author.toUpperCase()} · {post.date.toUpperCase()}</text>
              </svg>
            </div>
            <div className="grid-body">
              <div className="grid-top">
                <span className="pill">{lang === "en" ? CATEGORIES.find(c=>c.id===post.category)?.en : CATEGORIES.find(c=>c.id===post.category)?.label}</span>
                <span className="mono tiny muted">{post.readMin} min</span>
              </div>
              <h3 className="grid-title">{lang === "en" ? post.title.en : post.title.sl}</h3>
              <p style={{fontSize:"13px",color:"var(--ink-2)",lineHeight:"1.5",margin:"0",flexGrow:1}}>
                {lang === "en" ? post.excerpt.en : post.excerpt.sl}
              </p>
              <div className="grid-footer" style={{marginTop:"12px"}}>
                <span className="mono tiny muted">{post.author}</span>
                <span className="mono tiny" style={{color:"var(--accent-cobalt)"}}>
                  {lang === "en" ? "Read →" : "Beri →"}
                </span>
              </div>
            </div>
          </article>
        ))}
      </div>
    </section>

    </>
    ) : (
      <HostPage
        lang={lang}
        hostWorkshops={hostWorkshops}
        allWorkshops={workshops}
        reviews={reviews}
        onOpenWorkshop={setModalId}
        favs={favs}
        toggleFav={toggleFav}
        density={tweaks.density}
        user={user}
        onRequestLogin={() => setAuthOpen(true)}
        refreshWorkshops={refreshWorkshop}
      />
    )}

    {/* ── FOOTER ── */}
    <footer className="site-footer">
      <div className="footer-inner">
        <div className="footer-brand">
          <div
            className="brand"
            style={{fontSize:"22px",cursor:"pointer"}}
            role="button"
            tabIndex={0}
            onClick={goHome}
            onKeyDown={e => { if (e.key === "Enter") goHome(); }}
          >
            likovne<em>-</em>delavnice<span className="brand-dot"/>si
          </div>
          <p className="footer-tagline mono tiny muted">
            {lang === "en"
              ? "All art workshops in Slovenia, in one place."
              : "Vse likovne delavnice v Sloveniji, na enem mestu."}
          </p>
        </div>
        <div className="footer-cols">
          <div className="footer-col">
            <div className="footer-col-title mono tiny">{lang === "en" ? "EXPLORE" : "ODKRIVAJ"}</div>
            {CATEGORIES.slice(0, 5).map(c => (
              <a key={c.id} href="#browse" className="footer-link"
                onClick={e => { e.preventDefault(); goToExploreCategory(c.id); }}>
                {lang === "en" ? c.en : c.label}
              </a>
            ))}
          </div>
          <div className="footer-col">
            <div className="footer-col-title mono tiny">{lang === "en" ? "CITIES" : "MESTA"}</div>
            {["Ljubljana","Maribor","Bled","Koper","Piran"].map(city => (
              <a key={city} href="#browse" className="footer-link"
                onClick={e => { e.preventDefault(); goToCityFilter(city); }}>{city}</a>
            ))}
          </div>
          <div className="footer-col">
            <div className="footer-col-title mono tiny">{lang === "en" ? "FOR HOSTS" : "ZA IZVAJALCE"}</div>
            <a href="#submit" className="footer-link"
              onClick={e => { e.preventDefault(); tryOpenSubmit(); }}>
              {lang === "en" ? "+ Add your workshop" : "+ Dodaj svojo delavnico"}
            </a>
            <a href="#/blog" className="footer-link">{lang === "en" ? "Blog" : "Blog"}</a>
            <a href="#/guidelines" className="footer-link">{t.footerGuidelines}</a>
            <a href="#/contact" className="footer-link">{t.footerContact}</a>
            <a href="#/terms" className="footer-link">{t.footerTerms}</a>
            <a href="#/privacy" className="footer-link">{t.footerPrivacy}</a>
            <a href="#/piskotki" className="footer-link">{lang === "en" ? "Cookie policy" : "Piškotki"}</a>
          </div>
        </div>
      </div>
      <div className="footer-bottom">
        <span className="mono tiny muted">© 2026 likovne-delavnice.si</span>
        <span className="footer-bottom-links mono tiny">
          <a href="#/terms">{t.footerTerms}</a>
          <span className="footer-dot">·</span>
          <a href="#/privacy">{t.footerPrivacy}</a>
          <span className="footer-dot">·</span>
          <a href="#/contact">{t.footerContact}</a>
          <span className="footer-dot">·</span>
          <a href="#/piskotki">{lang === "en" ? "Cookies" : "Piškotki"}</a>
        </span>
        <span className="mono tiny muted">
          {lang === "en" ? "Data crawled from public sources." : "Podatki zajeti iz javnih virov."}
        </span>
        <button className="mono tiny" style={{background:"none",border:"none",color:"var(--muted)",cursor:"pointer"}}
          onClick={() => setLang(l => l === "sl" ? "en" : "sl")}>
          {lang === "sl" ? "🌐 EN" : "🌐 SL"}
        </button>
      </div>
    </footer>

    {/* ── MODALS ── */}
    {modalWorkshop && (
      <DetailModal workshop={modalWorkshop} onClose={() => setModalId(null)}
        userRating={userRatings[modalWorkshop.id] || 0} setUserRating={setUserRating}
        fav={favs.includes(modalWorkshop.id)} toggleFav={() => toggleFav(modalWorkshop.id)}
        user={user} onRequestLogin={requireLogin} reviews={reviews} addReview={addReview}
        onReviewSubmitted={refreshWorkshop}
        onViewHostPage={hostName => { setModalId(null); openHostPage(hostName); }} />
    )}
    {authOpen && (
      <AuthModal mode="signin" onClose={() => setAuthOpen(false)} onAuth={u => setUser(u)} />
    )}
    {submitOpen && user && (
      <SubmitBusinessModal onClose={() => setSubmitOpen(false)} user={user}
        onSubmit={biz => setUserSubmissions(s => [...s, { ...biz, ts: Date.now() }])} />
    )}

    {/* ── COOKIE BANNER ── */}
    {CookieBannerCmp && <CookieBannerCmp lang={lang} />}

    {/* ── TWEAKS PANEL ── */}
    {showTweaks && (
      <div className="tweaks">
        <h3>Tweaks</h3>
        <div className="t-sub">Live design controls</div>
        <div className="t-section">
          <label>Paleta / Color</label>
          <div className="swatches">
            {PALETTES.map(p => (
              <button key={p.id} className={`sw ${tweaks.palette === p.id ? "on" : ""}`}
                style={{background:p.sw}} onClick={() => updateTweak("palette", p.id)} title={p.label} />
            ))}
          </div>
        </div>
        <div className="t-section">
          <label>Font pairing</label>
          <div className="t-options">
            {FONT_SETS.map(f => (
              <button key={f.id} className={`t-opt ${tweaks.fonts === f.id ? "on" : ""}`}
                onClick={() => updateTweak("fonts", f.id)}>{f.label}</button>
            ))}
          </div>
        </div>
        <div className="t-section">
          <label>Card style</label>
          <div className="t-options">
            {CARD_STYLES.map(c => (
              <button key={c.id} className={`t-opt ${tweaks.cardStyle === c.id ? "on" : ""}`}
                onClick={() => updateTweak("cardStyle", c.id)}>{c.label}</button>
            ))}
          </div>
        </div>
        <div className="t-section">
          <label>Density</label>
          <div className="t-options">
            {DENSITIES.map(d => (
              <button key={d.id} className={`t-opt ${tweaks.density === d.id ? "on" : ""}`}
                onClick={() => updateTweak("density", d.id)}>{d.label}</button>
            ))}
          </div>
        </div>
        <div className="t-section">
          <label>Hero style</label>
          <div className="t-options">
            {HEROES.map(h => (
              <button key={h.id} className={`t-opt ${tweaks.hero === h.id ? "on" : ""}`}
                onClick={() => updateTweak("hero", h.id)}>{h.label}</button>
            ))}
          </div>
        </div>
      </div>
    )}

    </LangContext.Provider>
  );
}

const GATE_KEY = "ld_access";
const GATE_PWD = "likovniki";

function PasswordGate({ onUnlock }) {
  const [val, setVal] = React.useState("");
  const [err, setErr] = React.useState(false);

  function submit(e) {
    e.preventDefault();
    if (val === GATE_PWD) {
      localStorage.setItem(GATE_KEY, "1");
      onUnlock();
    } else {
      setErr(true);
      setVal("");
    }
  }

  return (
    <div style={{
      position: "fixed", inset: 0, display: "flex", alignItems: "center",
      justifyContent: "center", background: "#faf9f7"
    }}>
      <form onSubmit={submit} style={{ display: "flex", flexDirection: "column", gap: 12, width: 280 }}>
        <div style={{ fontFamily: "serif", fontSize: 22, fontWeight: 700, marginBottom: 4 }}>
          Likovne delavnice
        </div>
        <input
          autoFocus
          type="password"
          placeholder="Geslo / Password"
          value={val}
          onChange={e => { setVal(e.target.value); setErr(false); }}
          style={{
            padding: "10px 14px", fontSize: 16, border: err ? "1.5px solid #c0392b" : "1.5px solid #ccc",
            borderRadius: 8, outline: "none"
          }}
        />
        {err && <div style={{ color: "#c0392b", fontSize: 13 }}>Napačno geslo. / Wrong password.</div>}
        <button type="submit" style={{
          padding: "10px 0", background: "#1a1a1a", color: "#fff",
          border: "none", borderRadius: 8, fontSize: 15, cursor: "pointer"
        }}>
          Naprej →
        </button>
      </form>
    </div>
  );
}

function Root() {
  const [unlocked, setUnlocked] = React.useState(localStorage.getItem(GATE_KEY) === "1");
  if (!unlocked) return <PasswordGate onUnlock={() => setUnlocked(true)} />;
  return <App />;
}

ReactDOM.createRoot(document.getElementById("root")).render(<Root />);
