// Checkout flow + Order tracking

function CheckoutPage({ session, onAdvance, onReset, go }) {
  const { step, crypto } = session;
  const { sec, label } = useCountdown(899); // 14:59

  // Once payment is verified on-chain, briefly show "delivering" then "delivered".
  React.useEffect(() => {
    if (step === 'delivering') {
      const t = setTimeout(() => onAdvance({ step: 'delivered' }), 2400);
      return () => clearTimeout(t);
    }
  }, [step]);

  return (
    <section className="max-w-[960px] mx-auto px-5 md:px-8 pt-8 md:pt-12">
      <div className="flex items-center justify-between mb-8">
        <div>
          <div className="text-[11px] mono uppercase tracking-widest text-white/40 mb-2">Secure checkout</div>
          <h1 className="text-3xl font-semibold tracking-tight">Order {session.orderId}</h1>
        </div>
        <button onClick={onReset} className="text-xs mono uppercase tracking-widest text-white/40 hover:text-white inline-flex items-center gap-1.5">
          <Icon name="x" size={12} /> Cancel
        </button>
      </div>

      <CheckoutStepper step={step} />

      <div className="grid grid-cols-1 lg:grid-cols-[1fr_320px] gap-6 mt-8">
        <div>
          {step === 'select' && <StepSelectCrypto session={session} onAdvance={onAdvance} />}
          {(step === 'paying' || step === 'detecting' || step === 'confirming') && (
            <StepPay session={session} onAdvance={onAdvance} countdownLabel={label} countdownSec={sec} />
          )}
          {step === 'delivering' && <StepDelivering session={session} />}
          {step === 'delivered' && <StepDelivered session={session} go={go} />}
        </div>

        <aside className="lg:sticky lg:top-24 lg:self-start">
          <OrderSummary session={session} />
        </aside>
      </div>
    </section>
  );
}

