// Ambassador Dashboard — 3 tabs: My Posts, Sprints, My Application
const { useState: useStateD, useMemo: useMemoD } = React;

function DashboardPage({ user, onLogout }) {
  const [tab, setTab] = useStateD('posts');
  const [posts, setPosts] = useStateD(window.MOCK_POSTS || []);

  // Refetch posts on every mount so navigating Admin→Dashboard shows current data.
  React.useEffect(() => {
    let cancelled = false;
    window._api.getPosts().then((p) => {
      if (cancelled) return;
      const list = Array.isArray(p) ? p : [];
      setPosts(list);
      window.MOCK_POSTS = list;
    }).catch(() => {});
    return () => { cancelled = true; };
  }, []);

  // Sprints tab is only available to approved ambassadors + staff. Pending users
  // can post but don't see sprint assignments until the team approves them.
  const isStaff = user.role === 'admin' || user.role === 'superadmin';
  const canSeeSprints = isStaff || user.status === 'approved';
  const tabs = [
    { value: 'posts',    label: 'My Posts' },
    ...(canSeeSprints ? [{ value: 'sprints', label: 'Sprints' }] : []),
  ];
  // If a pending user lands on sprints somehow, snap back to posts.
  React.useEffect(() => {
    if (!canSeeSprints && tab === 'sprints') setTab('posts');
  }, [canSeeSprints, tab]);

  return (
    <main className="dash">
      <div className="container">
        <header className="dash-head">
          <div>
            <span className="kicker">Bloom · Ambassador</span>
            <h1 className="serif-h1">Ambassador Dashboard</h1>
          </div>
          <div className="dash-head-right">
            <StatusBadge status={user.status} tier={user.tier} role={user.role}/>
          </div>
        </header>

        {user.status === 'pending' && <PendingDashboardCTA/>}

        <Tabs items={tabs} value={tab} onChange={setTab}/>
        <div className="tab-panel">
          {tab === 'posts'   && <PostsTab posts={posts} setPosts={setPosts}/>}
          {tab === 'sprints' && <SprintsTab/>}
        </div>
      </div>
    </main>
  );
}

// -------- Application page (top-level) --------
function ApplicationPage({ user, onNav }) {
  const [app, setApp] = useStateD(window.MY_APPLICATION || {});
  const [appDirty, setAppDirty] = useStateD(false);

  // Refetch on mount so navigations always show the latest server copy.
  React.useEffect(() => {
    window._api.getApplication()
      .then(d => { const obj = d || {}; setApp(obj); window.MY_APPLICATION = obj; setAppDirty(false); })
      .catch(() => {});
  }, []);

  const isRejected = user.status === 'rejected';

  return (
    <main className="dash">
      <div className="container">
        <header className="dash-head">
          <div>
            <span className="kicker">Bloom · Ambassador</span>
            <h1 className="serif-h1">My Application</h1>
          </div>
          <div className="dash-head-right">
            <StatusBadge status={user.status} tier={user.tier} role={user.role}/>
          </div>
        </header>

        {isRejected ? <RejectedView app={app}/> : (
          <React.Fragment>
            {/* Notice only shows once the user has actually submitted (status='pending').
                Brand-new users with status='waiting' see only the form. */}
            {user.status === 'pending' && <PendingNotice onNav={onNav}/>}
            <div className="tab-panel">
              <ApplicationTab app={app} setApp={setApp} dirty={appDirty} setDirty={setAppDirty} onNav={onNav}/>
            </div>
          </React.Fragment>
        )}
      </div>
    </main>
  );
}

