const { useEffect, useRef, useState } = React;

const DEFAULT_TWEAKS = /*EDITMODE-BEGIN*/{
  "waveformStyle": "line",
  "accent": "oklch(0.72 0.18 38)",
  "showGrain": true
}/*EDITMODE-END*/;

function Topbar({ onMode }) {
  const [time, setTime] = useState("");
  useEffect(() => {
    const u = () => {
      const d = new Date();
      const h = String(d.getUTCHours()).padStart(2, "0");
      const m = String(d.getUTCMinutes()).padStart(2, "0");
      const s = String(d.getUTCSeconds()).padStart(2, "0");
      setTime(`${h}:${m}:${s} UTC`);
    };
    u();
    const i = setInterval(u, 1000);
    return () => clearInterval(i);
  }, []);
  return (
    <header className="topbar">
      <div className="logo">
        <span className="dot" />
        <span>AL&nbsp;BUENO</span>
        <span style={{ opacity: 0.5 }}>·</span>
        <span style={{ opacity: 0.5 }}>SOUND&nbsp;DESIGN</span>
      </div>
      <div className="meta">
        <span>QUEENS, NY</span>
        <span>{time}</span>
        <span>↘ AVAILABLE Q3 ’26</span>
      </div>
    </header>
  );
}

// Hero: orbital nav + center waveform that reacts to cursor proximity
function Hero({ tweaks }) {
  const { data, pokeCursor } = window.useProceduralAudio(96);
  const [rot, setRot] = useState(0);
  const heroRef = useRef(null);

  useEffect(() => {
    let raf;
    const tick = () => { setRot((r) => r + 0.05); raf = requestAnimationFrame(tick); };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  const onMove = (e) => {
    if (!heroRef.current) return;
    const r = heroRef.current.getBoundingClientRect();
    const x = (e.clientX - r.left) / r.width;
    const y = (e.clientY - r.top) / r.height;
    // distance from center increases energy
    const d = Math.hypot(x - 0.5, y - 0.5);
    pokeCursor(x, 0.06 + (1 - d) * 0.05);
  };

  const items = window.AB_NAV;
  const style = tweaks.waveformStyle;

  return (
    <section className="hero" ref={heroRef} onMouseMove={onMove}>
      {/* concentric guide rings */}
      <div className="rings" aria-hidden="true">
        {[1, 2, 3, 4].map((n) => (
          <div key={n} className="ring" style={{ width: 220 + n * 130, height: 220 + n * 130 }} />
        ))}
      </div>

      {/* center waveform */}
      <div className="hero-wave">
        {style === "circular" && (
          <window.WaveformCircular data={data} size={560} innerR={130} outerR={250} rotation={rot} color="var(--fg)" />
        )}
        {style === "bars" && (
          <div style={{ width: 560 }}>
            <window.WaveformBars data={data} height={360} gap={3} color="var(--fg)" />
          </div>
        )}
        {style === "line" && (
          <div style={{ width: 560 }}>
            <window.WaveformLine data={data} height={360} color="var(--fg)" />
          </div>
        )}
      </div>

      {/* orbital nav around it */}
      <window.OrbitalNav items={items} onSelect={(it) => {
        if (it.href.startsWith("index.html#")) {
          const id = it.href.split("#")[1];
          document.getElementById(id)?.scrollIntoView({ behavior: "smooth", block: "start" });
        } else {
          location.href = it.href;
        }
      }} />

      {/* corner type */}
      <div className="hero-corner tl">
        <div className="eyebrow">Portfolio · 2007 — 2026</div>
        <div className="hero-name serif">Al Bueno</div>
        <div className="hero-tagline mono">
          Sound design, score, and<br/>spatial composition for<br/>image, room, and brand.
        </div>
      </div>

      <div className="hero-corner br">
        <div className="eyebrow">Selected work</div>
        <div className="mono" style={{ fontSize: 13, color: "var(--fg-dim)", marginTop: 8 }}>
          ↓ scroll <span className="caret">&nbsp;</span>
        </div>
      </div>

      <div className="hero-corner bl">
        <div className="eyebrow">Now playing</div>
        <div className="now-playing mono">
          <span className="dot-live" /> idle bed · 432 Hz
        </div>
      </div>

      <div className="hero-corner tr">
        <div className="eyebrow">Drag the dial ↻</div>
      </div>
    </section>
  );
}

function ProjectIndex() {
  const projects = window.AB_PROJECTS;
  const [hover, setHover] = useState(-1);
  const previewRef = useRef(null);
  const cursorRef = useRef({ x: 0, y: 0 });

  useEffect(() => {
    const m = (e) => { cursorRef.current = { x: e.clientX, y: e.clientY }; };
    window.addEventListener("mousemove", m);
    return () => window.removeEventListener("mousemove", m);
  }, []);

  useEffect(() => {
    let raf;
    const tick = () => {
      if (previewRef.current) {
        const offset = 24;
        previewRef.current.style.transform = `translate(${cursorRef.current.x + offset}px, ${cursorRef.current.y + offset}px)`;
      }
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  return (
    <section id="work" className="work">
      <div className="section-head">
        <span className="eyebrow">§ Work · {String(projects.length).padStart(2, "0")} entries</span>
        <h2 className="section-title">
          A catalogue of <span className="serif">listening</span>.
        </h2>
        <p className="section-sub mono">
          Each piece is its own grammar of sound. Scroll to scrub the index.
        </p>
      </div>

      <div className="proj-table mono" id="index">
        <div className="proj-row head">
          <span>№</span>
          <span>Title</span>
          <span>Discipline</span>
          <span>Medium</span>
          <span>Year</span>
          <span style={{ textAlign: "right" }}>↗</span>
        </div>
        {projects.map((p, i) => (
          <a
            key={p.id}
            href={p.href}
            className="proj-row"
            onMouseEnter={() => setHover(i)}
            onMouseLeave={() => setHover(-1)}
            style={{ "--proj-color": p.color }}
          >
            <span className="proj-num">{p.index}</span>
            <span className="proj-title serif">{p.title}</span>
            <span className="proj-cell">{p.type}</span>
            <span className="proj-cell">{p.medium}</span>
            <span className="proj-cell">{p.year}</span>
            <span className="proj-arrow">↗</span>
            <div className="proj-line" />
          </a>
        ))}
      </div>

      {/* cursor-following preview */}
      <div
        ref={previewRef}
        className="proj-preview"
        style={{
          opacity: hover >= 0 ? 1 : 0,
          pointerEvents: "none",
          position: "fixed", top: 0, left: 0, zIndex: 40,
        }}
      >
        {hover >= 0 && <ProjectPreview project={projects[hover]} />}
      </div>
    </section>
  );
}

function ProjectPreview({ project }) {
  const { data } = window.useProceduralAudio(64);
  return (
    <div className="proj-preview-card" style={{ "--proj-color": project.color }}>
      <div className="proj-preview-head mono">
        <span>{project.index} / {project.year}</span>
        <span>{project.duration}</span>
      </div>
      <div className="proj-preview-wave">
        <window.WaveformBars data={data} height={140} gap={2} color={project.color} />
      </div>
      <div className="proj-preview-foot">
        <div className="proj-preview-title serif">{project.title}</div>
        <div className="mono proj-preview-tags">{project.tags.join(" · ")}</div>
      </div>
    </div>
  );
}

function About() {
  const { data } = window.useProceduralAudio(48);
  return (
    <section id="about" className="about">
      <div className="about-grid">
        <div className="about-left">
          <span className="eyebrow">§ About</span>
          <h2 className="about-h serif">
            I make sound that <em>holds</em> a room — and sometimes lets it go.
          </h2>
        </div>
        <div className="about-right mono">
          <p>
            Al Bueno is a New York-based sound designer and electronic music producer whose practice
            spans experimental music, nightlife, and audiovisual art. The work moves across short film,
            documentary, installation, and brand — anywhere that time and space are the medium.
          </p>
          <p>
            As founder and director of BCR, a record label focused on techno music, he has developed
            a distinctive sonic sensibility rooted in texture, frequency, and spatial experience.
            His work extends into live event production and sound design for video installations
            and documentary film, including Chromophobia, an 8-channel sound installation.
          </p>
          <p>
            Trained as a computer engineer and well versed in audio engineering, the studio approaches
            every project from the room outwards: what does this place already sound like, and what
            does it still need? Bridging precision and feeling.
          </p>
          <div className="capabilities">
            <div className="cap-row"><span className="cap-num">01</span><span>Sound design · foley</span><span className="cap-mid">— film & series</span></div>
            <div className="cap-row"><span className="cap-num">02</span><span>Original score & composition</span><span className="cap-mid">— stereo to 7.1.4</span></div>
            <div className="cap-row"><span className="cap-num">03</span><span>Sonic identity & branding</span><span className="cap-mid">— logos, idents, beds</span></div>
          </div>
        </div>
      </div>
      <div className="about-strip">
        <window.WaveformLine data={data} height={120} color="var(--fg-dim)" />
      </div>
    </section>
  );
}

function Contact() {
  const [copied, setCopied] = useState(false);
  const email = "al@albueno.com";
  const copy = () => {
    navigator.clipboard?.writeText(email);
    setCopied(true);
    setTimeout(() => setCopied(false), 1600);
  };
  return (
    <section id="contact" className="contact">
      <span className="eyebrow">§ Contact</span>
      <h2 className="contact-h serif">
        Let&rsquo;s make<br/>something <em>resonant</em>.
      </h2>
      <div className="contact-grid mono">
        <div>
          <div className="eyebrow">Email</div>
          <button onClick={copy} className="contact-link">
            {email} <span style={{ opacity: 0.5, marginLeft: 8 }}>{copied ? "[copied]" : "[copy ↗]"}</span>
          </button>
        </div>
        <div>
          <div className="eyebrow">Studios</div>
          <div className="contact-link">BuenoStudio · Queens, NY</div>
        </div>
        <div>
          <div className="eyebrow">Booking</div>
          <div className="contact-link">Q3 — Q4 2026</div>
        </div>
      </div>

      <div className="footer mono">
        <span>© Al Bueno · MMXXVI</span>
        <span>Site v3.2 · monospaced &amp; mono-mastered</span>
        <span>↑ back to top</span>
      </div>
    </section>
  );
}

function App() {
  const [tweaks, setTweak] = window.useTweaks(DEFAULT_TWEAKS);

  useEffect(() => {
    document.documentElement.style.setProperty("--accent", tweaks.accent);
  }, [tweaks.accent]);

  return (
    <>
      <Topbar />
      <Hero tweaks={tweaks} />
      <ProjectIndex />
      <About />
      <Contact />

      <window.TweaksPanel>
        <window.TweakSection label="Hero waveform" />
        <window.TweakRadio
          label="Style"
          value={tweaks.waveformStyle}
          onChange={(v) => setTweak("waveformStyle", v)}
          options={[
            { value: "circular", label: "Ring" },
            { value: "bars", label: "Bars" },
            { value: "line", label: "Line" },
          ]}
        />
        <window.TweakSection label="Accent" />
        <window.TweakRadio
          label="Color"
          value={tweaks.accent}
          onChange={(v) => setTweak("accent", v)}
          options={[
            { value: "oklch(0.72 0.18 38)", label: "Ember" },
            { value: "oklch(0.78 0.14 200)", label: "Glass" },
            { value: "oklch(0.82 0.15 110)", label: "Lime" },
            { value: "oklch(0.74 0.16 320)", label: "Magenta" },
          ]}
        />
      </window.TweaksPanel>
    </>
  );
}

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