function CheckoutStepper({ step }) {
  const steps = [
    { id: 'select', label: '1 · Pay method' },
    { id: 'paying', label: '2 · Send payment' },
    { id: 'confirming', label: '3 · Confirming' },
    { id: 'delivered', label: '4 · Delivered' },
  ];
  const idx = {
    select: 0, paying: 1, detecting: 2, confirming: 2, delivering: 3, delivered: 3
  }[step];
  return (
    <div className="hairline rounded-xl overflow-hidden" style={{ background: 'var(--bg-1)' }}>
      <div className="grid grid-cols-4">
        {steps.map((s, i) => {
          const active = i === idx;
          const done = i < idx;
          return (
            <div key={s.id} className="p-3.5 flex items-center gap-2 text-xs mono uppercase tracking-widest border-r last:border-r-0" style={{ borderColor: 'var(--line)', color: active ? 'var(--ink)' : done ? 'var(--ok)' : 'var(--ink-mute)' }}>
              {done ? <Icon name="check" size={12} /> : active ? <span className="pulse"><Dot color="var(--accent)" size={8} /></span> : <Dot color="rgba(255,255,255,0.15)" pulse={false} size={8} />}
              <span className="truncate">{s.label}</span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function StepSelectCrypto({ session, onAdvance }) {
  const sol = CRYPTOS[0];
  const [rate, setRate] = React.useState(sol.rate);
  const [rateSource, setRateSource] = React.useState('fallback');
  const [locking, setLocking] = React.useState(false);

  React.useEffect(() => {
    let alive = true;
    fetchSolRate().then(r => {
      if (!alive || !r) return;
      setRate(r);
      setRateSource('coingecko');
    });
    return () => { alive = false; };
  }, []);

  const amount = session.variant.price / rate;

  const onContinue = () => {
    setLocking(true);
    const solAmount = Number((session.variant.price / rate).toFixed(4));
    onAdvance({
      step: 'paying',
      crypto: sol,
      solRate: rate,
      solAmount,
      recipient: SOLPAY_RECIPIENT,
      watchStartSec: Math.floor(Date.now() / 1000),
    });
  };

  return (
    <div className="glass rounded-2xl p-6">
      <h2 className="text-xl font-semibold tracking-tight mb-1">Review payment</h2>
      <p className="text-sm text-white/55 mb-5">Pay with Solana. Price locks for 15 minutes the moment you click continue.</p>
      <div className="grid grid-cols-1 gap-2">
        <div className="hairline rounded-xl p-4 selected flex items-center justify-between" style={{ borderColor: 'var(--accent)', background: 'rgba(168,123,255,0.06)' }}>
          <div className="flex items-center gap-3">
            <div className="w-10 h-10 rounded-lg flex items-center justify-center mono font-semibold" style={{ background: `${sol.color}18`, color: sol.color, border: `1px solid ${sol.color}30` }}>
              {sol.symbol}
            </div>
            <div>
              <div className="font-medium">{sol.name} <span className="text-white/40 text-xs font-normal">({sol.network})</span></div>
              <div className="text-xs text-white/50 mono">{sol.conf} confirmation required · ~30s · tolerance {(SOL_TOLERANCE * 100).toFixed(1)}%</div>
            </div>
          </div>
          <div className="text-right">
            <div className="font-medium mono">{amount.toFixed(4)} {sol.symbol}</div>
            <div className="text-xs text-white/50 mono">≈ {formatUSD(session.variant.price)} · {rateSource === 'coingecko' ? 'live' : 'fallback'} @ {formatUSD(rate)}/SOL</div>
          </div>
        </div>
      </div>
      <button
        onClick={onContinue}
        disabled={locking}
        className="btn-primary w-full mt-5 py-3.5 inline-flex items-center justify-center gap-2 disabled:opacity-60"
      >
        {locking ? 'Locking price…' : <>Lock price &amp; continue <Icon name="arrow" size={14} /></>}
      </button>
    </div>
  );
}

function StepPay({ session, onAdvance, countdownLabel, countdownSec }) {
  const { crypto, variant, step, solAmount, recipient, watchStartSec } = session;
  const amountStr = Number(solAmount).toFixed(4);
  const low = countdownSec < 300;
  const expired = countdownSec === 0;
  const [watchStatus, setWatchStatus] = React.useState({ kind: 'waiting', detail: 'Listening for on-chain payment…' });

  React.useEffect(() => {
    if (!recipient || step === 'delivered' || step === 'delivering') return;
    const cancel = watchRecipientPayment({
      recipient,
      expectedSol: Number(solAmount),
      startTimeSec: watchStartSec,
      intervalMs: 4000,
      onUpdate: (ev) => {
        if (ev.type === 'detected') {
          setWatchStatus({ kind: 'detected', detail: 'Payment detected. Verifying amount…' });
          onAdvance({ step: 'confirming', confirmed: 0, txid: ev.signature });
        } else if (ev.type === 'amount_mismatch') {
          setWatchStatus({
            kind: 'mismatch',
            detail: `Received ${ev.received.toFixed(4)} SOL — below accepted minimum of ${ev.minAccepted.toFixed(4)} SOL. Top up the difference.`,
          });
        } else if (ev.type === 'verified') {
          setWatchStatus({ kind: 'verified', detail: `Verified ${ev.received.toFixed(4)} SOL on-chain.` });
          onAdvance({ step: 'delivering', confirmed: crypto.conf, txid: ev.signature });
        } else if (ev.type === 'error') {
          setWatchStatus({ kind: 'error', detail: ev.error });
        }
      },
    });
    return cancel;
  }, [recipient, solAmount, watchStartSec, step]);

  return (
    <div className="glass rounded-2xl p-6">
      <div className="flex items-center justify-between mb-4">
        <h2 className="text-xl font-semibold tracking-tight">Send exactly</h2>
        <div className="flex items-center gap-2 text-xs mono px-3 py-1.5 rounded-full hairline" style={{ color: expired ? 'var(--bad)' : low ? 'var(--warn)' : 'var(--ink-dim)' }}>
          <Icon name="clock" size={12} /> {expired ? 'price expired' : `price locked · ${countdownLabel}`}
        </div>
      </div>

      <div className="grid grid-cols-1 md:grid-cols-[auto_1fr] gap-5 items-start">
        <div className="flex justify-center md:justify-start">
          <SolanaPayQR url={recipient} size={196} />
        </div>
        <div className="space-y-4">
          <div>
            <div className="text-[11px] mono uppercase tracking-widest text-white/40 mb-1.5">Amount · {crypto.symbol} · {crypto.network}</div>
            <Copyable text={`${amountStr} ${crypto.symbol}`} className="w-full" />
            <div className="text-xs text-white/50 mt-1 mono">
              ≈ {formatUSD(variant.price)} at {formatUSD(session.solRate || crypto.rate)}/{crypto.symbol} · tolerance {(SOL_TOLERANCE * 100).toFixed(1)}%
            </div>
          </div>
          <div>
            <div className="text-[11px] mono uppercase tracking-widest text-white/40 mb-1.5">Wallet address</div>
            <Copyable text={recipient} className="w-full" />
          </div>
          <div className="hairline rounded-lg p-3 text-xs text-white/65 flex gap-2" style={{ background: 'rgba(168,123,255,0.04)', borderColor: 'rgba(168,123,255,0.2)' }}>
            <Icon name="info" size={14} />
            <span>Scan the QR or copy the address into any Solana wallet and send <span className="mono" style={{ color: 'var(--accent)' }}>{amountStr} SOL</span>. We watch the address for an incoming transfer matching this amount (tolerance {(SOL_TOLERANCE * 100).toFixed(1)}%).</span>
          </div>
        </div>
      </div>

      <div className="mt-6 pt-6 border-t" style={{ borderColor: 'var(--line)' }}>
        <PaymentStatusRow session={session} />

        <WatcherBanner status={watchStatus} txid={session.txid} step={step} conf={crypto.conf} confirmed={session.confirmed || 0} />
      </div>
    </div>
  );
}

function WatcherBanner({ status, txid, step, conf, confirmed }) {
  let color = 'var(--accent)';
  let bg = 'var(--bg-1)';
  if (status.kind === 'verified') color = 'var(--ok)';
  else if (status.kind === 'mismatch') color = 'var(--warn)';
  else if (status.kind === 'error') color = 'var(--bad)';

  return (
    <div className="hairline rounded-xl p-4 mt-5" style={{ background: bg }}>
      <div className="flex items-center gap-3 mb-2">
        {status.kind === 'verified'
          ? <Icon name="check" size={16} style={{ color }} />
          : <span className="w-2 h-2 rounded-full pulse" style={{ background: color }} />}
        <div className="flex-1">
          <div className="text-sm font-medium" style={{ color: status.kind === 'error' ? 'var(--bad)' : 'var(--ink)' }}>
            {status.kind === 'waiting' && 'Listening for payment'}
            {status.kind === 'detected' && 'Payment detected'}
            {status.kind === 'verified' && 'Payment verified'}
            {status.kind === 'mismatch' && 'Underpaid'}
            {status.kind === 'error' && 'RPC error'}
          </div>
          <div className="text-xs text-white/55 mono break-all">{status.detail}</div>
        </div>
      </div>
      {txid && (
        <div className="text-[11px] mono text-white/40 break-all">
          sig: {txid.slice(0, 20)}…{txid.slice(-8)}
        </div>
      )}
      {step === 'confirming' && (
        <>
          <div className="flex items-center justify-between text-xs mono text-white/60 mb-1.5 mt-3">
            <span>Confirming on Solana</span>
            <span>{confirmed} / {conf}</span>
          </div>
          <div className="h-2 rounded-full overflow-hidden" style={{ background: 'rgba(255,255,255,0.06)' }}>
            <div className="h-full progress-anim transition-all duration-700" style={{ width: `${(confirmed / conf) * 100}%` }} />
          </div>
        </>
      )}
    </div>
  );
}

function SolanaPayQR({ url, size = 196 }) {
  if (!url) return <div style={{ width: size, height: size, background: '#fff', borderRadius: 12 }} />;
  const qrSize = size - 16;
  // Primary: bundled `qrcode` lib if loaded. Fallback: external QR image service (no runtime deps).
  const [libSrc, setLibSrc] = React.useState(null);
  React.useEffect(() => {
    if (!window.QRCode?.toDataURL) return;
    let alive = true;
    window.QRCode.toDataURL(url, { width: qrSize, margin: 1, color: { dark: '#07070c', light: '#ffffff' } })
      .then(d => { if (alive) setLibSrc(d); }).catch(() => {});
    return () => { alive = false; };
  }, [url, qrSize]);

  const fallbackSrc = `https://api.qrserver.com/v1/create-qr-code/?size=${qrSize}x${qrSize}&margin=0&data=${encodeURIComponent(url)}`;
  const src = libSrc || fallbackSrc;
  return (
    <div style={{ width: size, height: size, background: '#fff', padding: 8, borderRadius: 12 }}>
      <img src={src} alt="Solana Pay QR" width={qrSize} height={qrSize} style={{ display: 'block' }} />
    </div>
  );
}

function PaymentStatusRow({ session }) {
  const items = [
    { label: 'Address generated', done: true },
    { label: 'Waiting for payment', done: ['detecting', 'confirming', 'delivering', 'delivered'].includes(session.step) },
    { label: 'Confirming', done: ['delivering', 'delivered'].includes(session.step) },
    { label: 'Delivered', done: session.step === 'delivered' },
  ];
  return (
    <div className="flex items-center gap-3 text-xs mono flex-wrap">
      {items.map((it, i) => (
        <React.Fragment key={i}>
          <div className="flex items-center gap-1.5" style={{ color: it.done ? 'var(--ok)' : 'var(--ink-mute)' }}>
            {it.done ? <Icon name="check" size={12} /> : <Dot color="rgba(255,255,255,0.15)" pulse={false} size={6} />}
            {it.label}
          </div>
          {i < items.length - 1 && <span className="text-white/20">→</span>}
        </React.Fragment>
      ))}
    </div>
  );
}

function StepDelivering({ session }) {
  return (
    <div className="glass rounded-2xl p-6">
      <h2 className="text-xl font-semibold tracking-tight mb-1 flex items-center gap-2">
        <span className="pulse"><Dot color="var(--accent)" /></span> Fulfilling your order
      </h2>
      <p className="text-sm text-white/55 mb-5">Our fulfillment bot is generating your delivery. Do not close this page.</p>
      <div className="space-y-2">
        {[
          { t: '[14:23:02]', m: 'Payment confirmed · 2/2 confirmations' },
          { t: '[14:23:03]', m: 'Pulling credentials from vault…' },
          { t: '[14:23:04]', m: 'Validating account freshness…' },
          { t: '[14:23:05]', m: 'Encrypting delivery payload…' },
          { t: '[14:23:05]', m: 'Dispatching to endpoint…' },
        ].map((l, i) => (
          <div key={i} className="mono text-xs flex gap-3" style={{ animation: `fadeIn .3s ease ${i * 0.4}s both` }}>
            <span className="text-white/30">{l.t}</span>
            <span className="text-white/70">{l.m}</span>
          </div>
        ))}
      </div>
      <style>{`@keyframes fadeIn { from { opacity:0; transform: translateY(3px) } to { opacity:1; transform: none } }`}</style>
    </div>
  );
}

function StepDelivered({ session, go }) {
  const { product, variant } = session;
  const isCode = product.delivery.toLowerCase().includes('code');
  const isGift = product.delivery.toLowerCase().includes('gift');
  return (
    <div className="glass rounded-2xl p-6">
      <div className="flex items-center gap-3 mb-1">
        <div className="w-9 h-9 rounded-full flex items-center justify-center" style={{ background: 'rgba(125,243,161,0.12)', color: 'var(--ok)' }}>
          <Icon name="check" size={18} />
        </div>
        <h2 className="text-xl font-semibold tracking-tight">Delivered</h2>
      </div>
      <p className="text-sm text-white/55 mb-5">Your {product.name} · {variant.label} is ready. Save these details — they're also in your account.</p>

      {isCode && (
        <div className="space-y-3">
          <div>
            <div className="text-[11px] mono uppercase tracking-widest text-white/40 mb-1.5">Redeem code</div>
            <Copyable text="X3K7M-9BQ2L-P4V8R-J6H2N-A5TC7" className="w-full" />
          </div>
          <div className="text-xs text-white/50">Redeem at account.provider.example/redeem within 30 days.</div>
        </div>
      )}
      {isGift && (
        <div>
          <div className="text-[11px] mono uppercase tracking-widest text-white/40 mb-1.5">Gift link</div>
          <Copyable text="https://gift.chat.example/redeem/Zk3Xq9Mn2B7pL4vR" className="w-full" />
        </div>
      )}
      {!isCode && !isGift && (
        <div className="space-y-3">
          <div>
            <div className="text-[11px] mono uppercase tracking-widest text-white/40 mb-1.5">Email</div>
            <Copyable text="flame.harbor.2461@mail.example" className="w-full" />
          </div>
          <div>
            <div className="text-[11px] mono uppercase tracking-widest text-white/40 mb-1.5">Password</div>
            <Copyable text="Kq8-mvr!42Zx-nLp9" className="w-full" />
          </div>
          {product.category === 'streaming' && (
            <div>
              <div className="text-[11px] mono uppercase tracking-widest text-white/40 mb-1.5">Profile</div>
              <Copyable text="Profile: Indigo · PIN 4820" className="w-full" />
            </div>
          )}
        </div>
      )}

      <div className="mt-5 hairline rounded-xl p-4 flex gap-3 items-start" style={{ background: 'var(--bg-1)' }}>
        <Icon name="shield" size={16} style={{ color: 'var(--accent)' }} />
        <div className="text-xs text-white/65">
          <div className="text-white font-medium mb-0.5">Covered by warranty</div>
          If anything stops working within your {variant.label.split('·')[0].trim()}, open a replacement ticket from your account — auto-resolved in under 6 hours on average.
        </div>
      </div>

      <div className="grid grid-cols-2 gap-2 mt-5">
        <button onClick={() => go('account')} className="btn-ghost py-3 text-sm inline-flex items-center justify-center gap-2">
          <Icon name="user" size={14} /> View in account
        </button>
        <button onClick={() => go('home')} className="btn-primary py-3 text-sm inline-flex items-center justify-center gap-2">
          Continue shopping <Icon name="arrow" size={14} />
        </button>
      </div>
    </div>
  );
}

function OrderSummary({ session }) {
  const { product, variant, crypto, orderId } = session;
  return (
    <div className="hairline rounded-2xl p-5" style={{ background: 'var(--bg-1)' }}>
      <div className="text-[11px] mono uppercase tracking-widest text-white/40 mb-3">Order summary</div>
      <div className="flex gap-3">
        <ProductThumb product={product} size={56} rounded="rounded-lg" glyphClass="text-2xl" />
        <div className="min-w-0">
          <div className="font-medium truncate">{product.name}</div>
          <div className="text-xs text-white/55 truncate">{variant.label}</div>
        </div>
      </div>
      <div className="mt-4 pt-4 border-t space-y-2 text-sm" style={{ borderColor: 'var(--line)' }}>
        <div className="flex items-center justify-between text-white/60"><span>Subtotal</span><span className="mono">{formatUSD(variant.price)}</span></div>
        <div className="flex items-center justify-between text-white/60"><span>Network fee</span><span className="mono" style={{ color: 'var(--ok)' }}>$0.00</span></div>
        <div className="flex items-center justify-between pt-2 border-t font-semibold" style={{ borderColor: 'var(--line)' }}>
          <span>Total</span>
          <span className="mono">{formatUSD(variant.price)}</span>
        </div>
      </div>
      <div className="mt-4 pt-4 border-t text-[11px] mono text-white/50 space-y-1" style={{ borderColor: 'var(--line)' }}>
        <div className="flex justify-between"><span>Order ID</span><span>{orderId}</span></div>
        {crypto && <div className="flex justify-between"><span>Method</span><span>{crypto.symbol} · {crypto.network}</span></div>}
        <div className="flex justify-between"><span>Created</span><span>just now</span></div>
      </div>
    </div>
  );
}

Object.assign(window, { CheckoutPage });
