/* WP Site Beam — Tweaks panel + App root */

function Tweaks({ s, api, onClose }) {
  const accents = ['orange', 'beam', 'rose', 'purple', 'green'];
  // Accent → best-matching brand icon variant
  const ACCENT_TO_LOGO = {
    orange: 'black-amber',
    beam:   'teal',
    rose:   'red',
    purple: 'purple',
    green:  'green',
  };
  function setAccent(a) {
    api.set('accent', a);
    api.set('logoVariant', ACCENT_TO_LOGO[a] || 'black-amber');
  }
  return (
    <div className="tweaks" role="dialog" aria-label="Tweaks">
      <div className="tweaks-head">
        <span className="tweaks-title">Tweaks</span>
        <button className="icon-btn" aria-label="Close tweaks" onClick={onClose} style={{ width:26, height:26 }}>
          <Icon name="x" size={14}/>
        </button>
      </div>
      <div className="tweaks-body">
        <div>
          <div className="tw-label">Theme</div>
          <div className="tw-seg">
            {['dark','light'].map(v => (
              <button key={v} className={s.theme === v ? 'active' : ''} onClick={() => api.set('theme', v)}>{v}</button>
            ))}
          </div>
        </div>

        <div>
          <div className="tw-label">Nav style</div>
          <div className="tw-seg">
            {['sidebar','topbar'].map(v => (
              <button key={v} className={s.nav === v ? 'active' : ''} onClick={() => api.set('nav', v)}>{v}</button>
            ))}
          </div>
        </div>

        <div>
          <div className="tw-label">Density</div>
          <div className="tw-seg">
            {['compact','cozy','roomy'].map(v => (
              <button key={v} className={s.density === v ? 'active' : ''} onClick={() => api.set('density', v)}>{v}</button>
            ))}
          </div>
        </div>

        <div>
          <div className="tw-label">Icons</div>
          <div className="tw-seg">
            {['line','emoji'].map(v => (
              <button key={v} className={s.icons === v ? 'active' : ''} onClick={() => api.set('icons', v)}>{v}</button>
            ))}
          </div>
        </div>

        <div>
          <div className="tw-label">Accent hue</div>
          <div className="tw-swatches">
            {accents.map(a => (
              <button key={a} className={`tw-swatch ${s.accent === a ? 'active' : ''}`}
                style={{ background: window.WPSBD.ACCENTS[a].h }}
                aria-label={a}
                onClick={() => setAccent(a)}
              />
            ))}
          </div>
        </div>

        {/* ── Accessibility (customer-facing a11y toggles) ───────── */}
        <div style={{ paddingTop:10, borderTop:'1px solid var(--border)' }}>
          <div className="tw-label" style={{ display:'flex', alignItems:'center', gap:6 }}>
            <Icon name="shield" size={11}/>Accessibility
          </div>
          <div style={{ fontSize:'.66rem', color:'var(--dim)', marginTop:-2, marginBottom:8, lineHeight:1.4 }}>
            Applies to the whole SaaS. Persists across sessions.
          </div>
        </div>

        <div>
          <div className="tw-label">Text size</div>
          <div className="tw-seg">
            {[
              { v:'normal', lbl:'Normal' },
              { v:'large',  lbl:'Large' },
              { v:'xlarge', lbl:'X-Large' },
            ].map(o => (
              <button key={o.v} className={(s.textSize || 'normal') === o.v ? 'active' : ''}
                onClick={() => api.set('textSize', o.v)}>{o.lbl}</button>
            ))}
          </div>
        </div>

        <div>
          <div className="tw-label">Contrast</div>
          <div className="tw-seg">
            {[
              { v:'normal', lbl:'Normal' },
              { v:'high',   lbl:'High' },
            ].map(o => (
              <button key={o.v} className={(s.contrast || 'normal') === o.v ? 'active' : ''}
                onClick={() => api.set('contrast', o.v)}>{o.lbl}</button>
            ))}
          </div>
          <div style={{ fontSize:'.66rem', color:'var(--dim)', marginTop:4 }}>
            Boosts body text + borders for WCAG AAA contrast.
          </div>
        </div>

        <div>
          <div className="tw-label">Motion</div>
          <div className="tw-seg">
            {[
              { v:'normal',  lbl:'Normal' },
              { v:'reduced', lbl:'Reduced' },
            ].map(o => (
              <button key={o.v} className={(s.motion || 'normal') === o.v ? 'active' : ''}
                onClick={() => api.set('motion', o.v)}>{o.lbl}</button>
            ))}
          </div>
          <div style={{ fontSize:'.66rem', color:'var(--dim)', marginTop:4 }}>
            Strips transitions &amp; animations sitewide.
          </div>
        </div>

        {/* SECURITY (Phase A 2026-05-18): the actualRole + viewing-as switchers
            are SA-only dev tools. Previously they appeared in every user's
            Tweaks panel — a customer could click "sa" and bypass frontend
            role gating entirely. Now hidden unless the user's REAL role
            (from auth, not impersonation) is super_admin / dev_admin /
            internal_partner. The actualRole setter is also now blocked at
            the WPSBD.set level (see state.js Phase A patch). */}
        {(window.currentUser && (
          window.currentUser.role === 'super_admin' ||
          window.currentUser.role === 'dev_admin' ||
          window.currentUser.role === 'internal_partner'
        )) && (
          <>
            <div style={{ paddingTop:10, borderTop:'1px solid var(--border)' }}>
              <div className="tw-label">Logged-in as (actual role) — SA-ONLY</div>
              <div className="tw-seg" style={{ flexWrap:'wrap' }}>
                {['customer','marketing','dev','admin','sa'].map(v => (
                  <button key={v} className={(s.actualRole || 'customer') === v ? 'active' : ''}
                          disabled
                          title="actualRole is now derived from auth; not user-settable. To test other roles, log in as a real user with that role."
                          onClick={() => {}}>{v}</button>
                ))}
              </div>
              <div style={{ fontSize:'.68rem', color:'var(--dim)', marginTop:4 }}>
                Current actual role: <strong>{s.actualRole}</strong> (from auth — not editable).
                Use a real user account to test other roles.
              </div>
            </div>

            <div>
              <div className="tw-label">Viewing as (impersonating)</div>
              <div className="tw-seg" style={{ flexWrap:'wrap' }}>
                {((window.WPSBD?.IMPERSONATE?.[s.actualRole || 'customer']) || [s.actualRole || 'customer']).map(v => (
                  <button key={v} className={s.role === v ? 'active' : ''} onClick={() => api.set('role', v)}>{v}</button>
                ))}
              </div>
            </div>
          </>
        )}

        <div style={{ fontSize:'.72rem', color:'var(--dim)', lineHeight:1.4, paddingTop:6, borderTop:'1px solid var(--border)' }}>
          Preferences persist to localStorage. Toggle the toolbar <strong style={{ color:'var(--text-2)' }}>Tweaks</strong> switch to hide.
        </div>
      </div>
    </div>
  );
}

