/* Publisher Console — B2B paid-data procurement workspace.
   Extracted from the personal "YOU" tab so it can stand on its own as a
   desktop-oriented surface (publisher.html). The phone app keeps only a
   lightweight read-only summary (see PublisherCampaignSummary, used by the
   YOU tab); full publisher management lives here.

   Reusable shape:
   - usePublisherWorkspace(): the shared campaign/application state + actions.
     NOTE: this hook now lives in components/campaign-data.jsx (the single
     source of truth) and is read off window. It is backed by one shared
     store, so the desktop console and the phone summary read/write the SAME
     campaign data — no more two independent snapshots. campaign-data.jsx must
     load before this file.
   - CampaignWorkspaceRouter(): the screen router (hub + subpages). Layout-
     agnostic — it just renders one panel at a time inside whatever frame the
     caller provides.
   - PublisherConsole(): the desktop frame (sidebar + wide content area) that
     hosts CampaignWorkspaceRouter. Mounted by publisher.html.

   This module depends on:
   - shared chrome on window: StatusBar, Pill (components/chrome.jsx)
   - the shared data model: usePublisherWorkspace (components/campaign-data.jsx)
   - styles.css tokens.
*/

/* ---------- Screen router (layout-agnostic) ---------- */

function CampaignWorkspaceRouter({ workspace, view, setView, onExit, exitLabel = 'Back', onNotify }) {
  const {
    verificationStatus, setVerificationStatus, verified,
    companyBalance, setCompanyBalance,
    applications, campaigns, liveCampaigns, approvedApplications,
    submitApplication, updateApplicationStatus, activateApplication,
  } = workspace;

  const [requirementStep, setRequirementStep] = React.useState(0);
  const [selectedApplication, setSelectedApplication] = React.useState(null);
  const [selectedCampaign, setSelectedCampaign] = React.useState(null);
  const [campaignReturnView, setCampaignReturnView] = React.useState('campaigns');

  function failVerification() {
    setVerificationStatus('failed');
    onNotify && onNotify(
      'Publisher verification not approved',
      'The platform could not confirm the submitted qualification papers. You can revise the company application and apply again.',
      'Action'
    );
  }

  function handleSubmit() {
    const app = submitApplication();
    setSelectedApplication(app);
    setRequirementStep(0);
    setView('applications');
  }

  function handleStatus(app, status) {
    setSelectedApplication(updateApplicationStatus(app, status));
  }

  function handleActivate(app, method) {
    const campaign = activateApplication(app, method);
    setSelectedCampaign(campaign);
    setCampaignReturnView('campaigns');
    setView('campaign-detail');
  }

  if (view === 'verification') {
    return <CampaignVerificationPage status={verificationStatus} setStatus={setVerificationStatus} onFail={failVerification} onBack={() => setView('hub')}/>;
  }
  if (view === 'requirement') {
    return <CampaignRequirementFlow step={requirementStep} setStep={setRequirementStep} onBack={() => setView('hub')} onSubmit={handleSubmit}/>;
  }
  if (view === 'monitor') {
    return <CampaignMonitorPage verified={verified} campaigns={liveCampaigns} onBack={() => setView('hub')} onVerify={() => setView('verification')} onOpen={(campaign) => { setSelectedCampaign(campaign); setCampaignReturnView('monitor'); setView('campaign-detail'); }}/>;
  }
  if (view === 'campaign-detail') {
    return <CampaignDetailPage campaign={selectedCampaign || campaigns[0]} onBack={() => setView(campaignReturnView)}/>;
  }
  if (view === 'account') {
    return <CompanyAccountPage balance={companyBalance} setBalance={setCompanyBalance} onBack={() => setView('hub')}/>;
  }
  if (view === 'applications') {
    return <CampaignApplicationsPage verified={verified} applications={applications} balance={companyBalance} onBack={() => setView('hub')} onVerify={() => setView('verification')} onOpen={setSelectedApplication} onApprove={(app) => handleStatus(app, 'approved')} onReject={(app) => handleStatus(app, 'rejected')} onActivate={handleActivate} selectedApplication={selectedApplication}/>;
  }
  if (view === 'campaigns') {
    return <CampaignHistoryPage campaigns={campaigns} onBack={() => setView('hub')} onOpen={(campaign) => { setSelectedCampaign(campaign); setCampaignReturnView('campaigns'); setView('campaign-detail'); }}/>;
  }
  if (view === 'help' || view === 'terms' || view === 'contact') {
    return <CampaignSupportPage view={view} onBack={() => setView('hub')}/>;
  }

  return (
    <CampaignHub
      onBack={onExit}
      backLabel={exitLabel}
      verified={verified}
      verificationStatus={verificationStatus}
      liveCount={liveCampaigns.length}
      applicationCount={applications.length}
      approvedApplications={approvedApplications}
      campaignCount={campaigns.length}
      companyBalance={companyBalance}
      onOpen={(next) => {
        if (!verified && !['verification', 'help', 'terms', 'contact'].includes(next)) setView('verification');
        else if (next === 'requirement') { setRequirementStep(0); setView('requirement'); }
        else if (next === 'applications') { setSelectedApplication(null); setView('applications'); }
        else setView(next);
      }}
    />
  );
}

