/* global React, ReactDOM */
const { useState, useEffect, useMemo } = React;

// Emoji colors — mapped to the closest filament in the real 18-color inventory
// (see PALETTE in clickaboo_keys / clickaroons). These constants flow through
// the EMOJIS catalog and into the rendered mesh + Telegram message.
const APPLE_YELLOW = "#F7D959";  // Lemon Yellow
const APPLE_RED    = "#DE4343";  // Scarlet Red
const APPLE_ORANGE = "#F99963";  // Mandarin Orange
const DARK_BROWN   = "#4D3324";  // Dark Chocolate

const PRICE_RON = 28.70;

// `baseRotZ` / `superiorRotZ` are optional per-part Z-axis rotations (radians)
// applied after the standard prep. Use them to align each part independently.
const EMOJIS = [
  // Active (4)
  { key: "flame", label: "Flacără", glyph: "🔥",
    baseUrl: "models/flame_base.stl", superiorUrl: "models/flame_superior.3mf",
    baseColor: APPLE_RED, superiorColor: APPLE_RED,
    superiorFlipY: true, superiorFlipX: false,
    superiorMoveY: 0.25,
    // Per-mesh colors for the 3MF parts, ordered from innermost (smallest)
    // to outermost (largest). Any meshes beyond this list keep the default
    // `superiorColor`.
    superiorMeshColors: ["#FFFFFF", "#F7D959", "#F99963"],  // Ivory White, Lemon Yellow, Mandarin Orange
    soon: false },
  { key: "heart", label: "Inimă", glyph: "❤️",
    baseUrl: "models/heart_base.stl", superiorUrl: "models/heart_supperior.stl",
    baseColor: APPLE_YELLOW, superiorColor: APPLE_RED,
    superiorFlipY: true, superiorRotZ: Math.PI, superiorMoveY: -0.25, soon: false },
  { key: "kiss", label: "Pupic", glyph: "😘",
    baseUrl: "models/kiss_base.stl", superiorUrl: "models/kiss-emoji-superior.3mf",
    baseColor: APPLE_YELLOW, superiorColor: APPLE_RED,
    superiorFlipY: true, superiorMoveY: 0.30,
    // Sorted by triangle count ascending: 252, 336, 448, 516, 1636, 1840.
    // Eyes + mouth brown, heart red, two largest meshes = face plate (yellow).
    superiorMeshColors: [DARK_BROWN, DARK_BROWN, APPLE_RED, DARK_BROWN, APPLE_YELLOW, APPLE_YELLOW],
    soon: false },
  { key: "love", label: "Iubire", glyph: "🥰",
    baseUrl: "models/love_base.stl", superiorUrl: "models/3-hearth-emoji-superior.3mf",
    baseColor: APPLE_YELLOW, superiorColor: APPLE_RED,
    superiorFlipY: true, superiorFlipX: true, superiorRotZ: Math.PI, superiorRotY: Math.PI, superiorMoveY: 0.30,
    // Sorted ascending: 336, 340, 396 (3 face features) then 564, 564, 564
    // (the 3 identical hearts), then 2 largest meshes = face plate (yellow).
    superiorMeshColors: [DARK_BROWN, DARK_BROWN, DARK_BROWN, APPLE_RED, APPLE_RED, APPLE_RED, APPLE_YELLOW, APPLE_YELLOW],
    soon: false },
  // Coming soon (5) — fills the 3×3 grid
  { key: "party",      label: "Petrecere", glyph: "🥳", soon: true },
  { key: "tears",      label: "Emoționat", glyph: "🥹", soon: true },
  { key: "sunglasses", label: "Cool",      glyph: "😎", soon: true },
  { key: "sensitive",  label: "Sensibil",  glyph: "🥺", soon: true },
  { key: "love_eyes",  label: "Topit",     glyph: "😍", soon: true },
];

const ACTIVE_EMOJIS = EMOJIS.filter((e) => !e.soon);
const pickRandomActiveKey = () =>
  ACTIVE_EMOJIS[Math.floor(Math.random() * ACTIVE_EMOJIS.length)].key;