/* ── APP ROOT ────────────────────────────────────────────────── */
function App() {
  // ── Plugin Connect short-circuit ──────────────────────────────────
  // URL of form `?plugin_connect=1&site_url=…&install_id=…&state=…&callback_url=…`
  // renders the standalone PluginConnect approval UI WITHOUT the SaaS shell
  // (no sidebar/topbar). This is the App.jsx fallback host per spec §13 Q4 (c):
  // standalone plugin-connect.html is the primary popup target; this route
  // catches the case where the popup was blocked and the main browser tab
  // navigated here instead. Same PluginConnect component runs in both hosts.
  // Detection must happen before any hooks to satisfy rules-of-hooks (the URL
  // doesn't change during a single App mount, so the branch is stable).
  if (typeof window !== 'undefined'
      && window.location
      && /[?&]plugin_connect=1\b/.test(window.location.search || '')) {
    const PC = window.PluginConnect;
    return PC ? React.createElement(PC) : null;
  }

  const [s, api] = useWPSBD();
  const [tweaksOpen, setTweaksOpen] = useState(false);

  // Expose a top-level nav helper so deep components (e.g. Brand Profile → "Generate with Kit Builder") can route
  useEffect(() => { window.__WPSB_NAV = (tab) => api.set('tab', tab); }, [api]);

  useEffect(() => {
    const onMsg = (e) => {
      if (e.origin && e.origin !== window.location.origin) return;
      if (!e.data) return;
      if (e.data.type === '__activate_edit_mode')   setTweaksOpen(true);
      if (e.data.type === '__deactivate_edit_mode') setTweaksOpen(false);
    };
    window.addEventListener('message', onMsg);
    return () => window.removeEventListener('message', onMsg);
  }, []);

  const P1 = window.Pages1, P2 = window.Pages2;
  const allowed = {
    customer:  ['dashboard','sites','content','tasks','workspace','account','billing','brandprofile','support','requests','scanner','imagetools','filemanager','redirects','seo','estimator','acquisition','sitebuilder','kitbuilder','marketingmaterials','agencytools','myaiusage'],
    marketing: ['dashboard','content','tasks','workspace','brandprofile','marketing','seo','scanner','imagetools','filemanager','redirects','sitebuilder','kitbuilder','marketingmaterials','requests','agencytools'],
    dev:       ['dashboard','sites','content','tasks','workspace','account','support','requests','scanner','imagetools','filemanager','redirects','seo','estimator','acquisition','sitebuilder','kitbuilder','marketingmaterials','modules','brains','wiki','internalnotes','agencytools','apikeys'],
    admin:     ['dashboard','sites','content','tasks','workspace','account','billing','brandprofile','support','requests','scanner','imagetools','filemanager','redirects','seo','estimator','acquisition','sitebuilder','kitbuilder','marketingmaterials','marketing','wiki','team','permissions','roles','brand','usermgmt','businessmetrics','notices','internalnotes','agencytools','leads','aiusage','alttext','myaiusage','operations','apikeys'],
    support:   ['dashboard','sites','tasks','workspace','account','support','requests','scanner','usermgmt','notices','agencytools','apikeys'],
    sa: ['dashboard','sites','content','tasks','workspace','account','billing','brandprofile','support','requests','scanner','imagetools','filemanager','redirects','seo','estimator','acquisition','sitebuilder','kitbuilder','marketingmaterials','notices','brains','permissions','roles','team','modules','brand','marketing','wiki','businessmetrics','usermgmt','internalnotes','agencytools','leads','aiusage','alttext','myaiusage','operations','apikeys','pricingintel'],
  }[s.role] || [];

  useEffect(() => {
    if (!allowed.includes(s.tab)) api.switchTab('dashboard');
  }, [s.role]);

  const page = (() => {
    switch (s.tab) {
      case 'dashboard': return <Dashboard s={s} api={api}/>;
      case 'sites':     return <P1.Sites/>;
      case 'account':   return <P1.Account s={s}/>;
      case 'billing':   return <P1.Billing s={s}/>;
      case 'support':   return <P2.Support/>;
      case 'requests':  return <window.Roadmap role={s.role} />;
      case 'scanner':   return <window.Scanner/>;
      case 'imagetools': return <window.ImageTools/>;
      case 'filemanager': return <window.FileManager/>;
      case 'redirects': return <window.Redirects/>;
      case 'seo':       return <window.ContentSEO/>;
      case 'estimator': return <window.Estimator/>;
      case 'usermgmt':    return <window.UserManagement/>;
      case 'operations':  return <window.OperationsAdmin/>;
      case 'leads':       return <window.Leads/>;
      case 'aiusage':     return <window.AIUsage/>;
      case 'alttext':     return <window.AltText/>;
      case 'myaiusage':   return <window.AccountAIUsage/>;
      case 'apikeys':     return <window.AccountApiKeys/>;
      case 'acquisition': return <div style={{padding:40,textAlign:'center',color:'var(--dim)'}}>
        <div style={{fontSize:'1.5rem',marginBottom:12}}>🏢</div>
        <strong style={{color:'var(--text)'}}>Acquisition Mode</strong>
        <div style={{marginTop:8,fontSize:'.85rem'}}>Coming soon — Growth+ plan feature.</div>
        <div style={{marginTop:4,fontSize:'.78rem',color:'var(--dimmer)'}}>Build phase Q3 2026 · Playbook available now at wpsitebeam.io/acquisition</div>
      </div>;
      case 'sitebuilder': return <window.SiteBuilder/>;
      case 'kitbuilder': return <window.KitBuilder/>;
      case 'marketingmaterials': return <window.MarketingMaterials/>;
      case 'businessmetrics': return <window.BusinessMetrics/>;
      case 'pricingintel':    return <window.PricingIntelligence/>;
      case 'workspace': return <P2.Workspace/>;
      case 'modules':     return <P2.Modules/>;
      case 'permissions': return <P2.Permissions/>;
      case 'notices':   return <P2.Notices/>;
      case 'brains':    return <P2.Brains/>;
      case 'roles':     return <P2.Roles api={api}/>;
      case 'team':      return <P2.Team/>;
      case 'brand':     return <P2.Brand/>;
      case 'tasks':     return <P2.Tasks/>;
      case 'content':   return <P2.Content/>;
      case 'marketing': return <P2.Marketing/>;
      case 'wphealth':  return <window.WPHealth/>;
      case 'wiki':      return <P2.Wiki/>;
      case 'internalnotes': return <window.InternalNotes role={s.role} />;
      case 'agencytools': return <window.AgencyTools />;
      case 'brandprofile': return <P2.BrandProfile/>;
      default: return <Dashboard s={s} api={api}/>;
    }
  })();

  // Reset focus on tab change so screen-reader users land at the top of new content
  const mainRef = React.useRef(null);
  useEffect(() => {
    if (mainRef.current) mainRef.current.focus();
  }, [s.tab]);

  // Tablet/mobile sidebar drawer — open/close + auto-close on tab change + outside click
  const [sbOpen, setSbOpen] = useState(false);
  useEffect(() => { setSbOpen(false); }, [s.tab]);

  // Desktop sidebar collapse — icon-only rail toggle, persisted in localStorage.
  // Separate from the mobile drawer (which is fullscreen slide-in under 980px).
  const [sbCollapsed, setSbCollapsed] = useState(() => {
    try { return localStorage.getItem('wpsbd_sb_collapsed') === '1'; }
    catch { return false; }
  });
  const toggleCollapse = () => {
    setSbCollapsed(v => {
      const next = !v;
      try { localStorage.setItem('wpsbd_sb_collapsed', next ? '1' : '0'); } catch {}
      return next;
    });
  };

  return (
    <>
      <a className="skip-link" href="#main-content">Skip to main content</a>
      <div className="sa-bar" aria-hidden="true"/>
      <div className={`app${sbOpen ? ' sb-open' : ''}${sbCollapsed ? ' sb-collapsed' : ''}`}
           data-nav="sidebar" data-density={s.density} data-theme={s.theme}>
        <Topbar s={s} api={api} onOpenTweaks={() => setTweaksOpen(v => !v)} onToggleSidebar={() => setSbOpen(v => !v)}/>
        <Sidebar s={s} api={api} collapsed={sbCollapsed} onToggleCollapse={toggleCollapse}/>
        <button className="sidebar-scrim" aria-label="Close navigation" tabIndex={sbOpen ? 0 : -1}
                onClick={() => setSbOpen(false)}/>
        <main className="main" id="main-content" role="main" tabIndex={-1} ref={mainRef}
              aria-labelledby="page-title">{page}<GlobalFooter/></main>
      </div>
      {/* Live region for async status announcements (scan complete, saved, etc.) */}
      <div id="wpsbd-live" role="status" aria-live="polite" aria-atomic="true" className="sr-only"></div>
      {tweaksOpen && <Tweaks s={s} api={api} onClose={() => setTweaksOpen(false)}/>}
    </>
  );
}