function RejectedView({ app }) {
  if (!app || Object.keys(app).length === 0) {
    return <section className="card" style={{ padding: 24 }}>No application data on file.</section>;
  }
  const row = (label, value) => value ? (
    <div style={{ marginBottom: 12 }}>
      <div className="mono-label">{label}</div>
      <p style={{ margin: 0 }}>{String(value)}</p>
    </div>
  ) : null;
  return (
    <React.Fragment>
      <section className="pending-notice">
        <div className="pending-notice-mark"><Icon name="shield" size={20}/></div>
        <div className="pending-notice-body">
          <h3>Thanks for applying</h3>
          <p>
            We can't onboard you in this cohort, but applications will reopen soon.
            Follow <a className="link" href="https://x.com/bloom" target="_blank" rel="noreferrer">@bloom on X</a> for the next call.
          </p>
        </div>
      </section>
      <section className="card" style={{ padding: 24 }}>
        <h2 className="serif-h3" style={{ marginTop: 0 }}>What you shared with us</h2>
        {row('Real Name', app.realName)}
        {row('Region', app.region)}
        {row('Why ambassador?', app.q_why)}
        {row('Tier qualification', app.q_tier)}
      </section>
    </React.Fragment>
  );
}

// Dashboard CTA shown only to pending applicants — nudges them to start
// posting now to strengthen their application.
function PendingDashboardCTA() {
  return (
    <section className="pending-cta">
      <div className="pending-cta-mark"><Icon name="send" size={20}/></div>
      <div className="pending-cta-body">
        <h3>Get a head start on your application</h3>
        <p>
          Your application is being reviewed. You can already start submitting
          posts about Bloom below. Quality posts during the review window{' '}
          <strong>strengthen your application</strong> and increase your chance
          of being selected.
        </p>
      </div>
    </section>
  );
}

function PendingNotice({ onNav }) {
  return (
    <section className="pending-notice">
      <div className="pending-notice-mark"><Icon name="shield" size={20}/></div>
      <div className="pending-notice-body">
        <h3>Your application is in review</h3>
        <p>
          The Bloom team reviews each applicant manually. While we get to it,
          you can already start posting about Bloom. Head to your{' '}
          <a href="#/dashboard" className="link" onClick={(e) => { e.preventDefault(); onNav && onNav('dashboard'); }}>
            dashboard
          </a>{' '}
          and submit your first post. The Sprints tab will unlock once approved.
        </p>
      </div>
    </section>
  );
}