// ---------- click sound (copied verbatim from clickaroons) ----------
let audioCtx = null;
function clickSound() {
  try {
    if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    const ctx = audioCtx;
    const sr = ctx.sampleRate;
    const now = ctx.currentTime;

    const burstLen = Math.floor(sr * 0.012);
    const buf = ctx.createBuffer(1, burstLen, sr);
    const data = buf.getChannelData(0);
    for (let i = 0; i < burstLen; i++) {
      const env = Math.pow(1 - i / burstLen, 2.2);
      data[i] = (Math.random() * 2 - 1) * env;
    }
    const src = ctx.createBufferSource();
    src.buffer = buf;
    const bp = ctx.createBiquadFilter();
    bp.type = "bandpass";
    bp.frequency.value = 5500 + Math.random() * 800;
    bp.Q.value = 4.5;
    const hp = ctx.createBiquadFilter();
    hp.type = "highpass";
    hp.frequency.value = 2500;
    const ng = ctx.createGain();
    ng.gain.value = 0.85;
    src.connect(bp).connect(hp).connect(ng).connect(ctx.destination);
    src.start(now);

    const o = ctx.createOscillator();
    const og = ctx.createGain();
    o.type = "sine";
    o.frequency.setValueAtTime(3800 + Math.random() * 400, now);
    o.frequency.exponentialRampToValueAtTime(2200, now + 0.012);
    og.gain.setValueAtTime(0.0001, now);
    og.gain.exponentialRampToValueAtTime(0.18, now + 0.001);
    og.gain.exponentialRampToValueAtTime(0.0001, now + 0.018);
    o.connect(og).connect(ctx.destination);
    o.start(now);
    o.stop(now + 0.022);

    const t2 = now + 0.008;
    const buf2 = ctx.createBuffer(1, Math.floor(sr * 0.008), sr);
    const d2 = buf2.getChannelData(0);
    for (let i = 0; i < d2.length; i++) {
      d2[i] = (Math.random() * 2 - 1) * Math.pow(1 - i / d2.length, 2);
    }
    const src2 = ctx.createBufferSource();
    src2.buffer = buf2;
    const bp2 = ctx.createBiquadFilter();
    bp2.type = "bandpass";
    bp2.frequency.value = 7500;
    bp2.Q.value = 6;
    const ng2 = ctx.createGain();
    ng2.gain.value = 0.6;
    src2.connect(bp2).connect(ng2).connect(ctx.destination);
    src2.start(t2);
  } catch (e) {}
}

// ---------- emoji picker ----------
function EmojiTile({ emoji, selected, onClick }) {
  const classes = [
    "cf-emoji-tile",
    selected ? "is-on" : "",
    emoji.soon ? "is-soon" : "",
  ].filter(Boolean).join(" ");
  return (
    <button
      type="button"
      className={classes}
      onClick={emoji.soon ? undefined : onClick}
      aria-label={emoji.label}
      aria-disabled={emoji.soon ? true : undefined}
      title={emoji.soon ? `${emoji.label} — disponibil curând` : emoji.label}
    >
      <span className="cf-emoji-glyph" aria-hidden="true">{emoji.glyph}</span>
      <span className="cf-emoji-label">{emoji.label}</span>
      {emoji.soon && <span className="cf-emoji-soon">Curând</span>}
    </button>
  );
}

// ---------- 3D preview ----------
function Emoji3D({ accent, emoji, soundOn }) {
  const baseProp     = useMemo(() => ({ url: emoji.baseUrl,     color: emoji.baseColor     }), [emoji.baseUrl,     emoji.baseColor]);
  const superiorProp = useMemo(() => ({ url: emoji.superiorUrl, color: emoji.superiorColor }), [emoji.superiorUrl, emoji.superiorColor]);
  const [pressedOnce, setPressedOnce] = React.useState(false);
  const handlePress = React.useCallback(() => {
    if (soundOn) clickSound();
    setPressedOnce(true);
  }, [soundOn]);
  // Reset hint when the user picks a different emoji.
  React.useEffect(() => { setPressedOnce(false); }, [emoji.key]);
  return (
    <div className="kb-stage">
      <div className="kb-platter" style={{ background: `radial-gradient(ellipse at center, ${accent}22, transparent 60%)` }}/>
      <window.EmojiViewer base={baseProp} superior={superiorProp} baseRotZ={emoji.baseRotZ || 0} baseMoveY={emoji.baseMoveY || 0} superiorRotZ={emoji.superiorRotZ || 0} superiorRotY={emoji.superiorRotY || 0} superiorFlipY={!!emoji.superiorFlipY} superiorFlipX={!!emoji.superiorFlipX} superiorMoveY={emoji.superiorMoveY || 0} superiorGradient={emoji.superiorGradient || null} superiorRim={emoji.superiorRim || null} superiorClones={emoji.superiorClones || null} superiorMeshColors={emoji.superiorMeshColors || null} splitParts={!!emoji.splitParts} onPress={handlePress} />
      <div className={`cf-hint-bubble ${pressedOnce ? "is-hidden" : ""}`} aria-hidden="true">
        Apasă emoji-ul <span className="cf-hint-icon">🔊</span>
      </div>
      <div className="kb-hint">drag pentru rotire · scroll pentru zoom · click pe emoji</div>
    </div>
  );
}

// ---------- main app ----------
const STATE_KEY = "clickamojis:state";
function loadSaved() {
  try { return JSON.parse(sessionStorage.getItem(STATE_KEY)) || {}; } catch (e) { return {}; }
}