/* ---------- Desktop console frame ---------- */

function PublisherConsole() {
  const workspace = usePublisherWorkspace();
  const [view, setView] = React.useState('hub');
  const nav = [
    ['hub', 'Overview'],
    ['requirement', 'Submit data application'],
    ['applications', 'My applications'],
    ['campaigns', 'My campaigns'],
    ['monitor', 'Monitor'],
    ['account', 'Company account'],
    ['verification', 'Verification'],
    ['help', 'Support'],
  ];

  function go(next) {
    if (!workspace.verified && !['hub', 'verification', 'help', 'terms', 'contact'].includes(next)) setView('verification');
    else setView(next);
  }

  return (
    <div className="pub-console">
      <aside className="pub-sidebar">
        <div className="pub-brand">
          <div className="pub-brand-mark">GV</div>
          <div>
            <div className="pub-brand-name">GoVibe</div>
            <div className="pub-brand-sub">Publisher Console</div>
          </div>
        </div>
        <div className="pub-company">
          <div className="mono" style={{fontSize:9, color:'var(--warm)', marginBottom:5}}>COMPANY ACCOUNT</div>
          <div className="pub-company-balance">${workspace.companyBalance.toFixed(0)}</div>
          <Pill tone={workspace.verified ? 'teal' : undefined}>{workspace.verified ? 'verified publisher' : 'unverified'}</Pill>
        </div>
        <nav className="pub-nav">
          {nav.map(([id, label]) => {
            const isActive = id === view || (id === 'help' && (view === 'terms' || view === 'contact'));
            const locked = !workspace.verified && !['hub', 'verification', 'help'].includes(id);
            return (
              <button key={id} className="pub-nav-item" data-active={isActive} onClick={() => go(id)}>
                <span>{label}</span>
                {locked && <span className="pub-nav-lock">locked</span>}
                {id === 'monitor' && workspace.liveCampaigns.length > 0 && <span className="pub-nav-live">LIVE</span>}
              </button>
            );
          })}
        </nav>
        <a className="pub-back" href="index.html">&larr; All prototype surfaces</a>
      </aside>

      <main className="pub-main">
        <header className="pub-topbar">
          <div>
            <div className="mono" style={{fontSize:9, color:'var(--teal-ink)', marginBottom:4}}>FOR BUSINESS · PAID DATA PROCUREMENT</div>
            <div className="pub-topbar-title">Publisher Console</div>
          </div>
          <div className="pub-topbar-meta">
            <Pill>{workspace.liveCampaigns.length} live</Pill>
            <Pill>{workspace.approvedApplications}/{workspace.applications.length} approved</Pill>
          </div>
        </header>
        <div className="pub-canvas">
          <div className="pub-canvas-inner">
            <CampaignWorkspaceRouter
              workspace={workspace}
              view={view}
              setView={setView}
              onExit={() => setView('hub')}
              exitLabel="Overview"
            />
          </div>
        </div>
      </main>
    </div>
  );
}

/* ---------- Hub + subpages (shared) ---------- */

function CampaignHub({ onBack, backLabel = 'Back', verified, verificationStatus, liveCount, applicationCount, approvedApplications, campaignCount, companyBalance, onOpen }) {
  return (
    <div style={{padding:'4px 20px 28px'}}>
      <PubPageTop title="Data procurement" sub="Company workspace for paid data requests. Commission regional data collection and receive structured results (CSV / GeoJSON / API)." onBack={onBack} backLabel={backLabel}/>
      {!verified && <PublisherIntro onVerify={() => onOpen('verification')}/>}
      <div className="pub-action-grid">
        <CampaignHubAction kind="verification" label="Verification" status={verificationStatus} onClick={() => onOpen('verification')}/>
        <CampaignHubAction kind="application" label="Submit Data Application" disabled={!verified} status="new" onClick={() => onOpen('requirement')}/>
        <CampaignHubAction kind="monitor" label="Monitor" disabled={!verified} liveCount={liveCount} onClick={() => onOpen('monitor')}/>
        <CampaignHubAction kind="account" label="My Account" disabled={!verified} status={`$${companyBalance.toFixed(0)}`} onClick={() => onOpen('account')}/>
        <CampaignHubAction kind="applications" label="My Applications" disabled={!verified} status={`${approvedApplications}/${applicationCount} approved`} onClick={() => onOpen('applications')}/>
        <CampaignHubAction kind="campaigns" label="My Campaigns" disabled={!verified} status={`${campaignCount} total`} onClick={() => onOpen('campaigns')}/>
      </div>
      <CompanyAccountCard balance={companyBalance} verified={verified} onOpen={() => onOpen('account')}/>
      <div style={{display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:8, marginTop:12}}>
        <button className="btn-secondary" style={{height:38}} onClick={() => onOpen('help')}>Help</button>
        <button className="btn-secondary" style={{height:38}} onClick={() => onOpen('terms')}>Terms</button>
        <button className="btn-primary" style={{height:38}} onClick={() => onOpen('contact')}>Contact</button>
      </div>
      <div style={{border:'1px solid var(--line)', borderRadius:15, background:'var(--bg-elev)', padding:14, marginTop:12}}>
        <div className="mono" style={{fontSize:9, color:'var(--teal-ink)', marginBottom:6}}>WHAT YOU BUY</div>
        <div style={{fontSize:14, fontWeight:800}}>You pay for the data result — not for people.</div>
        <div style={{fontSize:12.5, color:'var(--ink-3)', lineHeight:1.45, marginTop:5}}>Campaigns deliver <strong>structured data</strong> (CSV / GeoJSON / API). You are buying verified facts about places, not contributor identities, names, or accounts. Contributors keep their own attribution and credits — those never transfer to you.</div>
      </div>
    </div>
  );
}