// -------- TAB 1: My Posts --------
function PostsTab({ posts, setPosts }) {
  const [form, setForm] = useStateD({ type: '', sprint: '', url: '' });
  const [submitting, setSubmitting] = useStateD(false);

  const submit = (e) => {
    e.preventDefault();
    if (!form.type || !form.url || submitting) return;
    setSubmitting(true);
    window._api.submitPost({
      type: form.type,
      sprint: form.sprint ? Number(form.sprint) : null,
      url: form.url,
    }).then((newPost) => {
      // newPost is the server's canonical row (real id, server date, etc.)
      setPosts([newPost, ...posts]);
      window.MOCK_POSTS = [newPost, ...posts];
      setForm({ type: '', sprint: '', url: '' });
    }).catch(err => {
      window.ui && window.ui.toast(err.message, { kind: 'error' });
    }).finally(() => setSubmitting(false));
  };

  const remove = async (id) => {
    const ok = await window.ui.confirm({
      title: 'Delete this post?',
      message: 'This will remove the submission from your dashboard. It cannot be undone.',
      danger: true,
      confirmLabel: 'Delete',
    });
    if (!ok) return;
    window._api.deletePost(id).then(() => {
      const next = posts.filter(p => p.id !== id);
      setPosts(next);
      window.MOCK_POSTS = next;
      window.ui.toast('Post deleted.', { kind: 'success' });
    }).catch(err => window.ui.toast(err.message, { kind: 'error' }));
  };

  return (
    <div className="posts-tab">
      <section className="card">
        <header className="card-head">
          <h2 className="serif-h3">Submit Post</h2>
          <p className="card-sub">Submit a thesis, update, or X content tied to a Sprint.</p>
        </header>
        <form className="post-form" onSubmit={submit}>
          <div className="select-wrap">
            <select value={form.type} onChange={(e) => setForm({ ...form, type: e.target.value })}>
              <option value="">Select Type</option>
              {['Thesis','Update','Thread','Video','Space','Translation','Other'].map(t => <option key={t}>{t}</option>)}
            </select>
            <Icon name="chevron-down" size={14}/>
          </div>
          <input
            type="number" min="0" max="33"
            placeholder="Sprint Number"
            value={form.sprint}
            onChange={(e) => setForm({ ...form, sprint: e.target.value })}
          />
          <input
            type="url"
            placeholder="https://x.com/…"
            value={form.url}
            onChange={(e) => setForm({ ...form, url: e.target.value })}
          />
          <button type="submit" className="btn btn-primary" disabled={submitting}>
            <Icon name="send" size={14}/> {submitting ? 'Submitting…' : 'Submit'}
          </button>
        </form>
      </section>

      <section className="card mt-32">
        <header className="card-head row">
          <div>
            <h2 className="serif-h3">Your Submitted Posts</h2>
            <p className="card-sub">Metrics and ratings are updated by Bloom during review.</p>
          </div>
          <span className="mono-label">{posts.length} entries</span>
        </header>
        <div className="table-wrap">
          <table className="data-table">
            <thead>
              <tr>
                <th>Platform</th>
                <th>Type</th>
                <th>Sprint</th>
                <th>Post URL</th>
                <th>Date</th>
                <th>Rating</th>
                <th>Comment</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {posts.map(p => (
                <tr key={p.id}>
                  <td><span className="x-mark">𝕏</span></td>
                  <td>{p.type}</td>
                  <td className="mono">{p.sprint ?? '—'}</td>
                  <td><a className="link" href={window.safeHref(p.url)} target="_blank" rel="noreferrer">{shortUrl(p.url)}</a></td>
                  <td className="mono">{fmtDate(p.date)}</td>
                  <td>{p.rating != null ? <span className="rating">{p.rating}/10</span> : <span className="dash">—</span>}</td>
                  <td className="comment-cell">{p.comment || <span className="dash">—</span>}</td>
                  <td>
                    <button className="icon-btn" onClick={() => remove(p.id)} aria-label="Delete"><Icon name="trash" size={14}/></button>
                  </td>
                </tr>
              ))}
              {posts.length === 0 && (
                <tr><td colSpan="8" className="empty">No posts yet. Submit your first thesis above.</td></tr>
              )}
            </tbody>
          </table>
        </div>
      </section>
    </div>
  );
}

function shortUrl(u) {
  try {
    const url = new URL(u);
    const tail = url.pathname.split('/').filter(Boolean).pop() || '';
    return `${url.host.replace(/^www\./,'')}/…${tail.slice(-8)}`;
  } catch { return u; }
}
function fmtDate(d) {
  if (!d) return '—';
  const s = String(d);
  const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(s);
  if (!m) return s;
  return `${m[3]}/${m[2]}/${m[1]}`;
}

