/* global React, ReactDOM */
// Main App: routing + global keyboard.

function App() {
  const toast = window.useToast();
  const [route, setRoute] = React.useState('dashboard');
  const [user, setUser] = React.useState(null);
  const [loadingMe, setLoadingMe] = React.useState(true);
  const [cmdkOpen, setCmdkOpen] = React.useState(false);
  const [focusSubmissionId, setFocusSubmissionId] = React.useState(null);
  const [openStaging, setOpenStaging] = React.useState(false);
  const [help, setHelp] = React.useState(false);
  const [theme, setTheme] = React.useState(() => localStorage.getItem('pk.theme') || 'auto');

  // Restore session via /api/auth/me
  React.useEffect(() => {
    window.API.me()
      .then((u) => { if (u) setUser(u); setLoadingMe(false); })
      .catch(() => setLoadingMe(false));
  }, []);

  const role = user?.role || 'super-admin';

  React.useEffect(() => {
    document.documentElement.setAttribute('data-theme', theme);
    localStorage.setItem('pk.theme', theme);
  }, [theme]);

  // Global keyboard
  React.useEffect(() => {
    const onKey = (e) => {
      const isInput = e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.isContentEditable;
      const meta = e.metaKey || e.ctrlKey;
      if (meta && e.key.toLowerCase() === 'k') { e.preventDefault(); setCmdkOpen(true); return; }
      if (isInput) return;
      if (e.key === '/') { e.preventDefault(); setCmdkOpen(true); }
      else if (e.key === '?') { e.preventDefault(); setHelp(true); }
      else if (e.key === 'g') {
        const fn = (e2) => {
          const map = { d: 'dashboard', s: 'submissions', e: 'data', w: 'wiki', p: 'pokedex', a: 'audit', t: 'settings', f: 'feedback' };
          if (map[e2.key]) { setRoute(map[e2.key]); }
          window.removeEventListener('keydown', fn);
        };
        window.addEventListener('keydown', fn, { once: true });
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  if (loadingMe) {
    return (
      <div style={{ display:'grid', placeItems:'center', height:'100vh', color:'var(--text-3)' }}>
        <span className="spinner" style={{ width: 24, height: 24 }}/>
      </div>
    );
  }

  if (!user) {
    return <window.LoginScreen onLogin={(u) => { setUser(u); }}/>;
  }

  const onAction = (kind, arg) => {
    if (kind === 'scrape') {
      window.API.triggerScrape()
        .then(() => toast.push('已触发抓取任务'))
        .catch((e) => toast.push(`触发失败:${e.message}`, 'err'));
    }
    else if (kind === 'newWiki') { setRoute('wiki'); toast.push('新建攻略'); }
    else if (kind === 'publish') {
      if (!window.can(role, 'data', 'w')) { toast.push('权限不足', 'err'); return; }
      setRoute('data'); setOpenStaging(true);
    }
    else if (kind === 'staging') {
      if (!window.can(role, 'data', 'r')) { toast.push('权限不足', 'err'); return; }
      setRoute('data'); setOpenStaging(true);
    }
    else if (kind === 'openSub') { setRoute('submissions'); setFocusSubmissionId(arg); }
    else if (kind === 'openWiki') setRoute('wiki');
    else if (kind === 'cycleTheme') {
      const cycle = { light: 'dark', dark: 'auto', auto: 'light' };
      const next = cycle[theme] || 'light';
      setTheme(next);
      toast.push(`主题: ${next}`);
    }
  };

  let page;
  if (!window.can(role, route, 'r')) {
    page = <ForbiddenPage route={route} role={role} onBack={() => setRoute('dashboard')}/>;
  }
  else if (route === 'dashboard')   page = <window.Dashboard user={user} role={role} onNavigate={setRoute} onOpenStaging={() => { setRoute('data'); setOpenStaging(true); }}/>;
  else if (route === 'submissions') page = <window.SubmissionsPage user={user} role={role} toast={toast} focusId={focusSubmissionId} onClearFocus={() => setFocusSubmissionId(null)}/>;
  else if (route === 'data')   page = <window.DataEditorPage role={role} toast={toast} openStagingExt={openStaging} onStagingClosed={() => setOpenStaging(false)}/>;
  else if (route === 'wiki')   page = <window.WikiPage role={role} toast={toast}/>;
  else if (route === 'pokedex') page = <window.PokedexPage role={role} toast={toast}/>;
  else if (route === 'audit')  page = <window.AuditLogPage role={role}/>;
  else if (route === 'scrape') page = <window.ScrapePage role={role} toast={toast}/>;
  else if (route === 'feedback') page = <window.FeedbackPage role={role}/>;
  else if (route === 'status') page = <window.StatusPage role={role}/>;
  else if (route === 'settings') page = <window.SettingsPage role={role} toast={toast} onThemeChange={setTheme} currentTheme={theme}/>;

  return (
    <div className="app-shell">
      <window.Topbar user={user}
                     onOpenCmdK={() => setCmdkOpen(true)}
                     onLogout={() => {
                       window.API.logout().then(() => { setUser(null); setRoute('dashboard'); });
                     }}/>
      <window.Sidebar route={route} role={role}
                      onNavigate={setRoute}
                      onForbidden={(n) => toast.push(`权限不足:${n.label} 需要更高角色`, 'err')}/>
      <main className="main" style={{ padding: 'var(--main-pad, 36px 48px)' }}>{page}</main>

      <window.CommandPalette open={cmdkOpen} onClose={() => setCmdkOpen(false)}
                             role={role}
                             onNavigate={(id) => {
                               if (!window.can(role, id, 'r')) { toast.push('权限不足', 'err'); return; }
                               setRoute(id);
                             }}
                             onAction={onAction}/>

      {help && <HelpOverlay onClose={() => setHelp(false)}/>}

      {toast.node}
    </div>
  );
}

function ForbiddenPage({ route, role, onBack }) {
  const nav = window.NAV.find((n) => n.id === route);
  return (
    <div>
      <div className="page-header">
        <div>
          <div className="breadcrumb"><span>权限</span><span className="sep">/</span><span>受限</span></div>
          <h1 className="page-title">权限不足</h1>
          <div className="page-subtitle">
            你的角色 <window.RolePill role={role}/> 无法访问 <b>{nav?.label || route}</b>。
          </div>
        </div>
      </div>
      <div className="card card-pad" style={{
        display:'flex', flexDirection: 'column', alignItems: 'center',
        textAlign: 'center', padding: 64,
      }}>
        <div style={{
          width: 72, height: 72, borderRadius: '50%',
          background: 'var(--surface-2)', border: '1px solid var(--border)',
          display: 'grid', placeItems: 'center', marginBottom: 20,
          color: 'var(--text-3)',
        }}>
          <window.I.shield size={32}/>
        </div>
        <div style={{ fontWeight: 600, fontSize: 16, marginBottom: 8 }}>
          需要更高的角色权限
        </div>
        <div className="muted" style={{ fontSize: 13, maxWidth: 420, marginBottom: 20 }}>
          联系主管理员申请 <b>编辑</b> 或 <b>主管理员</b> 角色,即可访问 {nav?.label}。
        </div>
        <window.Btn kind="primary" onClick={onBack}>返回仪表盘</window.Btn>
      </div>
    </div>
  );
}

function HelpOverlay({ onClose }) {
  const groups = [
    { name: '全局', items: [
      ['⌘ K', '打开命令面板'], ['/', '搜索'], ['?', '快捷键帮助'],
      ['g d', '跳到仪表盘'], ['g s', '跳到审核台'], ['g e', '跳到数据编辑'],
      ['g w', '跳到攻略'], ['g p', '跳到图鉴'], ['g a', '跳到日志'],
    ]},
    { name: '审核台', items: [
      ['j / k', '上下移动'], ['Enter', '打开详情'],
      ['a', '通过'], ['r', '驳回'], ['Space', '多选'],
    ]},
    { name: '数据编辑', items: [
      ['e', '编辑当前阵容'], ['n', '新增阵容'],
      ['⌘ S', '保存到暂存'], ['⌘ ⇧ P', '发布全部'],
    ]},
  ];
  return (
    <div className="drawer-backdrop" onClick={onClose} style={{ display:'grid', placeItems:'center' }}>
      <div onClick={(e) => e.stopPropagation()} className="card" style={{ width: 640, maxHeight: '80vh', overflow: 'auto', animation: 'pop .14s ease' }}>
        <div className="card-header">
          <div className="card-title">键盘快捷键</div>
          <button className="icon-btn" onClick={onClose}><window.I.x size={14}/></button>
        </div>
        <div className="card-pad" style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap: 20 }}>
          {groups.map((g) => (
            <div key={g.name}>
              <div style={{ fontSize: 11, color: 'var(--text-3)', textTransform:'uppercase', letterSpacing:'.06em', marginBottom: 10 }}>{g.name}</div>
              {g.items.map(([k, label]) => (
                <div key={k} style={{ display:'flex', justifyContent:'space-between', alignItems:'center', padding: '6px 0', fontSize: 13 }}>
                  <span className="muted">{label}</span>
                  <span className="kbd" style={{ fontFamily: 'var(--font-mono)' }}>{k}</span>
                </div>
              ))}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

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