/* PublisherIntro — first-run / empty-state onboarding for the Publisher Console.
   Explains the product, what the buyer actually receives (structured data, not
   people), and the three-step lifecycle. Shown on the Overview hub while the
   account is still unverified (the empty state), and echoed in the locked
   subpage card. */
function PublisherIntro({ onVerify }) {
  const steps = [
    ['1', 'Define an area', 'Draw a region and pick a data template (status, facade, access, hours).'],
    ['2', 'Platform review + crowd collection', 'We approve the request, then verified contributors collect and AI-validate it on the ground.'],
    ['3', 'Export the data result', 'Receive structured output — CSV / GeoJSON / API — ready to use.'],
  ];
  return (
    <div style={{border:'1px solid var(--line)', borderRadius:16, background:'var(--bg-elev)', padding:16, marginBottom:14}}>
      <div className="mono" style={{fontSize:9, color:'var(--teal-ink)', marginBottom:6}}>GET STARTED</div>
      <div style={{fontSize:19, fontWeight:900, letterSpacing:'-0.02em', lineHeight:1.15}}>Commission real-world data, on demand.</div>
      <div style={{fontSize:12.5, color:'var(--ink-3)', lineHeight:1.45, marginTop:6}}>
        GoVibe turns a region you care about into a paid collection campaign. You define what to verify; a verified crowd collects it; you get back <strong>structured data results (CSV / GeoJSON / API)</strong>.
      </div>

      <div style={{display:'grid', gap:8, marginTop:12}}>
        {steps.map(s => (
          <div key={s[0]} style={{display:'grid', gridTemplateColumns:'28px 1fr', gap:10, alignItems:'start'}}>
            <span style={{width:28, height:28, borderRadius:9, background:'var(--warm-soft)', color:'var(--warm)', display:'grid', placeItems:'center', fontFamily:'var(--font-mono)', fontSize:13, fontWeight:900}}>{s[0]}</span>
            <div>
              <div style={{fontSize:13, fontWeight:800, lineHeight:1.2}}>{s[1]}</div>
              <div style={{fontSize:12, color:'var(--ink-3)', lineHeight:1.4, marginTop:2}}>{s[2]}</div>
            </div>
          </div>
        ))}
      </div>

      <div style={{borderTop:'1px solid var(--line)', marginTop:13, paddingTop:12}}>
        <div className="mono" style={{fontSize:9, color:'var(--teal-ink)', marginBottom:5}}>DATA, NOT PEOPLE</div>
        <div style={{fontSize:12.5, color:'var(--ink-3)', lineHeight:1.45}}>
          You purchase the <strong>data result</strong> — never contributor identities, names, or credits. Contributors keep their own attribution and earn credits for their work; that stays with them.
        </div>
      </div>

      {onVerify && <button className="btn-primary" style={{height:42, width:'100%', marginTop:14}} onClick={onVerify}>Verify your company to start</button>}
    </div>
  );
}

function CampaignHubAction({ kind, label, status, disabled, liveCount, onClick }) {
  return (
    <button onClick={onClick} style={{border:'1px solid var(--line)', background:'var(--bg-elev)', borderRadius:14, minHeight:108, padding:9, display:'grid', justifyItems:'center', alignContent:'center', gap:7, cursor:'pointer', fontFamily:'var(--font-sans)', opacity:disabled ? 0.62 : 1, position:'relative'}}>
      {liveCount > 0 && <span style={{position:'absolute', top:7, right:7, borderRadius:999, background:'var(--status-fresh)', color:'#fff', fontSize:9, fontWeight:900, padding:'3px 6px'}}>LIVE</span>}
      {status === 'verified' && <span style={{position:'absolute', top:7, right:7}}><MetalBadge small/></span>}
      <span style={{width:38, height:38, display:'grid', placeItems:'center', color:disabled ? 'var(--ink-3)' : 'var(--ink)'}}><CampaignIcon kind={kind}/></span>
      <span style={{fontSize:11.5, fontWeight:800, lineHeight:1.1, textAlign:'center'}}>{label}</span>
      {disabled && <span style={{fontSize:9.5, color:'var(--ink-3)'}}>verify first</span>}
      {status && status !== 'verified' && status !== 'new' && <span style={{fontSize:9.5, color:'var(--warm)', lineHeight:1.1}}>{status}</span>}
    </button>
  );
}

