// Create-a-token wizard: basics → curve preview → review & deploy → success

function PedbyCreate({ onNav, onLaunch, wallet, creationFee }) {
  const [step, setStep] = React.useState(0);
  const [form, setForm] = React.useState({ name: '', ticker: '', description: '', image: '', website: '', twitter: '', telegram: '', discord: '' });
  const [deployed, setDeployed] = React.useState(null);
  const [showSocial, setShowSocial] = React.useState(false);
  const [devBuy, setDevBuy] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState('');
  const [imgBusy, setImgBusy] = React.useState(false);
  const [imgErr, setImgErr] = React.useState('');

  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const canNext0 = form.name.trim() && form.ticker.trim();

  const curve = PEDBY_CURVE.init();
  const startPrice = PEDBY_CURVE.price(curve);
  const startMcap = PEDBY_CURVE.marketCapUsd(curve);

  const steps = ['Basics', 'Curve preview', 'Review & deploy'];

  const deploy = async () => {
    if (busy) return;
    setErr('');
    setBusy(true);
    try {
      let token;
      if (window.PEDBY_LIVE) {
        token = await onLaunch(form, Math.max(0, +devBuy || 0));
      } else {
        const id = (form.ticker || 'tok').toLowerCase();
        token = {
          id, ticker: form.ticker.toUpperCase(), name: form.name, tag: 'fresh off the curve',
          description: form.description || 'No description provided.', creator: 'you', createdAgo: 'just now',
          replies: 0, realEth: 0, curve: PEDBY_CURVE.init(), graduated: false, spark: [4, 4, 4, 4, 4, 4, 4, 4],
          links: { website: form.website, twitter: form.twitter, telegram: form.telegram, discord: form.discord },
        };
        await onLaunch(token);
      }
      setDeployed(token);
    } catch (e) {
      setErr((e && (e.shortMessage || e.message)) ? (e.shortMessage || e.message).slice(0, 160) : 'Deploy failed — please try again.');
    } finally {
      setBusy(false);
    }
  };

  if (deployed) {
    return (
      <div style={{ maxWidth: 560, margin: '0 auto', padding: '96px 28px', textAlign: 'center' }}>
        <div style={{ width: 56, height: 56, borderRadius: 999, background: '#E7F4EC', display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 20px' }}>
          <SfIcon name="check" size={26} stroke="#1E8C45" />
        </div>
        <div style={{ fontSize: 24, fontWeight: 700, letterSpacing: -0.5 }}>${deployed.ticker} is live on Base</div>
        <div style={{ fontSize: 14, color: '#6B7570', marginTop: 8, lineHeight: 1.55 }}>
          Deployed as a native B20 token with a fresh bonding curve. Anyone can buy in now — the curve handles price automatically.
        </div>
        {deployed.address && (
          <div style={{ marginTop: 14, fontFamily: 'JetBrains Mono', fontSize: 11.5 }}>
            <a href={PEDBY_CHAIN.explorerAddr(deployed.address)} target="_blank" rel="noreferrer">{deployed.address} ↗</a>
          </div>
        )}
        <div style={{ display: 'flex', gap: 10, justifyContent: 'center', marginTop: 28 }}>
          <Btn kind="primary" onClick={() => onNav('token', deployed.id)}>View token page</Btn>
          <Btn kind="ghost" onClick={() => onNav('marketplace')}>Back to marketplace</Btn>
        </div>
      </div>
    );
  }

  return (
    <div className="pedby-page-pad" style={{ maxWidth: 640, margin: '0 auto', padding: '48px 28px 96px' }}>
      <div style={{ fontSize: 24, fontWeight: 700, letterSpacing: -0.5, marginBottom: 6 }}>Launch a token</div>
      <div style={{ fontSize: 13.5, color: '#6B7570', marginBottom: 28 }}>Deploys as a native B20 token on Base with a fair-launch bonding curve.</div>

      {/* Stepper */}
      <div style={{ display: 'flex', gap: 8, marginBottom: 28 }}>
        {steps.map((s, i) => (
          <div key={s} style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 6 }}>
            <div style={{ height: 4, borderRadius: 999, background: i <= step ? '#1E8C45' : '#EFF2EE' }} />
            <div style={{ fontSize: 11, fontFamily: 'JetBrains Mono', color: i <= step ? '#0F4E27' : '#9AA39E' }}>{s}</div>
          </div>
        ))}
      </div>

      {step === 0 && (
        <Card pad={24} style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <div style={{ display: 'flex', gap: 16, alignItems: 'flex-start' }}>
            <label style={{ cursor: 'pointer', position: 'relative' }} title="Upload image">
              {form.image ? (
                <img src={form.image} alt="" style={{ width: 64, height: 64, borderRadius: 16, objectFit: 'cover', border: '1px solid #E6EAE6', display: 'block' }}
                  onError={e => { e.target.style.display = 'none'; }} />
              ) : (
                <Photo w={64} h={64} label={imgBusy ? '…' : '+ image'} radius={16} />
              )}
              <input type="file" accept="image/png,image/jpeg,image/gif,image/webp" style={{ display: 'none' }}
                onChange={async e => {
                  const f = e.target.files && e.target.files[0];
                  if (!f) return;
                  setImgBusy(true); setImgErr('');
                  try { set('image', await pedbyImageToDataUri(f)); }
                  catch (er) { setImgErr(er.message || 'Could not process image.'); }
                  finally { setImgBusy(false); e.target.value = ''; }
                }} />
            </label>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 12, fontWeight: 600, color: '#3B453F', marginBottom: 6 }}>
                Token image <span style={{ color: '#9AA39E', fontWeight: 500 }}>(optional — click the square to upload; it's compressed in your browser and stored fully on-chain)</span>
              </div>
              <input value={form.image.startsWith('data:') ? '(uploaded image — stored on-chain)' : form.image}
                readOnly={form.image.startsWith('data:')}
                onChange={e => set('image', e.target.value.trim())}
                placeholder="…or paste an https:// image URL" style={{ ...inputStyle, width: '100%' }} />
              {form.image && (
                <button onClick={() => set('image', '')} style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, marginTop: 6, fontFamily: 'inherit', fontSize: 11.5, fontWeight: 600, color: '#C0392B' }}>Remove image</button>
              )}
              {imgErr && <div style={{ marginTop: 6, fontSize: 11.5, fontWeight: 600, color: '#7A1E15' }}>{imgErr}</div>}
            </div>
          </div>
          <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            <span style={{ fontSize: 12, fontWeight: 600, color: '#3B453F' }}>Token name</span>
            <input value={form.name} onChange={e => set('name', e.target.value)} placeholder="e.g. BasedFrog" style={inputStyle} />
          </label>
          <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            <span style={{ fontSize: 12, fontWeight: 600, color: '#3B453F' }}>Ticker</span>
            <input value={form.ticker} onChange={e => set('ticker', e.target.value.replace(/[^a-zA-Z]/g, '').slice(0, 8))} placeholder="e.g. FROG" style={inputStyle} />
          </label>
          <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            <span style={{ fontSize: 12, fontWeight: 600, color: '#3B453F' }}>Description</span>
            <textarea value={form.description} onChange={e => set('description', e.target.value)} placeholder="What's this token about?" rows={3} style={{ ...inputStyle, height: 'auto', resize: 'vertical', paddingTop: 8 }} />
          </label>

          <button onClick={() => setShowSocial(s => !s)} style={{
            display: 'flex', alignItems: 'center', gap: 6, background: 'none', border: 'none', cursor: 'pointer',
            padding: 0, fontFamily: 'inherit', fontSize: 12, fontWeight: 600, color: '#D6398A',
          }}>
            <SfIcon name={showSocial ? 'chevDown' : 'chev'} size={13} stroke="#D6398A" />
            Social links & website <span style={{ color: '#9AA39E', fontWeight: 500 }}>(optional)</span>
          </button>

          {showSocial && (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12, padding: 14, borderRadius: 12, background: '#FDF3F8', border: '1px solid #FBE7F1' }}>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <span style={{ fontSize: 12, fontWeight: 600, color: '#3B453F' }}>Website</span>
                <input value={form.website} onChange={e => set('website', e.target.value)} placeholder="https://" style={inputStyle} />
              </label>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <span style={{ fontSize: 12, fontWeight: 600, color: '#3B453F' }}>X / Twitter</span>
                <input value={form.twitter} onChange={e => set('twitter', e.target.value)} placeholder="@yourtoken" style={inputStyle} />
              </label>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <span style={{ fontSize: 12, fontWeight: 600, color: '#3B453F' }}>Telegram</span>
                <input value={form.telegram} onChange={e => set('telegram', e.target.value)} placeholder="t.me/yourtoken" style={inputStyle} />
              </label>
              <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                <span style={{ fontSize: 12, fontWeight: 600, color: '#3B453F' }}>Discord</span>
                <input value={form.discord} onChange={e => set('discord', e.target.value)} placeholder="discord.gg/…" style={inputStyle} />
              </label>
            </div>
          )}
        </Card>
      )}

      {step === 1 && (
        <Card pad={24}>
          <div style={{ fontSize: 13, fontWeight: 700, marginBottom: 4 }}>Fixed curve parameters</div>
          <div style={{ fontSize: 12.5, color: '#6B7570', marginBottom: 18, lineHeight: 1.5 }}>
            Every token launches with the same virtual reserves — no one gets a price advantage by launching, price only moves from real buys and sells.
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12, marginBottom: 18 }}>
            {[
              ['Starting price', PEDBY_CURVE.fmtUsd(startPrice * PEDBY_CURVE.ETH_USD, false)],
              ['Starting market cap', PEDBY_CURVE.fmtUsd(startMcap)],
              ['Total supply', '1,000,000,000'],
              ['Graduation target', PEDBY_CURVE.fmtEth(PEDBY_CURVE.GRADUATION_ETH) + ' raised'],
            ].map(([l, v]) => (
              <div key={l} style={{ border: '1px solid #E6EAE6', borderRadius: 10, padding: 12 }}>
                <div style={{ fontFamily: 'JetBrains Mono', fontSize: 10.5, color: '#9AA39E', textTransform: 'uppercase', letterSpacing: 0.5 }}>{l}</div>
                <div className="sf-num" style={{ fontSize: 16, fontWeight: 700, marginTop: 4 }}>{v}</div>
              </div>
            ))}
          </div>
          <div style={{ fontSize: 12, color: '#6B7570', lineHeight: 1.5, background: '#F3FAF5', border: '1px solid #E6EAE6', borderRadius: 10, padding: 12 }}>
            Once {PEDBY_CURVE.fmtEth(PEDBY_CURVE.GRADUATION_ETH)} of real ETH accumulates on the curve, this token graduates automatically — liquidity locks into a Base DEX pool.
          </div>
        </Card>
      )}

      {step === 2 && (
        <Card pad={24}>
          <div style={{ fontSize: 13, fontWeight: 700, marginBottom: 14 }}>Review</div>
          <div style={{ display: 'flex', gap: 14, alignItems: 'center', marginBottom: 18 }}>
            {form.image ? (
              <img src={form.image} alt="" style={{ width: 48, height: 48, borderRadius: 12, objectFit: 'cover', border: '1px solid #E6EAE6' }} />
            ) : (
              <Photo w={48} h={48} label="img" radius={12} />
            )}
            <div>
              <div style={{ fontWeight: 700, fontSize: 15 }}>{form.name || '—'} <span style={{ fontFamily: 'JetBrains Mono', fontSize: 12, color: '#6B7570' }}>${form.ticker || '—'}</span></div>
              <div style={{ fontSize: 12.5, color: '#6B7570', maxWidth: 380 }}>{form.description || 'No description provided.'}</div>
            </div>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12.5, color: '#3B453F', padding: '10px 0', borderTop: '1px solid #EFF2EE' }}>
            <span>Network</span><span style={{ fontWeight: 600 }}>Base</span>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12.5, color: '#3B453F', padding: '10px 0', borderTop: '1px solid #EFF2EE' }}>
            <span>Standard</span><span style={{ fontWeight: 600 }}>B20 (native token)</span>
          </div>
          {creationFee != null && creationFee > 0 && (
            <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12.5, color: '#3B453F', padding: '10px 0', borderTop: '1px solid #EFF2EE' }}>
              <span>Platform launch fee</span><span className="sf-num" style={{ fontWeight: 600 }}>{creationFee} ETH</span>
            </div>
          )}
          <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12.5, color: '#3B453F', padding: '10px 0', borderTop: '1px solid #EFF2EE' }}>
            <span>Network gas (estimated)</span><span className="sf-num" style={{ fontWeight: 600 }}>~0.0001 ETH</span>
          </div>
          {window.PEDBY_LIVE && (
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', fontSize: 12.5, color: '#3B453F', padding: '10px 0', borderTop: '1px solid #EFF2EE' }}>
              <span>First buy <span style={{ color: '#9AA39E' }}>(optional, front-runs snipers)</span></span>
              <input type="number" min="0" step="0.01" value={devBuy} onChange={e => setDevBuy(e.target.value)}
                placeholder="0.00 ETH" style={{ ...inputStyle, height: 32, width: 110, textAlign: 'right', fontFamily: 'JetBrains Mono', fontSize: 12 }} />
            </div>
          )}
          {err && (
            <div style={{ marginTop: 12, background: '#FBE3E0', color: '#7A1E15', borderRadius: 10, padding: '10px 12px', fontSize: 12.5, fontWeight: 600 }}>{err}</div>
          )}
          {(form.website || form.twitter || form.telegram || form.discord) && (
            <div style={{ marginTop: 14, paddingTop: 14, borderTop: '1px solid #EFF2EE' }}>
              <div style={{ fontSize: 11, fontFamily: 'JetBrains Mono', color: '#9A2367', textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 8 }}>Links</div>
              <SocialLinks links={{ website: form.website, twitter: form.twitter, telegram: form.telegram, discord: form.discord }} />
            </div>
          )}
        </Card>
      )}

      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 22 }}>
        <Btn kind="ghost" onClick={() => step === 0 ? onNav('marketplace') : setStep(step - 1)}>{step === 0 ? 'Cancel' : 'Back'}</Btn>
        {step < 2 ? (
          <Btn kind="primary" disabled={step === 0 && !canNext0} style={step === 0 && !canNext0 ? { opacity: 0.4, cursor: 'not-allowed' } : {}} onClick={() => (step === 0 ? canNext0 : true) && setStep(step + 1)}>Continue</Btn>
        ) : (
          <Btn kind="primary" icon={<SfIcon name="bolt" size={15} stroke="#fff" />} onClick={deploy} style={busy ? { opacity: 0.6, cursor: 'wait' } : {}}>
            {busy ? 'Deploying…' : 'Deploy on Base'}
          </Btn>
        )}
      </div>
    </div>
  );
}

