// brownie/app.jsx — pager shell + bottom tabbar + entry point.

const TAB_ICONS = {
  bakery: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <rect x="4" y="6" width="16" height="14" rx="3" />
      <circle cx="9" cy="11" r="1.2" fill="currentColor" stroke="none" />
      <circle cx="15" cy="13" r="1.2" fill="currentColor" stroke="none" />
      <circle cx="11" cy="16" r="1.2" fill="currentColor" stroke="none" />
    </svg>
  ),
  store: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M3 8 L5 4 L19 4 L21 8 L21 9 Q21 11 19 11 Q17 11 17 9 Q17 11 15 11 Q13 11 13 9 Q13 11 11 11 Q9 11 9 9 Q9 11 7 11 Q5 11 5 9 Q5 11 3 11 Q3 11 3 9 Z" />
      <path d="M5 11 L5 20 L19 20 L19 11" />
      <path d="M9 20 L9 14 L15 14 L15 20" />
    </svg>
  ),
  mastery: (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      <path d="M12 3 L14 9 L20 9 L15 13 L17 19 L12 15 L7 19 L9 13 L4 9 L10 9 Z" />
    </svg>
  ),
};

function BootBackdrop() {
  return (
    <>
      <div className="bakery-bg" />
      {Array.from({ length: 8 }).map((_, i) => {
        const left = 8 + ((i * 91) % 84);
        const dur = 6 + (i % 5) * 1.4;
        const delay = (i * 0.7) % 6;
        return (
          <div
            key={i}
            className="bakery-particle"
            style={{ left: `${left}%`, top: '70%', '--dur': `${dur}s`, '--delay': `${delay}s` }}
          />
        );
      })}
    </>
  );
}

function BootHero({ stillBrownie }) {
  return (
    <div className="hero-stage" style={{ top: 0, bottom: 0 }}>
      <div className="hero-rays" />
      <div className="hero-glow" />
      <div className="brownie-wrap">
        {Array.from({ length: 3 }).map((_, i) => (
          <div
            key={`steam-${i}`}
            className="steam"
            style={{
              left: `${42 + i * 8}%`,
              '--sdur': `${3.2 + i * 0.4}s`,
              '--sdelay': `${i * 1.1}s`,
            }}
          />
        ))}
        <div className="brownie" style={{ cursor: 'default', animationPlayState: stillBrownie ? 'paused' : 'running' }}>
          <BrownieSVG />
        </div>
      </div>
    </div>
  );
}

function BootScreen() {
  return (
    <div className="be-stage">
      <div className="be-phone">
        <BootBackdrop />

        <div className="boot-title">
          <div className="boot-title-eyebrow">Brownie Empire</div>
          <div className="boot-title-name">Warming up</div>
          <div className="boot-title-sub">Idle Tap Game</div>
        </div>

        <BootHero />

        <div className="boot-status">
          Preheating the oven<span className="dot">.</span><span className="dot">.</span><span className="dot">.</span>
        </div>
        <div className="boot-progress-rail">
          <div className="boot-progress-fill" />
        </div>
      </div>
    </div>
  );
}

// ─── Onboarding carousel ────────────────────────────────────────────────
const ONBOARDING_STEPS = [
  {
    id: 'welcome',
    eyebrow: 'A new empire',
    title: 'Welcome to Brownie Empire',
    body: 'You inherited a tiny bakery. The world wants brownies. Build the empire that feeds them.',
    visual: 'brownie',
  },
  {
    id: 'tap',
    eyebrow: 'Step 1',
    title: 'Tap to bake',
    body: 'Every tap of the brownie drops fresh crumbs into your stash. The bigger your empire, the more each tap is worth.',
    visual: 'tap',
  },
  {
    id: 'shop',
    eyebrow: 'Step 2',
    title: 'Hire help',
    body: 'Wooden spoons, ovens, food trucks — they bake while you sleep. Open the Store and buy your first helper.',
    visual: 'store',
  },
  {
    id: 'mastery',
    eyebrow: 'Step 3',
    title: 'Master the craft',
    body: 'Upgrades multiply production. Awards add permanent bonuses. Reset for Fudge Crumbs once you hit 1T baked.',
    visual: 'mastery',
  },
  {
    id: 'name',
    eyebrow: 'Almost there',
    title: 'Name your bakery',
    body: 'How will the world know your empire? Pick a name that fits a brownie dynasty.',
    visual: 'name',
  },
];

