// Main App — composes everything
const { useState, useEffect, useMemo } = React;

// ── Feature flags — flip to true to re-enable ────────────────────────────────
const FLAGS = {
  caseStudy:    false,  // open project cards → case study modal
  workshops:    false,  // workshops & talks section
  tools:        false,  // tools section
  tutorials:    false,  // tutorials & education section
  clients:      false,  // selected clients section
};
// ─────────────────────────────────────────────────────────────────────────────

function App() {
  const [layout, setLayout] = useState("grid");
  const [density, setDensity] = useState("regular");
  const projects = window.PROJECTS.map((p, i) => ({ ...p, _idx: i + 1 }));

  const [active, setActive] = useState(() => {
    const hash = window.location.hash.slice(1);
    return hash ? (projects.find(p => p.id === hash) ?? null) : null;
  });
  const [typeFilters, setTypeFilters] = useState(new Set());
  const [techFilters, setTechFilters] = useState(new Set());

  const DEFAULT_TITLE = "Function Store — Dan Molnar | TouchDesigner Artist & Developer";
  const DEFAULT_DESC  = "Dan Molnar is a TouchDesigner artist and developer based in Berlin, creating audiovisual installations, live performance systems, and tools for artists worldwide.";
  const DEFAULT_URL   = "https://functionstore.xyz/";
  const DEFAULT_IMG   = "https://functionstore.xyz/og-image.jpg";

  function setMeta(sel, attr, val) {
    const el = document.querySelector(sel);
    if (el) el.setAttribute(attr, val);
  }

  useEffect(() => {
    if (active) {
      const title = active.title + " — Function Store";
      const desc  = active.desc || DEFAULT_DESC;
      const img   = active.posterUrl || DEFAULT_IMG;
      const url   = window.location.origin + window.location.pathname + "#" + active.id;
      document.title = title;
      setMeta('meta[name="description"]',          "content", desc);
      setMeta('meta[property="og:title"]',          "content", title);
      setMeta('meta[property="og:description"]',    "content", desc);
      setMeta('meta[property="og:image"]',          "content", img);
      setMeta('meta[property="og:url"]',            "content", url);
      setMeta('meta[name="twitter:title"]',         "content", title);
      setMeta('meta[name="twitter:description"]',   "content", desc);
      setMeta('meta[name="twitter:image"]',         "content", img);
      history.pushState(null, "", "#" + active.id);
    } else {
      document.title = DEFAULT_TITLE;
      setMeta('meta[name="description"]',          "content", DEFAULT_DESC);
      setMeta('meta[property="og:title"]',          "content", DEFAULT_TITLE);
      setMeta('meta[property="og:description"]',    "content", DEFAULT_DESC);
      setMeta('meta[property="og:image"]',          "content", DEFAULT_IMG);
      setMeta('meta[property="og:url"]',            "content", DEFAULT_URL);
      setMeta('meta[name="twitter:title"]',         "content", "Function Store — Dan Molnar");
      setMeta('meta[name="twitter:description"]',   "content", "TouchDesigner artist and developer based in Berlin.");
      setMeta('meta[name="twitter:image"]',         "content", DEFAULT_IMG);
      history.pushState(null, "", window.location.pathname);
    }
  }, [active]);

  function openProject(project) { setActive(project); }
  function closeProject() { setActive(null); }

  function toggleType(val) {
    if (val === "ALL") { setTypeFilters(new Set()); return; }
    setTypeFilters(prev => { const s = new Set(prev); s.has(val) ? s.delete(val) : s.add(val); return s; });
  }
  function toggleTech(val) {
    if (val === "ALL") { setTechFilters(new Set()); return; }
    setTechFilters(prev => { const s = new Set(prev); s.has(val) ? s.delete(val) : s.add(val); return s; });
  }
  const [search, setSearch] = useState("");
  const [mobileMenu, setMobileMenu] = useState(false);
  const [filtersOpen, setFiltersOpen] = useState(false);
  const [listHover, setListHover] = useState(null);
  const [listPos, setListPos] = useState({ x: 0, y: 0 });

  // Apply fixed theme/typography + reactive density to root
  useEffect(() => {
    document.documentElement.setAttribute("data-theme", "warm-dark");
    document.documentElement.setAttribute("data-type", "mono-display");
    document.documentElement.setAttribute("data-density", density);
  }, [density]);

  const types = useMemo(() => ["ALL", ...new Set(projects.flatMap(p => p.type))], [projects]);
  const techs = useMemo(() => ["ALL", ...new Set(projects.flatMap(p => p.tags))], [projects]);

  const filtered = projects.filter(p => {
    if (typeFilters.size > 0 && !p.type.some(t => typeFilters.has(t))) return false;
    if (techFilters.size > 0 && !p.tags.some(tag => techFilters.has(tag))) return false;
    if (search) {
      const q = search.toLowerCase();
      const hay = (p.title + " " + (p.client || "") + " " + p.tags.join(" ")).toLowerCase();
      if (!hay.includes(q)) return false;
    }
    return true;
  });


  return (
    <>
      <GenerativeBG intensity={1} />
      <CustomCursor mode="trail" />

      <nav className="topnav">
        <div className="topnav-l">
          <img className="topnav-avatar" src="https://MyPortfolioWebsite.b-cdn.net/static/FunctionStore_headshot_square.jpg" alt="Dan Molnar" />
          <span className="topnav-logo">Function Store</span>
        </div>
        <div className="topnav-c">
          <a href="#work">Work</a>
          <a href="#about">About</a>
          {FLAGS.tutorials  && <a href="#tutorials">Tutorials</a>}
          {FLAGS.workshops  && <a href="#workshops">Workshops</a>}
          {FLAGS.tools      && <a href="#tools">Tools</a>}
          <a href="#contact">Contact</a>
          <span className="topnav-divider"></span>
          <a href="https://derealstudio.com" target="_blank" rel="noopener" className="topnav-ext">DEREAL ↗</a>
        </div>
        <div className="topnav-r">
          <a href="#contact" className="topnav-avail">
            <span className="topnav-dot"></span>
            Available for work
          </a>
        </div>
        <button
          className={"topnav-hamburger" + (mobileMenu ? " open" : "")}
          onClick={function() { setMobileMenu(function(v) { return !v; }); }}
          aria-label="Menu"
        >
          <span></span><span></span><span></span>
        </button>
      </nav>
      {mobileMenu && (
        <div className="topnav-mobile" onClick={function() { setMobileMenu(false); }}>
          <a href="#work">Work</a>
          <a href="#about">About</a>
          {FLAGS.tutorials  && <a href="#tutorials">Tutorials</a>}
          {FLAGS.workshops  && <a href="#workshops">Workshops</a>}
          {FLAGS.tools      && <a href="#tools">Tools</a>}
          <a href="#contact">Contact</a>
          <a href="https://derealstudio.com" target="_blank" rel="noopener" className="topnav-mobile-ext">DEREAL Studio ↗</a>
        </div>
      )}

      <main className="page">
        <HeroReel projects={projects} onOpen={FLAGS.caseStudy ? openProject : null} />

        <div className="wip-banner">
          <div className="wip-corners">
            <span className="wip-c wip-c-tl"></span><span className="wip-c wip-c-tr"></span>
            <span className="wip-c wip-c-bl"></span><span className="wip-c wip-c-br"></span>
          </div>
          <span className="wip-label">◎ WORK IN PROGRESS</span>
          <p className="wip-body">This site is under active construction. Project archive is incomplete and some features are disabled.</p>
        </div>

        <div className="soc-row">
          <a href="https://patreon.com/function_store" className="soc-btn" aria-label="Patreon" target="_blank" rel="noopener">
            <svg viewBox="0 0 24 24"><path d="M14.82 2.41c3.96 0 7.18 3.24 7.18 7.21 0 3.96-3.22 7.18-7.18 7.18-3.97 0-7.21-3.22-7.21-7.18 0-3.97 3.24-7.21 7.21-7.21M2 21.6h3.5V2.4H2V21.6z"/></svg>
          </a>
          <a href="https://youtube.com/@functionstore" className="soc-btn" aria-label="YouTube" target="_blank" rel="noopener">
            <svg viewBox="0 0 24 24"><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
          </a>
          <a href="https://github.com/function-store" className="soc-btn" aria-label="GitHub" target="_blank" rel="noopener">
            <svg viewBox="0 0 24 24"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
          </a>
          <a href="https://instagram.com/function.str" className="soc-btn" aria-label="Instagram" target="_blank" rel="noopener">
            <svg viewBox="0 0 24 24"><path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/></svg>
          </a>
          <a href="https://facebook.com/functionstore" className="soc-btn" aria-label="Facebook" target="_blank" rel="noopener">
            <svg viewBox="0 0 24 24"><path d="M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z"/></svg>
          </a>
          <a href="https://www.linkedin.com/in/daniel-molnar-668aa6b6/" className="soc-btn" aria-label="LinkedIn" target="_blank" rel="noopener">
            <svg viewBox="0 0 24 24"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>
          </a>
          <a href="mailto:dan@functionstore.xyz" className="soc-btn" aria-label="Email">
            <svg viewBox="0 0 24 24"><path d="M20 4H4C2.9 4 2 4.9 2 6v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg>
          </a>
        </div>

        <section className="sec sec-work" id="work">
          <SecHeader num="01" label="Selected work" />

          <div className="work-controls">
            <div className="work-filters-group">
              {(function() {
                var activeCount = typeFilters.size + techFilters.size;
                var activeChips = [...typeFilters, ...techFilters];
                return (
                  <button
                    className={"work-filter-toggle" + (filtersOpen ? " open" : "") + (activeCount > 0 ? " has-active" : "")}
                    onClick={function() { setFiltersOpen(function(v) { return !v; }); }}
                    data-cursor="FILTER"
                  >
                    <span className="wft-l">
                      <span className="wft-glyph">◈</span>
                      {activeCount > 0
                        ? <span className="wft-label">{activeCount} filter{activeCount > 1 ? "s" : ""} active</span>
                        : <span className="wft-label">Filter by type &amp; skills</span>
                      }
                      {activeCount > 0 && activeChips.map(function(f) {
                        return <span key={f} className="wft-chip">{f}</span>;
                      })}
                    </span>
                    <span className="wft-r">
                      {activeCount > 0 && (
                        <span
                          className="wft-clear"
                          onClick={function(e) { e.stopPropagation(); setTypeFilters(new Set()); setTechFilters(new Set()); }}
                        >clear ✕</span>
                      )}
                      <span className="wft-chevron">{filtersOpen ? "▲" : "▼"}</span>
                    </span>
                  </button>
                );
              })()}
              {filtersOpen && (
                <>
                  <div className="work-filters">
                    {types.map(t => (
                      <button
                        key={t}
                        className={`work-filter ${t === "ALL" ? typeFilters.size === 0 ? "on" : "" : typeFilters.has(t) ? "on" : ""}`}
                        onClick={() => toggleType(t)}
                        data-cursor="FILTER"
                      >
                        <span className="work-filter-dot"></span>
                        <span>{t}</span>
                        <span className="work-filter-n">
                          {t === "ALL" ? projects.length : projects.filter(p => p.type.includes(t)).length}
                        </span>
                      </button>
                    ))}
                  </div>
                  <div className="work-filters work-filters--tech">
                    {techs.map(t => (
                      <button
                        key={t}
                        className={`work-filter ${t === "ALL" ? techFilters.size === 0 ? "on" : "" : techFilters.has(t) ? "on" : ""}`}
                        onClick={() => toggleTech(t)}
                        data-cursor="FILTER"
                      >
                        <span className="work-filter-dot"></span>
                        <span>{t}</span>
                        <span className="work-filter-n">
                          {t === "ALL" ? projects.length : projects.filter(p => p.tags.includes(t)).length}
                        </span>
                      </button>
                    ))}
                  </div>
                </>
              )}
            </div>
            <div className="work-right">
              <div className="work-layout">
                {[{ v: "grid", g: "⊞" }, { v: "list", g: "☰" }, { v: "scroll", g: "▤" }].map(function(opt) {
                  return (
                    <button
                      key={opt.v}
                      className={"work-layout-btn" + (layout === opt.v ? " on" : "")}
                      onClick={function() { setLayout(opt.v); }}
                      data-cursor="LAYOUT"
                      title={opt.v}
                    >{opt.g}</button>
                  );
                })}
              </div>
              <div className="work-sizer">
                {[{ v: "sparse", n: 2 }, { v: "regular", n: 3 }, { v: "dense", n: 4 }].map(function(opt) {
                  return (
                    <button
                      key={opt.v}
                      className={"work-sizer-btn" + (density === opt.v ? " on" : "")}
                      onClick={function() { setDensity(opt.v); }}
                      data-cursor="LAYOUT"
                    >
                      {Array.from({ length: opt.n }, function(_, i) {
                        return <span key={i} className="work-sizer-sq" />;
                      })}
                    </button>
                  );
                })}
              </div>
              <div className="work-search">
                <span className="work-search-l">›</span>
                <input
                  type="text"
                  value={search}
                  placeholder="search title, client, tag…"
                  onChange={(e) => setSearch(e.target.value)}
                />
                <span className="work-search-r">{filtered.length} / {projects.length}</span>
              </div>
            </div>
          </div>

          {layout === "grid" && (
            <div className={`work-grid work-grid-${density}`}>
              {filtered.map(p => (
                <ProjectCard key={p.id} project={p} density={density} onOpen={FLAGS.caseStudy ? openProject : null} />
              ))}
            </div>
          )}
          {layout === "list" && (
            <div
              className="work-list"
              onMouseMove={(e) => setListPos({ x: e.clientX, y: e.clientY })}
              onMouseLeave={() => setListHover(null)}
            >
              {filtered.map(p => (
                <div key={p.id} onMouseEnter={() => setListHover(p)} onMouseLeave={() => setListHover(null)}>
                  <ProjectRow project={p} onOpen={FLAGS.caseStudy ? openProject : null} />
                </div>
              ))}
              {listHover && <ListPreview project={listHover} x={listPos.x} y={listPos.y} />}
            </div>
          )}
          {layout === "scroll" && (
            <div className="work-scroll">
              {filtered.map(p => (
                <div key={p.id} className="work-scroll-item">
                  <ProjectCard project={p} density="comfy" onOpen={FLAGS.caseStudy ? openProject : null} />
                </div>
              ))}
            </div>
          )}
        </section>

        <About />
        {FLAGS.tutorials && <Tutorials />}
        {FLAGS.workshops && <Workshops onOpen={FLAGS.caseStudy ? openProject : null} />}
        {FLAGS.tools     && <Tools />}
        {FLAGS.clients   && <Clients />}
        <Contact />

        <footer className="ftr">
          <div className="ftr-l">
            <span>© 2026 DAN MOLNAR / FUNCTION STORE</span>
            <span className="ftr-dot">·</span>
            <span>BERLIN</span>
          </div>
          <div className="ftr-r">
            <span>BUILT IN TOUCHDESIGNER (NO IT WASN'T)</span>
          </div>
        </footer>
      </main>

      {FLAGS.caseStudy && active && <CaseStudy project={active} onClose={closeProject} />}

    </>
  );
}

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