// Global helper any component can call to announce a status change
window.announce = function(msg) {
  const el = document.getElementById('wpsbd-live');
  if (!el) return;
  el.textContent = '';
  // Trigger change after a tick so AT picks it up
  setTimeout(() => { el.textContent = msg; }, 50);
};

/* ── GLOBAL FOOTER ──────────────────────────────────────────────
   Present at the bottom of every page; matches plugin footer copy. */
function GlobalFooter() {
  return (
    <footer className="wpsbd-footer" style={{
      marginTop: 48, padding: '24px 0 32px',
      textAlign: 'center', fontSize: '.78rem', color: 'var(--dim)', lineHeight: 1.6
    }}>
      <div style={{ marginBottom: 10 }}>
        © 2026 WPSiteBeam
      </div>
      <div style={{ display: 'inline-flex', gap: 20, flexWrap: 'wrap', justifyContent: 'center', marginBottom: 14 }}>
        <a href="https://wpsitebeam.io/terms-of-service" target="_blank" rel="noopener noreferrer"
           style={{ color: 'var(--text-2)', textDecoration: 'none' }}>Terms of Service</a>
        <a href="https://wpsitebeam.io/privacy-policy" target="_blank" rel="noopener noreferrer"
           style={{ color: 'var(--text-2)', textDecoration: 'none' }}>Privacy Policy</a>
        <a href="https://wpsitebeam.io/disclaimer" target="_blank" rel="noopener noreferrer"
           style={{ color: 'var(--text-2)', textDecoration: 'none' }}>Disclaimer</a>
        <a href="#" onClick={e => { e.preventDefault(); window.WPSBD?.switchTab?.('support'); }}
           style={{ color: 'var(--text-2)', textDecoration: 'none' }}>Support</a>
      </div>
      <div style={{ maxWidth: 680, margin: '0 auto', fontSize: '.72rem', color: 'var(--dim)', opacity: .85, paddingTop: 14 }}>
        🤖 AI-powered — always verify scan results before acting on them. WPSiteBeam collects no message content, passwords, or personal data. WPSiteBeam retains all proprietary rights to its platform, systems, and AI models.
      </div>
    </footer>
  );
}
window.GlobalFooter = GlobalFooter;