// -------- TAB 2: Sprints --------
function SprintsTab() {
  const [openId, setOpenId] = useStateD(null);
  const [sprints, setSprints] = useStateD(window.SPRINT_GRID || []);

  // Refetch every time this tab mounts so admin changes show up immediately.
  React.useEffect(() => {
    let cancelled = false;
    window._api.getSprints().then(d => {
      if (cancelled) return;
      const list = Array.isArray(d) ? d : [];
      setSprints(list);
      window.SPRINT_GRID = list;
    }).catch(() => {});
    return () => { cancelled = true; };
  }, []);
  return (
    <div className="sprints-tab">
      <section className="card">
        <header className="card-head row">
          <div>
            <h2 className="serif-h3">Sprints <span className="mono-count">({sprints.length})</span></h2>
            <p className="card-sub">Weekly activities. Click a card for details.</p>
          </div>
          <Legend/>
        </header>
        {sprints.length === 0 ? (
          <div className="empty" style={{padding:'48px 24px', textAlign:'center', color:'var(--ink-400)'}}>
            No sprints yet. The Bloom team will post weekly tasks here once the program begins.
          </div>
        ) : (
          <div className="sprint-grid">
            {sprints.map(s => (
              <button key={s.n} className={`sprint-card ${s.status} ${openId === s.n ? 'open' : ''}`} onClick={() => setOpenId(openId === s.n ? null : s.n)}>
                <div className="sprint-card-top">
                  <span className="sprint-n-big">{s.n}</span>
                  <span className={`sprint-dot ${s.status}`}></span>
                </div>
                <div className="sprint-card-title">{s.title || <em className="muted">No description</em>}</div>
                <div className="sprint-card-snip">{s.snippet || ''}</div>
              </button>
            ))}
          </div>
        )}
      </section>

      {openId != null && (() => {
        const s = sprints.find(x => x.n === openId);
        if (!s) return null;
        return (
          <Modal open onClose={() => setOpenId(null)}>
            <header className="modal-head">
              <div>
                <span className="mono-label">Sprint {String(s.n).padStart(2, '0')}</span>
                <h3 className="serif-h2">{s.title || 'Untitled'}</h3>
              </div>
              <button className="icon-btn" onClick={() => setOpenId(null)}><Icon name="x" size={16}/></button>
            </header>
            <div className="modal-body">
              <SprintDetail label="The Moment" body={s.moment}/>
              <SprintDetail label="Objective" body={s.objective}/>
              <SprintDetail label="What's New" body={s.whatsNew}/>
              <SprintDetail label="Resources" body={s.resources}/>
            </div>
          </Modal>
        );
      })()}
    </div>
  );
}
function Legend() {
  return (
    <div className="legend">
      <span><i className="dot active"></i>Active</span>
      <span><i className="dot pending"></i>Pending</span>
      <span><i className="dot ended"></i>Ended</span>
      <span><i className="dot empty"></i>Empty</span>
    </div>
  );
}
function SprintDetail({ label, body }) {
  return (
    <div className="sprint-detail">
      <div className="mono-label">{label}</div>
      <p>{body || <span className="muted">—</span>}</p>
    </div>
  );
}

// -------- TAB 3: My Application — slim version --------
const APPLICATION_REQUIRED = [
  { key: 'realName',         label: 'Real Name' },
  { key: 'displayName',      label: 'Display Name' },
  { key: 'region',           label: 'Local Region' },
  { key: 'languages',        label: 'Content Languages' },
  { key: 'email',            label: 'Email' },
  { key: 'telegram',         label: 'Telegram Username' },
  { key: 'twitter',          label: 'Twitter Display Name' },
  { key: 'years',            label: 'Crypto Years of Experience' },
  { key: 'tradingPlatforms', label: 'Where do you usually trade?' },
  { key: 'monthlyVolume',    label: 'Average Monthly Trading Volume' },
  { key: 'volumeProof',      label: 'Volume Proof', isArray: true },
  { key: 'hasRefRevenue',    label: 'Referral fee revenue' },
  { key: 'ack_nfa',          label: 'NFA Acknowledgment',     match: 'Yes' },
  { key: 'ack_disc',         label: 'Rewards Acknowledgment', match: 'Yes' },
  { key: 'ack_conduct',      label: 'Conduct Acknowledgment', match: 'Yes' },
  { key: 'tier',             label: 'Applying Tier' },
  { key: 'q_tier',           label: 'Tier Qualification' },
  { key: 'q_why',            label: 'Why do you want to be an Ambassador?' },
];