function CampaignIcon({ kind }) {
  const p = {stroke:'currentColor', strokeWidth:1.6, strokeLinecap:'round', strokeLinejoin:'round', fill:'none'};
  if (kind === 'verification') return <svg width="34" height="34" viewBox="0 0 34 34"><path {...p} d="M17 4.5l10 4v7.5c0 6.1-4.2 10.6-10 13.5C11.2 26.6 7 22.1 7 16V8.5l10-4Z"/><path {...p} d="M12 17l3.5 3.5L23 13"/></svg>;
  if (kind === 'application') return <svg width="34" height="34" viewBox="0 0 34 34"><path {...p} d="M8 26V8h18v18H8Z"/><path {...p} d="M12 13h10M12 18h10M12 23h6"/><path {...p} d="M24 6l4 4"/></svg>;
  if (kind === 'monitor') return <svg width="34" height="34" viewBox="0 0 34 34"><path {...p} d="M6 24h22M9 24V13M17 24V8M25 24v-7"/><path {...p} d="M9 13l8-5 8 9"/></svg>;
  if (kind === 'account') return <svg width="34" height="34" viewBox="0 0 34 34"><rect {...p} x="7" y="10" width="20" height="15" rx="3"/><path {...p} d="M10 10V8h14v2M21 18h4"/></svg>;
  if (kind === 'applications') return <svg width="34" height="34" viewBox="0 0 34 34"><path {...p} d="M10 6h11l4 4v18H10z"/><path {...p} d="M20 6v5h5M13 16h8M13 21h8"/></svg>;
  return <svg width="34" height="34" viewBox="0 0 34 34"><path {...p} d="M7 12h20v14H7z"/><path {...p} d="M11 12V8h12v4M12 18h10M12 22h7"/></svg>;
}

function MetalBadge({ small }) {
  return (
    <span style={{display:'inline-grid', placeItems:'center', width:small ? 24 : 44, height:small ? 24 : 44, borderRadius:'50%', background:'linear-gradient(135deg,#f8fafc,#a8b0ba 42%,#f5d78a 72%,#8f6b24)', color:'#26313c', border:'1px solid rgba(60,55,40,.24)', boxShadow:'inset 0 1px 2px rgba(255,255,255,.75), 0 4px 10px rgba(30,35,40,.16)', fontSize:small ? 13 : 22, fontWeight:900}}>✓</span>
  );
}

function CompanyAccountCard({ balance, verified, onOpen }) {
  return (
    <div style={{border:'1px solid var(--line)', borderRadius:16, background:'var(--bg-elev)', padding:15}}>
      <div style={{display:'flex', justifyContent:'space-between', gap:10, alignItems:'flex-start'}}>
        <div>
          <div className="mono" style={{fontSize:9, color:'var(--warm)', marginBottom:6}}>COMPANY ACCOUNT</div>
          <div style={{fontSize:28, fontWeight:900, letterSpacing:'-0.035em'}}>${balance.toFixed(0)}</div>
          <div style={{fontSize:12, color:'var(--ink-3)', marginTop:3}}>5% volume discount unlocked · $18 rebate pending</div>
        </div>
        <Pill tone={verified ? 'teal' : undefined}>{verified ? 'verified' : 'locked'}</Pill>
      </div>
      {onOpen && <button className={verified ? 'btn-primary' : 'btn-secondary'} style={{height:40, marginTop:12, width:'100%'}} onClick={onOpen}>{verified ? 'Manage balance' : 'Verify to activate'}</button>}
    </div>
  );
}

function CampaignVerificationPage({ status, setStatus, onFail, onBack }) {
  const isReview = status === 'review';
  const isVerified = status === 'verified';
  return (
    <div style={{padding:'4px 20px 28px'}}>
      <PubPageTop title="Verification" sub="Confirm company identity before using paid campaign tools." onBack={onBack}/>
      {isVerified ? (
        <div style={{border:'1px solid var(--line)', borderRadius:16, background:'var(--bg-elev)', padding:18, textAlign:'center'}}>
          <MetalBadge/>
          <div style={{fontSize:21, fontWeight:900, marginTop:10}}>Verified publisher</div>
          <div style={{fontSize:12.5, color:'var(--ink-3)', lineHeight:1.45, marginTop:5}}>Company identity, contact domain, and qualification papers have passed platform review.</div>
        </div>
      ) : isReview ? (
        <>
          <div style={{border:'1px solid var(--line)', borderRadius:16, background:'var(--bg-elev)', padding:16, marginBottom:12}}>
            <div className="mono" style={{fontSize:9, color:'var(--warm)', marginBottom:6}}>UNDER REVIEW</div>
            <div style={{fontSize:20, fontWeight:900}}>Platform investigation in progress</div>
            <div style={{fontSize:12.5, color:'var(--ink-3)', lineHeight:1.45, marginTop:5}}>The team checks company registration, buyer identity, email domain, and uploaded qualification papers. Typical result: 1-2 business days.</div>
          </div>
          <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:8}}>
            <button className="btn-secondary" style={{height:40}} onClick={onFail}>Simulate fail</button>
            <button className="btn-primary" style={{height:40}} onClick={() => setStatus('verified')}>Simulate pass</button>
          </div>
        </>
      ) : (
        <>
          {status === 'failed' && <div style={{border:'1px solid rgba(185,92,68,.35)', borderRadius:13, background:'rgba(185,92,68,.08)', padding:12, marginBottom:12}}><div style={{fontSize:13, fontWeight:800}}>Application not approved</div><div style={{fontSize:12, color:'var(--ink-3)', marginTop:3}}>A notification was sent. Revise the documents and apply again.</div></div>}
          <div style={{display:'grid', gap:9}}>
            {[
              ['Company legal name', 'Northbridge Field Analytics Inc.'],
              ['Industry', 'Retail intelligence'],
              ['Use case', 'POI status and site condition collection'],
              ['Work email', 'ops@northbridge.example'],
            ].map(row => <label key={row[0]} style={{display:'grid', gap:5, fontSize:11, color:'var(--ink-3)', fontWeight:700}}>{row[0]}<input value={row[1]} readOnly style={{height:40, borderRadius:10, border:'1px solid var(--line)', background:'var(--bg-elev)', padding:'0 11px', color:'var(--ink)', fontFamily:'var(--font-sans)', fontWeight:700}}/></label>)}
          </div>
          <div style={{border:'1px dashed var(--line-2)', borderRadius:14, background:'var(--bg-elev)', padding:14, marginTop:12}}>
            <div style={{fontSize:14, fontWeight:800}}>Qualification papers</div>
            <div style={{fontSize:12.5, color:'var(--ink-3)', lineHeight:1.45, marginTop:4}}>Business registration.pdf · Buyer authorization.pdf · Data-use policy.pdf</div>
          </div>
          <button className="btn-primary" style={{height:42, width:'100%', marginTop:14}} onClick={() => setStatus('review')}>Submit for review</button>
        </>
      )}
    </div>
  );
}