function OnboardingVisual({ kind }) {
  if (kind === 'brownie' || kind === 'tap') {
    return (
      <div className="onb-visual">
        <div className="onb-glow" />
        <div className="onb-brownie">
          <BrownieSVG />
        </div>
        {kind === 'tap' && <div className="onb-tap-ring" />}
      </div>
    );
  }
  if (kind === 'store') {
    return (
      <div className="onb-visual">
        <div className="onb-glow" />
        <div className="onb-card-preview">
          <div className="onb-card-icon">{window.BE_PRODUCER_ICONS.spoon}</div>
          <div className="onb-card-body">
            <div className="onb-card-name">Wooden Spoon</div>
            <div className="onb-card-meta">15 crumbs · +0.1/s</div>
          </div>
        </div>
      </div>
    );
  }
  if (kind === 'mastery') {
    return (
      <div className="onb-visual">
        <div className="onb-glow" />
        <svg className="onb-star" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
          <defs>
            <linearGradient id="starG" x1="0" y1="0" x2="0" y2="1">
              <stop offset="0%" stopColor="#f4ce82" />
              <stop offset="100%" stopColor="#b06a3c" />
            </linearGradient>
          </defs>
          <path d="M32 4 L40 24 L62 24 L44 38 L52 60 L32 46 L12 60 L20 38 L2 24 L24 24 Z"
            fill="url(#starG)" stroke="#2a1408" strokeWidth="1.5" strokeLinejoin="round" />
        </svg>
      </div>
    );
  }
  if (kind === 'name') {
    return (
      <div className="onb-visual">
        <div className="onb-glow" />
        <div className="onb-sign">
          <div className="onb-sign-eyebrow">Est. today</div>
          <div className="onb-sign-name">Your Bakery</div>
        </div>
      </div>
    );
  }
  return null;
}

function Onboarding({ onFinish }) {
  const { useState } = React;
  const [step, setStep] = useState(0);
  const [bakeryName, setBakeryNameLocal] = useState('');
  const last = ONBOARDING_STEPS.length - 1;
  const s = ONBOARDING_STEPS[step];
  const isNameStep = s.id === 'name';

  const next = () => {
    if (step >= last) {
      onFinish(bakeryName.trim() || null);
    } else {
      setStep(step + 1);
    }
  };
  const prev = () => step > 0 && setStep(step - 1);

  return (
    <div className="onb-overlay">
      <BootBackdrop />

      <button className="onb-skip" onClick={() => onFinish(null)}>Skip</button>

      <div className="onb-content" key={s.id}>
        <OnboardingVisual kind={s.visual} />
        <div className="onb-eyebrow">{s.eyebrow}</div>
        <div className="onb-title">{s.title}</div>
        <div className="onb-body">{s.body}</div>

        {isNameStep && (
          <div className="onb-input-wrap">
            <input
              type="text"
              className="onb-input"
              placeholder="e.g. Sweet Crumb Co."
              value={bakeryName}
              onChange={(e) => setBakeryNameLocal(e.target.value.slice(0, 30))}
              maxLength={30}
              autoFocus
              onKeyDown={(e) => { if (e.key === 'Enter') next(); }}
            />
            <div className="onb-input-meta">{bakeryName.length}/30</div>
          </div>
        )}
      </div>

      <div className="onb-footer">
        <div className="onb-dots">
          {ONBOARDING_STEPS.map((_, i) => (
            <div
              key={i}
              className={`onb-dot ${i === step ? 'active' : ''}`}
              onClick={() => setStep(i)}
            />
          ))}
        </div>
        <div className="onb-buttons">
          {step > 0 && (
            <button className="onb-back" onClick={prev}>Back</button>
          )}
          <button className="onb-next" onClick={next}>
            {step === last ? "Let's bake" : 'Next'}
          </button>
        </div>
      </div>
    </div>
  );
}