function ApplicationTab({ app, setApp, dirty, setDirty, onNav }) {
  const [errors, setErrors] = useStateD({});

  const set = (k, v) => {
    setApp({ ...app, [k]: v });
    setDirty(true);
    if (errors[k]) setErrors({ ...errors, [k]: false });
  };

  const validate = () => {
    const errs = {};
    let first = null;
    const required = APPLICATION_REQUIRED.slice();
    if (app.hasRefRevenue === 'Yes') {
      required.push({ key: 'refRevenue', label: 'Approx. monthly referral revenue' });
      required.push({ key: 'refProof',   label: 'Referral Revenue Proof', isArray: true });
    }
    for (const f of required) {
      const v = app[f.key];
      const empty = f.isArray
        ? (!v || v.length === 0)
        : f.match ? v !== f.match
        : (!v || (typeof v === 'string' && !v.trim()));
      if (empty) { errs[f.key] = true; if (!first) first = f.label; }
    }
    setErrors(errs);
    if (first) { window.ui && window.ui.toast('Missing required field: ' + first, { kind: 'error' }); return false; }
    return true;
  };

  const save = () => {
    if (!validate()) return;
    window._api.saveApplication(app)
      .then(d => {
        const obj = d || app;
        setApp(obj); window.MY_APPLICATION = obj;
        setDirty(false); setErrors({});
        // Inline toast so the message appears near where they clicked, not
        // floating in the centre of the page. Then bounce them to the
        // dashboard so they can start submitting posts right away.
        window.ui && window.ui.toast('Application submitted. We’ll review it manually.', { kind: 'success', duration: 5200 });
        if (onNav) setTimeout(() => onNav('dashboard'), 250);
      })
      .catch(err => window.ui && window.ui.toast(err.message, { kind: 'error' }));
  };
  const cancel = () => { setApp(window.MY_APPLICATION || {}); setDirty(false); setErrors({}); };

  const req = (k) => errors[k] ? 'field-error' : '';

  return (
    <div className="app-tab">
      <header className="app-tab-head">
        <div>
          <h2 className="serif-h3">Edit Application</h2>
          <p className="card-sub">{app.submittedAt ? `Submitted on ${fmtDate(app.submittedAt)}. Edits update your file with the Bloom team.` : 'Fill in your application. Edits update your file with the Bloom team.'}</p>
        </div>
        <div className="app-tab-actions">
          <button className="btn btn-ghost" onClick={cancel} disabled={!dirty}><Icon name="x" size={14}/> Cancel</button>
          <button className="btn btn-primary" onClick={save} disabled={!dirty}><Icon name="send" size={14}/> Submit Application</button>
        </div>
      </header>

      {/* PERSONAL */}
      <FormSection title="Personal">
        <div className="form-grid">
          <Field label="Real Name" required className={req('realName')}><input value={app.realName || ''} onChange={(e) => set('realName', e.target.value)}/></Field>
          <Field label="Display Name" required className={req('displayName')}><input value={app.displayName || ''} onChange={(e) => set('displayName', e.target.value)}/></Field>
          <Field label="Local Region" span2 required className={req('region')}>
            <RadioGroup name="region" value={app.region} onChange={(v) => set('region', v)} columns={5}
              options={['Americas','Europe','Africa','Asia','Other']}/>
          </Field>
          <Field label="Content Languages" span2 required className={req('languages')}>
            <input value={app.languages || ''} onChange={(e) => set('languages', e.target.value)} placeholder="English, Mandarin, …"/>
          </Field>
        </div>
      </FormSection>

      {/* SOCIALS */}
      <FormSection title="Socials & Contact">
        <div className="form-grid">
          <Field label="Email" required className={req('email')}><input type="email" value={app.email || ''} onChange={(e) => set('email', e.target.value)}/></Field>
          <Field label="Telegram Username" required className={req('telegram')}><input value={app.telegram || ''} onChange={(e) => set('telegram', e.target.value)} placeholder="@handle"/></Field>
          <Field label="Discord Username"><input value={app.discord || ''} onChange={(e) => set('discord', e.target.value)}/></Field>
          <Field label="Twitter (x.com) Display Name" required className={req('twitter')}><input value={app.twitter || ''} onChange={(e) => set('twitter', e.target.value)}/></Field>
          <Field label="LinkedIn"><input value={app.linkedin || ''} onChange={(e) => set('linkedin', e.target.value)}/></Field>
          <Field label="YouTube Channel"><input value={app.youtube || ''} onChange={(e) => set('youtube', e.target.value)}/></Field>
          <Field label="TikTok Display Name"><input value={app.tiktok || ''} onChange={(e) => set('tiktok', e.target.value)}/></Field>
          <Field label="Twitch / Kick"><input value={app.twitch || ''} onChange={(e) => set('twitch', e.target.value)}/></Field>
        </div>
      </FormSection>

      {/* EXPERIENCE */}
      <FormSection title="Experience">
        <div className="form-grid">
          <Field label="Crypto Years of Experience" span2 required className={req('years')}>
            <RadioGroup name="years" value={app.years} onChange={(v) => set('years', v)} columns={4}
              options={['1–2','2–5','5–10','Satoshi']}/>
          </Field>
          <Field label="Where do you usually trade?" span2 required className={req('tradingPlatforms')}
            help="List the venues you actively use, separated by commas.">
            <input value={app.tradingPlatforms || ''} onChange={(e) => set('tradingPlatforms', e.target.value)} placeholder="e.g. Bloom, Photon, Jupiter, Binance"/>
          </Field>
          <Field label="Average Monthly Trading Volume" span2 required className={req('monthlyVolume')}>
            <RadioGroup name="monthlyVolume" value={app.monthlyVolume} onChange={(v) => set('monthlyVolume', v)} columns={3}
              options={['< $5K','$5K–10K','$10K–50K','$50K–100K','$100K–500K','$500K+']}/>
          </Field>
          <Field label="Volume Proof (screenshots)" span2 required className={req('volumeProof')}
            help="Upload screenshots of your trading dashboard or volume (venue, last 30 days). PII can be redacted.">
            <ImageUploader value={app.volumeProof} onChange={(v) => set('volumeProof', v)}/>
          </Field>
          <Field label="Do you currently earn referral fee revenue?" span2 required className={req('hasRefRevenue')}>
            <RadioGroup name="hasRefRevenue" value={app.hasRefRevenue} onChange={(v) => set('hasRefRevenue', v)} columns={3}
              options={['Yes','No','Prefer not to say']}/>
          </Field>
          {app.hasRefRevenue === 'Yes' && (
            <React.Fragment>
              <Field label="Approx. monthly referral revenue" span2 required className={req('refRevenue')}>
                <RadioGroup name="refRevenue" value={app.refRevenue} onChange={(v) => set('refRevenue', v)} columns={3}
                  options={['< $500','$500–2K','$2K–10K','$10K–50K','$50K+']}/>
              </Field>
              <Field label="Referral Revenue Proof (screenshots)" span2 required className={req('refProof')}
                help="Upload screenshots of your referral dashboard. Source URL or partner name visible if possible.">
                <ImageUploader value={app.refProof} onChange={(v) => set('refProof', v)}/>
              </Field>
            </React.Fragment>
          )}
        </div>
      </FormSection>

      {/* ACK */}
      <FormSection title="Acknowledgments">
        <ul className="ack-list">
          {[
            { key: 'ack_nfa',     title: 'No financial advice',       body: 'I understand content I publish via Bloom is opinion, not financial advice. Trades I post reflect my own positions.' },
            { key: 'ack_disc',    title: 'Rewards are discretionary', body: 'Tier, fee share, and Bloom Points are reviewed monthly and may be adjusted by the Bloom team based on conduct and contribution.' },
            { key: 'ack_conduct', title: 'Code of conduct',           body: "I have read the Code of Conduct and agree to keep Soft Launch confidential, post real positions, and avoid promoting direct competitors while I'm an ambassador." },
          ].map(item => (
            <li key={item.key} className={(app[item.key] === 'Yes' ? 'ack-item on' : 'ack-item') + (errors[item.key] ? ' field-error' : '')}>
              <button type="button" className="ack-toggle" onClick={() => set(item.key, app[item.key] === 'Yes' ? 'No' : 'Yes')} aria-pressed={app[item.key] === 'Yes'}>
                <span className="ack-check"><Icon name="check" size={14}/></span>
              </button>
              <div className="ack-copy">
                <h4>{item.title}</h4>
                <p>{item.body}</p>
              </div>
            </li>
          ))}
        </ul>
      </FormSection>

      {/* TIER */}
      <FormSection title="Tier Application">
        <div className="form-grid">
          <Field label="Applying Tier" span2 required className={req('tier')}>
            <RadioGroup name="tier" value={app.tier} onChange={(v) => set('tier', v)} columns={3}
              options={[{ value: 'scout', label: 'Scout (Tier I)' }, { value: 'ranger', label: 'Ranger (Tier II)' }, { value: 'apex', label: 'Apex (Tier III)' }]}/>
          </Field>
          <Field span2 label="Tier Qualification" required className={req('q_tier')}>
            <textarea rows="3" value={app.q_tier || ''} onChange={(e) => set('q_tier', e.target.value)}/>
          </Field>
          <Field span2 label="Why do you want to be an Ambassador?" required className={req('q_why')}>
            <textarea rows="3" value={app.q_why || ''} onChange={(e) => set('q_why', e.target.value)}/>
          </Field>
          <Field span2 label="Anything Else">
            <textarea rows="2" value={app.q_else || ''} onChange={(e) => set('q_else', e.target.value)}/>
          </Field>
          <Field label="Referral Code">
            <input value={app.referral || ''} onChange={(e) => set('referral', e.target.value)} placeholder="e.g. ALICE2026"/>
          </Field>
          <Field label="Ambassador Code"
            help="Your unique referral code for the program. Max 10 chars.">
            <input value={app.ambCode || ''} onChange={(e) => set('ambCode', e.target.value.slice(0, 10))} placeholder="e.g. AMB-ALICE"/>
          </Field>
        </div>
      </FormSection>

      <div className="app-tab-actions floating">
        <button className="btn btn-ghost" onClick={cancel} disabled={!dirty}>Cancel</button>
        <button className="btn btn-primary" onClick={save} disabled={!dirty}><Icon name="send" size={14}/> Submit Application</button>
      </div>
    </div>
  );
}