function LockedCampaignCard({ onVerify }) {
  return (
    <div style={{border:'1px solid var(--line)', borderRadius:16, background:'var(--bg-elev)', padding:16}}>
      <div style={{fontSize:19, fontWeight:900}}>Publisher verification required</div>
      <div style={{fontSize:12.5, color:'var(--ink-3)', lineHeight:1.45, marginTop:5}}>Only verified company accounts can submit applications, fund approved requests, and monitor campaigns.</div>
      <div style={{fontSize:12, color:'var(--ink-3)', lineHeight:1.45, marginTop:8, paddingTop:10, borderTop:'1px solid var(--line)'}}>
        Once verified you commission a region and receive a <strong>structured data result (CSV / GeoJSON / API)</strong>. You pay for the data, not for the contributors — they keep their own attribution and credits.
      </div>
      <button className="btn-primary" style={{height:40, width:'100%', marginTop:12}} onClick={onVerify}>Start verification</button>
    </div>
  );
}

function CampaignRequirementFlow({ step, setStep, onBack, onSubmit }) {
  const steps = [
    ['Template', 'Site Condition Survey', [['Template', 'Facade, access, surroundings'], ['Time', '~4 min/point'], ['Base', '$3/pt']]],
    ['Area', 'Daikanyama 0.47 km2', [['Points', '52-68'], ['Contributors', '34 nearby'], ['Coverage', '70% min']]],
    ['Configure', 'Priority, standard verification', [['Timeline', '7 days'], ['Depth', 'Photo + status'], ['Reward', '3x GP']]],
    ['Quote', 'Estimated total $295', [['Base fee', '$37.60'], ['Delivery', '$180'], ['QA + priority', '$77.40']]],
    ['Submit', 'Ready for platform review', [['Status', 'Application'], ['Payment', 'After approval'], ['Next', 'My Applications']]],
  ];
  const current = steps[step];
  return (
    <div style={{padding:'4px 20px 28px'}}>
      <PubPageTop title="Data Requirement" sub="Collect campaign requirements and calculate cost." onBack={onBack}/>
      <div style={{display:'flex', gap:4, marginBottom:14}}>{steps.map((_, i) => <div key={i} style={{flex:1, height:4, borderRadius:999, background:i <= step ? 'var(--warm)' : 'var(--bg-sunk)'}}/>)}</div>
      <div style={{border:'1px solid var(--line)', borderRadius:15, background:'var(--bg-elev)', padding:15, marginBottom:12}}>
        <div className="mono" style={{fontSize:9, color:'var(--warm)', marginBottom:6}}>{current[0]}</div>
        <div style={{fontSize:20, fontWeight:900, letterSpacing:'-0.025em', lineHeight:1.12}}>{current[1]}</div>
      </div>
      <MetricGrid rows={current[2]}/>
      <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:8, marginTop:14}}>
        <button className="btn-secondary" onClick={() => step === 0 ? onBack() : setStep(s => Math.max(0, s - 1))}>Back</button>
        <button className="btn-primary" onClick={() => step === steps.length - 1 ? onSubmit() : setStep(s => Math.min(steps.length - 1, s + 1))}>{step === steps.length - 1 ? 'Submit' : 'Next'}</button>
      </div>
    </div>
  );
}