function DailyRewardModal({ engine, onClose }) {
  const { useState } = React;
  const [reward, setReward] = useState(null);
  const [streak, setStreak] = useState(null);
  const [busy, setBusy] = useState(false);
  const [errMsg, setErrMsg] = useState(null);

  const claim = async () => {
    if (busy) return;
    setBusy(true);
    const r = await engine.claimDaily();
    setBusy(false);
    if (r?.reward) {
      setReward(r.reward);
      setStreak(r.streak);
    } else if (r?.error === 'ALREADY_CLAIMED') {
      onClose();
    } else {
      setErrMsg('Claim failed');
    }
  };

  return (
    <div className="welcome-overlay" onClick={reward ? onClose : null}>
      <div className="welcome-card daily-modal" onClick={(e) => e.stopPropagation()}>
        <div className="welcome-brownie">
          {Array.from({ length: 3 }).map((_, i) => (
            <div key={`ds-${i}`} className="welcome-steam"
              style={{ left: `${30 + i * 18}%`, '--sdur': `${3.2 + i * 0.4}s`, '--sdelay': `${i * 0.9}s` }} />
          ))}
          <BrownieSVG />
        </div>
        <div className="welcome-eyebrow">Daily Reward</div>
        {!reward ? (
          <>
            <div className="welcome-title">Fresh from the oven</div>
            <div className="welcome-sub">Day {(engine.state.dailyStreak || 0) + 1} streak</div>
            <div className="welcome-meta">Tap claim · streak grows your reward</div>
            {errMsg && <div className="welcome-meta" style={{ color: 'var(--berry)' }}>{errMsg}</div>}
            <button className="welcome-collect" onClick={claim} disabled={busy}>
              {busy ? '…' : 'Claim today'}
            </button>
          </>
        ) : (
          <>
            <div className="welcome-title">Day {streak} · Locked in</div>
            <div className="welcome-amount-wrap">
              <div className="welcome-amount">
                +{window.beFmt(reward)}
                <span className="welcome-amount-unit">crumbs</span>
              </div>
            </div>
            <div className="welcome-meta">Come back tomorrow for an even bigger drop</div>
            <button className="welcome-collect" onClick={onClose}>Back to baking</button>
          </>
        )}
      </div>
    </div>
  );
}