// ---- ImageUploader: drag/drop or click to add screenshots ----
function ImageUploader({ value, onChange }) {
  const items = value || [];
  const inputRef = React.useRef(null);
  const onPick = (files) => {
    const list = Array.from(files || []);
    const reads = list.slice(0, 6).map(f => new Promise((res) => {
      const r = new FileReader();
      r.onload = () => res({ id: 'img_' + Math.random().toString(36).slice(2,8), name: f.name, dataUrl: r.result });
      r.readAsDataURL(f);
    }));
    Promise.all(reads).then(newOnes => onChange([...items, ...newOnes].slice(0, 8)));
  };
  const remove = (id) => onChange(items.filter(i => i.id !== id));
  return (
    <div className="img-uploader">
      <div className="img-thumbs">
        {items.map(i => (
          <div key={i.id} className="img-thumb">
            <img src={i.dataUrl} alt={i.name}/>
            <button type="button" className="img-thumb-x" onClick={() => remove(i.id)} aria-label="Remove"><Icon name="x" size={12}/></button>
            <span className="img-thumb-name">{i.name}</span>
          </div>
        ))}
        {items.length < 8 && (
          <button type="button" className="img-add" onClick={() => inputRef.current && inputRef.current.click()}>
            <Icon name="plus" size={18}/>
            <span>Add screenshot</span>
            <span className="img-add-hint">PNG, JPG · up to 8</span>
          </button>
        )}
      </div>
      <input ref={inputRef} type="file" accept="image/*" multiple style={{ display: 'none' }}
        onChange={(e) => { onPick(e.target.files); e.target.value = ''; }}/>
    </div>
  );
}

function FormSection({ num, title, sub, children }) {
  return (
    <section className="form-section" data-sub={sub || ''}>
      <div className="form-section-head">
        <h3 className="serif-h3">{title}</h3>
        {sub && <p className="form-section-sub">{sub}</p>}
      </div>
      {children}
    </section>
  );
}


window.DashboardPage = DashboardPage;
window.ApplicationPage = ApplicationPage;