// Convert an uploaded image to an on-chain-ready data URI, entirely client-side:
// small GIFs are embedded as-is (keeps animation); everything else is cover-cropped
// to a 256x256 square and compressed until it fits comfortably in calldata.
const PEDBY_IMG_MAX_BYTES = 48 * 1024; // ~48KB data URI ≈ pennies of gas on Base
function pedbyImageToDataUri(file) {
  return new Promise((resolve, reject) => {
    if (!/^image\//.test(file.type)) return reject(new Error('Please choose an image file.'));
    const reader = new FileReader();
    reader.onerror = () => reject(new Error('Could not read the file.'));
    reader.onload = () => {
      const raw = reader.result;
      // animated GIFs lose animation through canvas — embed small ones untouched
      if (file.type === 'image/gif' && raw.length <= PEDBY_IMG_MAX_BYTES) return resolve(raw);
      const img = new Image();
      img.onerror = () => reject(new Error('Could not decode the image.'));
      img.onload = () => {
        const S = 256, c = document.createElement('canvas');
        c.width = S; c.height = S;
        const x = c.getContext('2d');
        // cover-crop to square
        const side = Math.min(img.width, img.height);
        const sx = (img.width - side) / 2, sy = (img.height - side) / 2;
        x.drawImage(img, sx, sy, side, side, 0, 0, S, S);
        let out = c.toDataURL('image/png');
        if (out.length > PEDBY_IMG_MAX_BYTES) {
          for (const q of [0.85, 0.7, 0.55, 0.4]) {
            out = c.toDataURL('image/jpeg', q);
            if (out.length <= PEDBY_IMG_MAX_BYTES) break;
          }
        }
        if (out.length > PEDBY_IMG_MAX_BYTES) return reject(new Error('Image is too detailed to fit on-chain — try a simpler one, or paste a URL instead.'));
        resolve(out);
      };
      img.src = raw;
    };
    reader.readAsDataURL(file);
  });
}

const inputStyle = {
  height: 40, borderRadius: 10, border: '1px solid #E6EAE6', padding: '0 12px',
  fontSize: 13.5, fontFamily: 'inherit', outline: 'none', background: '#fff',
};

window.PedbyCreate = PedbyCreate;