/* Global toast — non-blocking success/action feedback.
   Paired with announce() for a11y. Usage: wpsbToast('Copied!'). */
window.wpsbToast = function(msg, tone = 'ok') {
  let host = document.getElementById('wpsbd-toast-host');
  if (!host) {
    host = document.createElement('div');
    host.id = 'wpsbd-toast-host';
    host.style.cssText = 'position:fixed;right:20px;bottom:20px;display:flex;flex-direction:column;gap:8px;z-index:9000;pointer-events:none;';
    document.body.appendChild(host);
  }
  const el = document.createElement('div');
  const color = tone === 'ok' ? 'var(--green)' : tone === 'warn' ? 'var(--warn)' : tone === 'err' ? 'var(--rose)' : 'var(--beam)';
  el.style.cssText = `
    background: var(--surface); border: 1px solid var(--border); border-left: 3px solid ${color};
    color: var(--text); padding: 10px 14px; border-radius: 6px; font-size: .82rem;
    box-shadow: 0 10px 30px rgba(0,0,0,.35); min-width: 220px; max-width: 360px;
    opacity: 0; transform: translateY(8px); transition: opacity .18s ease, transform .18s ease;
    pointer-events: auto;
  `;
  el.textContent = msg;
  host.appendChild(el);
  requestAnimationFrame(() => { el.style.opacity = '1'; el.style.transform = 'translateY(0)'; });
  setTimeout(() => {
    el.style.opacity = '0'; el.style.transform = 'translateY(8px)';
    setTimeout(() => el.remove(), 220);
  }, 2800);
  window.announce(msg);
};

/* Trigger a real download of given text content. */
window.wpsbDownload = function(filename, content, mime = 'application/octet-stream') {
  try {
    const blob = content instanceof Blob ? content : new Blob([content], { type: mime });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url; a.download = filename;
    document.body.appendChild(a); a.click(); a.remove();
    setTimeout(() => URL.revokeObjectURL(url), 500);
    window.wpsbToast(`Downloaded ${filename}`, 'ok');
  } catch (e) {
    window.wpsbToast(`Download failed: ${e.message}`, 'err');
  }
};

/* Copy to clipboard with toast feedback. */
window.wpsbCopy = async function(text, label = 'Copied to clipboard') {
  try {
    await navigator.clipboard.writeText(text);
    window.wpsbToast(label, 'ok');
  } catch {
    // fallback for older browsers
    const ta = document.createElement('textarea');
    ta.value = text; ta.style.position = 'fixed'; ta.style.opacity = '0';
    document.body.appendChild(ta); ta.select();
    try { document.execCommand('copy'); window.wpsbToast(label, 'ok'); }
    catch { window.wpsbToast('Copy failed — select text manually', 'err'); }
    ta.remove();
  }
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App/>);