function WelcomeBack({ amount, onDismiss }) {
  const { useState, useEffect } = React;
  const phrase = amount < 100        ? 'a quick break'
                : amount < 10000     ? 'a little while'
                : amount < 1e6       ? 'a few hours'
                : amount < 1e9       ? 'half a day'
                :                      'a long nap';

  // Count-up animation: tick from 0 → amount over ~900ms.
  const [shown, setShown] = useState(0);
  useEffect(() => {
    const start = performance.now();
    const dur = 900;
    let raf = 0;
    const tick = (t) => {
      const p = Math.min(1, (t - start) / dur);
      const eased = 1 - Math.pow(1 - p, 3); // easeOutCubic
      setShown(amount * eased);
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [amount]);

  // 5 sparkles drifting up around the amount.
  const sparkles = Array.from({ length: 6 }).map((_, i) => {
    const angle = (i / 6) * Math.PI * 2 + 0.4;
    const dist = 50 + (i % 3) * 14;
    const dx = Math.cos(angle) * dist;
    const dy = Math.sin(angle) * dist - 30;
    return {
      id: i,
      left: `${48 + Math.cos(angle) * 18}%`,
      top: `${48 + Math.sin(angle) * 18}%`,
      dx: `${dx}px`,
      dy: `${dy}px`,
      dur: `${2.4 + (i % 4) * 0.35}s`,
      delay: `${(i * 0.18) % 1.2}s`,
    };
  });

  return (
    <div className="welcome-overlay" onClick={onDismiss}>
      <div className="welcome-card" onClick={(e) => e.stopPropagation()}>
        <div className="welcome-brownie">
          {Array.from({ length: 3 }).map((_, i) => (
            <div
              key={`ws-${i}`}
              className="welcome-steam"
              style={{
                left: `${30 + i * 18}%`,
                '--sdur': `${3.2 + i * 0.4}s`,
                '--sdelay': `${i * 0.9}s`,
              }}
            />
          ))}
          <BrownieSVG />
        </div>

        <div className="welcome-eyebrow">Welcome back</div>
        <div className="welcome-title">The oven kept baking</div>
        <div className="welcome-sub">While you were away · {phrase}</div>

        <div className="welcome-amount-wrap">
          {sparkles.map(s => (
            <div
              key={s.id}
              className="welcome-sparkle"
              style={{
                left: s.left, top: s.top,
                '--dx': s.dx, '--dy': s.dy,
                '--dur': s.dur, '--delay': s.delay,
              }}
            />
          ))}
          <div className="welcome-amount">
            +{window.beFmt(shown)}
            <span className="welcome-amount-unit">crumbs</span>
          </div>
        </div>

        <div className="welcome-meta">
          Already added to your stash · <b>50%</b> offline rate
        </div>
        <button className="welcome-collect" onClick={onDismiss}>Back to baking</button>
      </div>
    </div>
  );
}

function ErrorScreen({ message }) {
  if (message === 'NO_TELEGRAM_INIT_DATA') {
    return <PlayOnTelegramScreen />;
  }
  return (
    <div className="be-stage">
      <div className="be-phone">
        <BootBackdrop />
        <BootHero stillBrownie />

        <div className="boot-error-card">
          <div className="boot-error-title">Can't reach the bakery</div>
          <div className="boot-error-msg">{message || 'Something went wrong on our end.'}</div>
          <button className="boot-retry" onClick={() => location.reload()}>Try again</button>
        </div>
      </div>
    </div>
  );
}

function PlayOnTelegramScreen() {
  const { useState, useEffect } = React;
  const cfg = window.BE_CONFIG || {};
  const botUsername = cfg.botUsername || null;
  const shortName = cfg.miniAppShortName || null;

  // Build the deep link. If we have a mini-app short name, use the t.me/<bot>/<short>
  // form which jumps straight into the WebApp. Otherwise just open the bot chat.
  const httpLink = botUsername
    ? (shortName ? `https://t.me/${botUsername}/${shortName}` : `https://t.me/${botUsername}`)
    : null;
  const tgLink = botUsername
    ? (shortName ? `tg://resolve?domain=${botUsername}&appname=${shortName}` : `tg://resolve?domain=${botUsername}`)
    : null;

  const isMobile = /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent);

  const [countdown, setCountdown] = useState(isMobile && httpLink ? 4 : null);

  // Auto-redirect on mobile.
  useEffect(() => {
    if (countdown === null) return;
    if (countdown <= 0) {
      // Try the tg:// scheme first (opens app directly), fall back to http(s) link.
      try { window.location.href = tgLink; } catch {}
      setTimeout(() => { try { window.location.href = httpLink; } catch {} }, 600);
      return;
    }
    const id = setTimeout(() => setCountdown(countdown - 1), 1000);
    return () => clearTimeout(id);
  }, [countdown, tgLink, httpLink]);

  const open = () => {
    if (!httpLink) return;
    if (isMobile && tgLink) {
      window.location.href = tgLink;
      setTimeout(() => { window.location.href = httpLink; }, 600);
    } else {
      window.open(httpLink, '_blank');
    }
  };

  return (
    <div className="be-stage">
      <div className="be-phone">
        <BootBackdrop />
        <BootHero stillBrownie />

        <div className="play-tg-card">
          <div className="play-tg-eyebrow">Brownie Empire</div>
          <div className="play-tg-title">Play on Telegram</div>
          <div className="play-tg-sub">
            {botUsername
              ? 'This bakery only opens inside the Telegram app.'
              : 'This bakery only opens inside the Telegram app. Search for the bot to start playing.'}
          </div>

          {httpLink ? (
            <button className="play-tg-cta" onClick={open}>
              <PaperPlaneIcon /> Open in Telegram
            </button>
          ) : (
            <div className="play-tg-meta" style={{ marginTop: 18 }}>
              The bot link isn't configured yet. Set <b>PUBLIC_BOT_USERNAME</b> in Vercel.
            </div>
          )}

          {countdown !== null && countdown > 0 && (
            <div className="play-tg-meta">Redirecting in {countdown}…</div>
          )}

          <div className="play-tg-foot">
            Don't have Telegram?{' '}
            <a href="https://telegram.org/" target="_blank" rel="noreferrer">Get it here</a>
          </div>
        </div>
      </div>
    </div>
  );
}

function PaperPlaneIcon() {
  return (
    <svg viewBox="0 0 24 24" width="18" height="18" style={{ marginRight: 8, verticalAlign: 'middle' }}>
      <path d="M2 12 L22 3 L18 21 L12 14 L2 12 Z M12 14 L18 7" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinejoin="round" strokeLinecap="round" />
    </svg>
  );
}

function BrowniePager() {
  const { useState, useRef, useEffect } = React;
  const [page, setPage] = useState(0);
  const [onboardingDone, setOnboardingDone] = useState(false);
  const [dailyDismissed, setDailyDismissed] = useState(false);

  const engine = window.useBrownieEngine();

  // Show onboarding once for brand-new players: zero taps, no inventory, no offline gain pending.
  const isFirstTime = engine.status === 'ready'
    && engine.state.totalTaps === 0
    && Object.keys(engine.state.producers).length === 0
    && Object.keys(engine.state.upgrades).length === 0
    && !engine.offlineGain
    && !onboardingDone;

  // Daily reward popup is eligible when last_daily_at is null or 20+ hours old.
  // Hide while onboarding/welcome-back are showing — one modal at a time.
  const lastDaily = engine.state.lastDailyAt ? new Date(engine.state.lastDailyAt).getTime() : 0;
  const dailyEligible = engine.status === 'ready'
    && (!lastDaily || (Date.now() - lastDaily) / 3_600_000 >= 20)
    && !engine.offlineGain
    && !isFirstTime
    && !dailyDismissed;

  const [dragX, setDragX] = useState(0);
  const [dragging, setDragging] = useState(false);
  const startX = useRef(0);
  const startY = useRef(0);
  const stageRef = useRef(null);
  const axisLock = useRef(null);

  const onStart = (clientX, clientY) => {
    startX.current = clientX;
    startY.current = clientY;
    axisLock.current = null;
    setDragging(true);
  };
  const onMove = (clientX, clientY) => {
    if (!dragging) return;
    const dx = clientX - startX.current;
    const dy = clientY - startY.current;
    if (!axisLock.current) {
      if (Math.abs(dx) > 12 || Math.abs(dy) > 12) {
        axisLock.current = Math.abs(dx) > Math.abs(dy) ? 'x' : 'y';
      }
    }
    if (axisLock.current === 'x') setDragX(dx);
  };
  const onEnd = () => {
    if (!dragging) return;
    setDragging(false);
    if (axisLock.current === 'x') {
      const threshold = 60;
      if (dragX < -threshold && page < 2) setPage(page + 1);
      else if (dragX > threshold && page > 0) setPage(page - 1);
    }
    setDragX(0);
    axisLock.current = null;
  };

  useEffect(() => {
    if (engine.status !== 'ready') return;
    const el = stageRef.current;
    if (!el) return;
    const down = (e) => {
      if (e.target.closest('.be-tabbar')) return;
      const t = e.touches ? e.touches[0] : e;
      onStart(t.clientX, t.clientY);
    };
    const move = (e) => {
      const t = e.touches ? e.touches[0] : e;
      onMove(t.clientX, t.clientY);
      if (axisLock.current === 'x' && e.cancelable) e.preventDefault();
    };
    const up = () => onEnd();
    el.addEventListener('touchstart', down, { passive: true });
    el.addEventListener('touchmove', move, { passive: false });
    el.addEventListener('touchend', up);
    el.addEventListener('mousedown', down);
    window.addEventListener('mousemove', move);
    window.addEventListener('mouseup', up);
    return () => {
      el.removeEventListener('touchstart', down);
      el.removeEventListener('touchmove', move);
      el.removeEventListener('touchend', up);
      el.removeEventListener('mousedown', down);
      window.removeEventListener('mousemove', move);
      window.removeEventListener('mouseup', up);
    };
  }, [dragging, dragX, page, engine.status]);

  if (engine.status === 'booting') return <BootScreen />;
  if (engine.status === 'error')   return <ErrorScreen message={engine.errorMsg} />;

  const offsetPct = -(page * (100 / 3)) + (dragX / (stageRef.current?.offsetWidth || 420)) * (100 / 3);

  const tabs = [
    { id: 0, key: 'bakery', label: 'Bakery' },
    { id: 1, key: 'store', label: 'Store' },
    { id: 2, key: 'mastery', label: 'Mastery' },
  ];

  return (
    <div className="be-stage">
      <div className="be-phone" ref={stageRef}>
        <div
          className={`be-pager ${dragging ? 'dragging' : ''}`}
          style={{ transform: `translateX(${offsetPct}%)` }}
        >
          <window.PageBakery engine={engine} />
          <window.PageStore engine={engine} />
          <window.PageUpgrades engine={engine} />
        </div>

        <div className="be-tabbar">
          {tabs.map(t => (
            <div
              key={t.id}
              className={`be-tab ${page === t.id ? 'active' : ''}`}
              onClick={() => setPage(t.id)}
            >
              <div className="pip" />
              {TAB_ICONS[t.key]}
              <div className="lbl">{t.label}</div>
            </div>
          ))}
        </div>

        {engine.offlineGain > 1 && (
          <WelcomeBack amount={engine.offlineGain} onDismiss={engine.dismissOfflineGain} />
        )}

        {isFirstTime && (
          <Onboarding
            onFinish={(name) => {
              if (name) engine.setBakeryName(name);
              setOnboardingDone(true);
            }}
          />
        )}

        {dailyEligible && (
          <DailyRewardModal engine={engine} onClose={() => setDailyDismissed(true)} />
        )}
      </div>
    </div>
  );
}

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