function CampaignApplicationsPage({ verified, applications, balance, onBack, onVerify, onOpen, onApprove, onReject, onActivate, selectedApplication }) {
  const selected = selectedApplication;
  return (
    <div style={{padding:'4px 20px 28px'}}>
      <PubPageTop title="My Applications" sub="Track platform approval and pay to activate approved campaigns." onBack={onBack}/>
      {!verified ? <LockedCampaignCard onVerify={onVerify}/> : selected ? (
        <>
          <ApplicationCard app={selected} onClick={() => {}}/>
          <MetricGrid rows={[['Quote', `$${selected.quote}`], ['Balance', `$${balance.toFixed(0)}`], ['Status', applicationStatusLabel(selected.status)]]}/>
          <div style={{display:'grid', gap:8, marginTop:12}}>
            {selected.status === 'review' && (
              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:8}}>
                <button className="btn-secondary" style={{height:40}} onClick={() => onReject(selected)}>Simulate reject</button>
                <button className="btn-primary" style={{height:40}} onClick={() => onApprove(selected)}>Simulate approve</button>
              </div>
            )}
            {selected.status === 'approved' && (
              <>
                <button className="btn-primary" style={{height:42}} onClick={() => onActivate(selected, 'balance')}>Pay from balance</button>
                <button className="btn-secondary" style={{height:42}} onClick={() => onActivate(selected, 'instant')}>Instant payment</button>
              </>
            )}
            {selected.status === 'rejected' && <div style={{border:'1px solid rgba(185,92,68,.35)', borderRadius:13, background:'rgba(185,92,68,.08)', padding:12, fontSize:12.5, color:'var(--ink-3)', lineHeight:1.45}}>Rejected applications can be revised by submitting a new data application with a narrower or safer scope.</div>}
            {selected.status === 'paid' && <div style={{border:'1px solid var(--line)', borderRadius:13, background:'var(--bg-elev)', padding:12, fontSize:12.5, color:'var(--ink-3)', lineHeight:1.45}}>Payment complete. The campaign is now active and available in My Campaigns.</div>}
            <button className="btn-secondary" style={{height:40}} onClick={() => onOpen(null)}>Back to applications</button>
          </div>
        </>
      ) : (
        <div style={{display:'grid', gap:9}}>
          {applications.map(app => <ApplicationCard key={app.id} app={app} onClick={() => onOpen(app)}/>)}
        </div>
      )}
    </div>
  );
}

function ApplicationCard({ app, onClick }) {
  const tone = app.status === 'approved' || app.status === 'paid' ? 'teal' : undefined;
  return (
    <button onClick={onClick} style={{border:'1px solid var(--line)', borderRadius:15, background:'var(--bg-elev)', padding:13, textAlign:'left', cursor:'pointer', fontFamily:'var(--font-sans)', width:'100%'}}>
      <div style={{display:'flex', justifyContent:'space-between', gap:8, alignItems:'center'}}><div style={{fontSize:15, fontWeight:900}}>{app.title}</div><Pill tone={tone}>{applicationStatusLabel(app.status)}</Pill></div>
      <div style={{fontSize:12, color:'var(--ink-3)', marginTop:4}}>{app.id} · {app.area} · submitted {app.submitted}</div>
      <div style={{fontSize:12.5, color:'var(--ink-3)', lineHeight:1.4, marginTop:7}}>{app.summary}</div>
    </button>
  );
}

function applicationStatusLabel(status) {
  if (status === 'review') return 'Review';
  if (status === 'approved') return 'Approved';
  if (status === 'paid') return 'Paid';
  return 'Rejected';
}

function CampaignMonitorPage({ verified, campaigns, onBack, onVerify, onOpen }) {
  return (
    <div style={{padding:'4px 20px 28px'}}>
      <PubPageTop title="Monitor" sub="Active campaign cards only." onBack={onBack}/>
      {!verified ? <LockedCampaignCard onVerify={onVerify}/> : (
        <CampaignCardList campaigns={campaigns} empty="No active campaigns yet. Approved applications become active after payment." onOpen={onOpen}/>
      )}
    </div>
  );
}

function CampaignDetailPage({ campaign, onBack }) {
  return (
    <div style={{padding:'4px 20px 28px'}}>
      <PubPageTop title={campaign.title} sub={`${campaign.id} · ${campaign.area}`} onBack={onBack}/>
      <MetricGrid rows={[['Coverage', campaign.coverage], ['Spend', campaign.spend], ['Verified', campaign.verified], ['Reward', campaign.reward], ['Remaining', campaign.remaining], ['Status', campaign.status]]}/>
      <div style={{border:'1px solid var(--line)', borderRadius:15, background:'var(--bg-elev)', padding:14, marginTop:12}}>
        <div style={{fontSize:14, fontWeight:900}}>Delivery map status</div>
        <div style={{height:118, borderRadius:12, background:'linear-gradient(135deg, rgba(37,160,137,.15), rgba(220,155,71,.18)), var(--bg-sunk)', border:'1px solid var(--line)', marginTop:10, position:'relative', overflow:'hidden'}}>
          {[18,34,52,71].map((x,i) => <span key={i} style={{position:'absolute', left:x+'%', top:(24+i*13)+'%', width:18, height:18, borderRadius:'50%', background:i < 3 ? 'var(--status-fresh)' : 'var(--warm)', border:'2px solid var(--bg)'}}/>)}
        </div>
      </div>
    </div>
  );
}