function App() {
  const tweaksDefaults = /*EDITMODE-BEGIN*/{
    "accent": "#3D6BFF"
  }/*EDITMODE-END*/;
  const [tweaks, setTweak] = window.useTweaks(tweaksDefaults);

  const saved = loadSaved();
  const [selectedKey, setSelectedKey] = useState(() => {
    if (saved.selectedKey && ACTIVE_EMOJIS.some((e) => e.key === saved.selectedKey)) return saved.selectedKey;
    return pickRandomActiveKey();
  });
  const [soundOn,     setSoundOn]     = useState(() => typeof saved.soundOn === "boolean" ? saved.soundOn : true);

  useEffect(() => {
    try { sessionStorage.setItem(STATE_KEY, JSON.stringify({ selectedKey, soundOn })); } catch (e) {}
  }, [selectedKey, soundOn]);

  const selected = EMOJIS.find((e) => e.key === selectedKey) || ACTIVE_EMOJIS[0];

  const surprise = () => {
    const next = ACTIVE_EMOJIS[Math.floor(Math.random() * ACTIVE_EMOJIS.length)];
    setSelectedKey(next.key);
    if (soundOn) clickSound();
  };

  const accent = tweaks.accent;

  return (
    <div className="cf-app" style={{ "--accent": accent }}>
      <aside className="cf-left">
        <header className="cf-header">
          <div className="cf-brand">
            <a href="/#hero" aria-label="Înapoi la Clickaboo" className="cf-brand-link">
              <img src="/assets/logo.svg" alt="Clickaboo" className="cf-brand-logo" />
            </a>
          </div>
          <div className="cf-step">Personalizează</div>
        </header>

        <div className="cf-scroll">
          <div className="cf-section">
            <div className="cf-extras">
              <button className="cf-extra-btn" onClick={surprise}>
                <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M2 4h3l2 4 2-4h3M2 12h3l2-4M11 12h3" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"/><circle cx="13.5" cy="3" r="1" fill="currentColor"/><circle cx="3" cy="14" r="1" fill="currentColor"/></svg>
                Surprinde-mă
              </button>
              <button
                className={`cf-extra-btn ${soundOn ? "is-on" : ""}`}
                onClick={() => { setSoundOn(!soundOn); if (!soundOn) clickSound(); }}
              >
                {soundOn ? (
                  <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 6v4h2l3 3V3L5 6H3zM10.5 5.5a3 3 0 010 5M12.5 3.5a6 6 0 010 9" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>
                ) : (
                  <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 6v4h2l3 3V3L5 6H3zM11 6l4 4M15 6l-4 4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/></svg>
                )}
                Sunet click {soundOn ? "pornit" : "oprit"}
              </button>
            </div>
          </div>

          <div className="cf-section">
            <div className="cf-row-head">
              <span className="cf-label">Alege emoji-ul</span>
              <span className="cf-value">{selected.label}</span>
            </div>
            <div className="cf-emoji-grid">
              {EMOJIS.map((e) => (
                <EmojiTile
                  key={e.key}
                  emoji={e}
                  selected={!e.soon && e.key === selectedKey}
                  onClick={() => { setSelectedKey(e.key); if (soundOn) clickSound(); }}
                />
              ))}
            </div>
          </div>
        </div>

        <footer className="cf-footer">
          <div className="cf-price-row">
            <div>
              <div className="cf-price-label">Total</div>
              <div className="cf-price-sub">include printare & breloc</div>
            </div>
            <div className="cf-price">{PRICE_RON} RON</div>
          </div>
          <button className="cf-checkout" style={{ background: accent }} onClick={() => {
            if (soundOn) clickSound();
            const params = new URLSearchParams({ from: "clickamojis", price: PRICE_RON.toFixed(2) });
            window.location.href = `/keychains/?${params}`;
          }}>
            Urmatorul Pas
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M3 8h10M9 4l4 4-4 4" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>
          </button>
        </footer>
      </aside>

      <main className="cf-right">
        <div className="cf-stage-meta">
          <div className="cf-stage-title">
            <span className="cf-stage-label">Previzualizare</span>
            <span className="cf-stage-sku">CM-{selected.key.toUpperCase()}</span>
          </div>
        </div>
        <Emoji3D accent={accent} emoji={selected} soundOn={soundOn} />
        <div className="cf-legend">
          <div className="cf-chip">
            <span style={{ fontSize: 18, lineHeight: 1 }} aria-hidden="true">{selected.glyph}</span>
            <span>{selected.label}</span>
          </div>
        </div>
      </main>

      <window.TweaksPanel title="Tweaks">
        <window.TweakSection title="UI Accent">
          <window.TweakColor
            label="Accent"
            value={tweaks.accent}
            onChange={(v) => setTweak("accent", v)}
            options={["#3D6BFF", "#E85A4F", "#1A1A1E", "#40B080"]}
          />
        </window.TweakSection>
      </window.TweaksPanel>
    </div>
  );
}

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