function CompanyAccountPage({ balance, setBalance, onBack }) {
  return (
    <div style={{padding:'4px 20px 28px'}}>
      <PubPageTop title="My Account" sub="Company balance, deposits, withdrawals, rebates, and invoices." onBack={onBack}/>
      <CompanyAccountCard balance={balance} verified/>
      <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:8, marginTop:12}}>
        <button className="btn-primary" style={{height:40}} onClick={() => setBalance(v => v + 500)}>Deposit $500</button>
        <button className="btn-secondary" style={{height:40}} onClick={() => setBalance(v => Math.max(0, v - 100))}>Withdraw $100</button>
      </div>
      <div style={{display:'grid', gap:8, marginTop:12}}>
        {[
          ['Deposit', '+$500', 'Company account top-up'],
          ['Campaign payment', '-$295', 'Daikanyama site condition'],
          ['Rebate', '+$18', 'Unused coverage guarantee'],
        ].map(row => <div key={row[0]} style={{display:'grid', gridTemplateColumns:'1fr auto', gap:10, border:'1px solid var(--line)', borderRadius:12, background:'var(--bg-elev)', padding:11}}><div><div style={{fontSize:13, fontWeight:800}}>{row[0]}</div><div style={{fontSize:11.5, color:'var(--ink-3)', marginTop:3}}>{row[2]}</div></div><div style={{fontFamily:'var(--font-mono)', fontSize:13, fontWeight:900}}>{row[1]}</div></div>)}
      </div>
    </div>
  );
}

function CampaignHistoryPage({ campaigns, onBack, onOpen }) {
  const active = campaigns.filter(c => c.status === 'Live');
  const history = campaigns.filter(c => c.status !== 'Live');
  return (
    <div style={{padding:'4px 20px 28px'}}>
      <PubPageTop title="My Campaigns" sub="Check active and historical campaigns, then download completed data." onBack={onBack}/>
      <div className="sec-head"><h3>Active</h3><span className="label">{active.length}</span></div>
      <CampaignCardList campaigns={active} empty="No active campaigns." onOpen={onOpen}/>
      <div className="sec-head" style={{marginTop:16}}><h3>History</h3><span className="label">{history.length}</span></div>
      <div style={{display:'grid', gap:9}}>
        {history.map(c => (
          <div key={c.id} style={{border:'1px solid var(--line)', borderRadius:15, background:'var(--bg-elev)', padding:13}}>
            <div style={{display:'flex', justifyContent:'space-between', gap:8, alignItems:'center'}}><div style={{fontSize:15, fontWeight:900}}>{c.title}</div><Pill>{c.status}</Pill></div>
            <div style={{fontSize:12, color:'var(--ink-3)', marginTop:4}}>{c.id} · {c.area} · {c.coverage} coverage</div>
            <button className="btn-primary" style={{height:38, width:'100%', marginTop:10}}>Download data</button>
          </div>
        ))}
      </div>
    </div>
  );
}

function CampaignCardList({ campaigns, empty, onOpen }) {
  if (!campaigns.length) {
    return <div style={{border:'1px solid var(--line)', borderRadius:14, background:'var(--bg-elev)', padding:14, fontSize:12.5, color:'var(--ink-3)', lineHeight:1.45}}>{empty}</div>;
  }
  return (
    <div style={{display:'grid', gap:9}}>
      {campaigns.map(c => (
        <button key={c.id} onClick={() => onOpen(c)} style={{border:'1px solid var(--line)', borderRadius:15, background:'var(--bg-elev)', padding:13, textAlign:'left', cursor:'pointer', fontFamily:'var(--font-sans)', width:'100%'}}>
          <div style={{display:'flex', justifyContent:'space-between', gap:8, alignItems:'center'}}><div style={{fontSize:15, fontWeight:900}}>{c.title}</div><Pill tone={c.status === 'Live' ? 'teal' : undefined}>{c.status}</Pill></div>
          <div style={{fontSize:12, color:'var(--ink-3)', marginTop:4}}>{c.id} · {c.area} · {c.remaining}</div>
          <MetricGrid rows={[['Coverage', c.coverage], ['Spend', c.spend], ['Verified', c.verified]]} compact/>
        </button>
      ))}
    </div>
  );
}

function CampaignSupportPage({ view, onBack }) {
  const title = view === 'help' ? 'Campaign Help' : view === 'terms' ? 'Campaign Terms' : 'Contact Support';
  const rows = view === 'help'
    ? [['Verification', 'Required before submitting applications because campaigns create paid contributor missions.'], ['Payment', 'Use company balance for prepaid control or instant card payment after platform approval.'], ['Monitoring', 'Track coverage, spend, verified points, and remaining time.']]
    : view === 'terms'
      ? [['Coverage', 'Minimum coverage guarantee applies to eligible paid campaigns.'], ['Rebate', 'Undelivered guaranteed coverage can return as company account credit.'], ['Data use', 'Published requirements must follow platform safety and privacy rules.']]
      : [['Customer service', 'A campaign specialist will review the campaign, account, and payment context.'], ['Response time', 'Most publisher questions receive a response within one business day.']];
  return (
    <div style={{padding:'4px 20px 28px'}}>
      <PubPageTop title={title} sub="Publisher support for company campaigns." onBack={onBack}/>
      <div style={{display:'grid', gap:9}}>
        {rows.map(row => <div key={row[0]} style={{border:'1px solid var(--line)', borderRadius:13, background:'var(--bg-elev)', padding:13}}><div style={{fontSize:14, fontWeight:900}}>{row[0]}</div><div style={{fontSize:12.5, color:'var(--ink-3)', lineHeight:1.45, marginTop:4}}>{row[1]}</div></div>)}
      </div>
      {view === 'contact' && <button className="btn-primary" style={{height:42, width:'100%', marginTop:12}}>Start support chat</button>}
    </div>
  );
}

function MetricGrid({ rows, compact }) {
  return (
    <div style={{display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap:8, marginTop:compact ? 10 : 0}}>
      {rows.map(row => <div key={row[0]} style={{background:'var(--bg-elev)', border:'1px solid var(--line)', borderRadius:12, padding:compact ? 8 : 10}}><div style={{fontFamily:'var(--font-mono)', fontSize:compact ? 12 : 13, fontWeight:900}}>{row[1]}</div><div style={{fontSize:10.5, color:'var(--ink-3)', marginTop:5}}>{row[0]}</div></div>)}
    </div>
  );
}

/* PubPageTop: shared back-header. Self-contained so this module does not depend on
   profile-screen.jsx load order. backLabel lets the console say "Overview". */
function PubPageTop({ title, sub, onBack, backLabel }) {
  return (
    <div style={{display:'flex', gap:12, alignItems:'flex-start', marginBottom:16}}>
      {onBack && <button onClick={onBack} aria-label={backLabel || 'Back'} style={{width:34, height:34, borderRadius:10, border:'1px solid var(--line)', background:'var(--bg-elev)', cursor:'pointer'}}>‹</button>}
      <div style={{flex:1}}>
        <div style={{fontSize:24, fontWeight:800, letterSpacing:'-0.025em', lineHeight:1.1}}>{title}</div>
        {sub && <div style={{fontSize:12.5, color:'var(--ink-3)', lineHeight:1.4, marginTop:4}}>{sub}</div>}
      </div>
    </div>
  );
}

/* ---------- Lightweight read-only summary for the phone YOU tab ---------- */

function PublisherCampaignSummary({ onBack }) {
  const workspace = usePublisherWorkspace();
  const live = workspace.liveCampaigns.length;
  const pending = workspace.applications.filter(a => a.status === 'review' || a.status === 'approved').length;
  const total = workspace.campaigns.length;

  return (
    <div style={{padding:'4px 20px 28px'}}>
      <PubPageTop title="My Campaigns" sub="Status of data requests you've published as a business." onBack={onBack}/>

      <div style={{display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:8, marginBottom:14}}>
        {[
          ['Live', String(live)],
          ['Pending', String(pending)],
          ['Total', String(total)],
        ].map(row => (
          <div key={row[0]} style={{background:'var(--bg-elev)', border:'1px solid var(--line)', borderRadius:12, padding:12}}>
            <div style={{fontFamily:'var(--font-mono)', fontSize:18, fontWeight:900}}>{row[1]}</div>
            <div style={{fontSize:11, color:'var(--ink-3)', marginTop:5}}>{row[0]}</div>
          </div>
        ))}
      </div>

      <div style={{display:'grid', gap:9, marginBottom:16}}>
        {workspace.campaigns.map(c => (
          <div key={c.id} style={{border:'1px solid var(--line)', borderRadius:15, background:'var(--bg-elev)', padding:13}}>
            <div style={{display:'flex', justifyContent:'space-between', gap:8, alignItems:'center'}}>
              <div style={{fontSize:15, fontWeight:900}}>{c.title}</div>
              <Pill tone={c.status === 'Live' ? 'teal' : undefined}>{c.status}</Pill>
            </div>
            <div style={{fontSize:12, color:'var(--ink-3)', marginTop:4}}>{c.id} · {c.area} · {c.coverage} coverage</div>
          </div>
        ))}
      </div>

      <div style={{border:'1px solid var(--line)', borderRadius:15, background:'var(--bg-elev)', padding:14}}>
        <div className="mono" style={{fontSize:9, color:'var(--teal-ink)', marginBottom:6}}>READ-ONLY ON MOBILE</div>
        <div style={{fontSize:14, fontWeight:800}}>Manage data procurement in the Publisher Console.</div>
        <div style={{fontSize:12.5, color:'var(--ink-3)', lineHeight:1.45, marginTop:5}}>Verification, new data applications, payment, and campaign monitoring run in the desktop Publisher Console.</div>
        <a href="publisher.html" target="_blank" rel="noopener" className="btn-primary" style={{height:42, marginTop:12, textDecoration:'none'}}>Open Publisher Console (desktop)</a>
      </div>
    </div>
  );
}

Object.assign(window, {
  // usePublisherWorkspace lives in components/campaign-data.jsx (shared store).
  CampaignWorkspaceRouter,
  PublisherConsole,
  PublisherCampaignSummary,
  // Shared subpage components (also useful for design-canvas previews):
  CampaignHub, PublisherIntro, CampaignHubAction, CampaignIcon, MetalBadge, CompanyAccountCard,
  CampaignVerificationPage, LockedCampaignCard, CampaignRequirementFlow,
  CampaignApplicationsPage, ApplicationCard, applicationStatusLabel,
  CampaignMonitorPage, CampaignDetailPage, CompanyAccountPage,
  CampaignHistoryPage, CampaignCardList, CampaignSupportPage, MetricGrid,
});
