// 路由 Context + Shell 布局（侧栏 + 顶栏 + 子女切换）
const NavCtx = React.createContext(null);
function NavProvider({ children }) {
  const [route, setRoute] = React.useState({ page: 'home', params: {} });
  const go = (page, params = {}) => { setRoute({ page, params }); window.scrollTo(0, 0); const el = document.querySelector('.content'); if (el) el.scrollTop = 0; };
  return <NavCtx.Provider value={{ route, go }}>{children}</NavCtx.Provider>;
}
const useNav = () => React.useContext(NavCtx);

const NAV = {
  student: [
    { label: '核心', items: [
      { id: 'home', icon: Icons.home, text: '首页总览' },
      { id: 'entry', icon: Icons.edit, text: '成绩录入' },
      { id: 'records', icon: Icons.list, text: '成绩记录' },
      { id: 'analysis', icon: Icons.chart, text: '学情分析' }
    ]},
    { label: '激励 · 治愈', items: [
      { id: 'points', icon: Icons.gift, text: '积分中心', dot: true },
      { id: 'soup', icon: Icons.heart, text: '心灵鸡汤' }
    ]}
  ],
  parent: [
    { label: '核心', items: [
      { id: 'home', icon: Icons.home, text: '首页总览' },
      { id: 'entry', icon: Icons.edit, text: '成绩录入' },
      { id: 'records', icon: Icons.list, text: '成绩记录' },
      { id: 'analysis', icon: Icons.chart, text: '学情分析' }
    ]},
    { label: '家庭 · 激励', items: [
      { id: 'family', icon: Icons.users, text: '家庭管理' },
      { id: 'points', icon: Icons.gift, text: '积分中心' },
      { id: 'soup', icon: Icons.heart, text: '教育治愈' }
    ]}
  ]
};

function ChildSwitcher() {
  const { state, dispatch, activeChild } = useStore();
  const [open, setOpen] = React.useState(false);
  return <div style={{ position: 'relative' }}>
    <div className="child-switch" onClick={() => setOpen(o => !o)} style={{ cursor: 'pointer' }}>
      <div className={'avatar ' + activeChild.avatar}>{activeChild.initial}</div>
      <div><div className="t">{activeChild.name}</div><div className="s">{activeChild.grade.replace(/\(.*\)/, '')} · 当前查看</div></div>
      <Ico d={Icons.chevron} size={16} sw={2.4} style={{ transform: open ? 'rotate(180deg)' : '', transition: '.2s' }} />
    </div>
    {open && <>
      <div onClick={() => setOpen(false)} style={{ position: 'fixed', inset: 0, zIndex: 40 }}></div>
      <div className="card" style={{ position: 'absolute', top: 50, right: 0, width: 230, padding: 8, zIndex: 41, boxShadow: 'var(--shadow-lg)' }}>
        <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--ink-4)', padding: '6px 10px' }}>切换查看对象</div>
        {state.children.map(c => {
          const rate = Selectors.avgRate(c).toFixed(0);
          return <div key={c.id} onClick={() => { dispatch({ type: 'SET_CHILD', childId: c.id }); setOpen(false); }}
            style={{ display: 'flex', alignItems: 'center', gap: 11, padding: '10px', borderRadius: 10, cursor: 'pointer',
              background: c.id === state.activeChildId ? 'var(--blue-5)' : 'transparent' }}>
            <div className={'avatar ' + c.avatar} style={{ width: 34, height: 34, fontSize: 13 }}>{c.initial}</div>
            <div style={{ flex: 1 }}><div style={{ fontWeight: 700, fontSize: 13 }}>{c.name}</div><div style={{ fontSize: 11, color: 'var(--ink-3)' }}>{c.grade} · 得分率 {rate}%</div></div>
            {c.id === state.activeChildId && <Ico d={Icons.check} size={15} sw={3} style={{ color: 'var(--blue-6)' }} />}
          </div>
        })}
      </div>
    </>}
  </div>;
}

// 搜索组件
function SearchBox() {
  const { state, activeChild } = useStore();
  const { go } = useNav();
  const [query, setQuery] = React.useState('');
  const [results, setResults] = React.useState([]);
  const [showResults, setShowResults] = React.useState(false);
  const [loading, setLoading] = React.useState(false);

  React.useEffect(() => {
    if (query.length < 2) {
      setResults([]);
      setShowResults(false);
      return;
    }

    const timeoutId = setTimeout(async () => {
      setLoading(true);
      try {
        const params = new URLSearchParams({ q: query });
        if (state.role === 'parent' && activeChild.id !== 'me') {
          params.append('childId', activeChild.id);
        }
        const resp = await fetch(`/api/search?${params}`, {
          headers: { Authorization: `Bearer ${state.token}` }
        });
        const data = await resp.json();
        if (data.success) {
          setResults(data.data);
          setShowResults(true);
        }
      } catch (e) {
        console.error('搜索失败:', e);
      } finally {
        setLoading(false);
      }
    }, 300);

    return () => clearTimeout(timeoutId);
  }, [query, state.token, state.role, activeChild.id]);

  const handleResultClick = (result) => {
    setQuery('');
    setShowResults(false);
    go('records');
  };

  return (
    <div style={{ position: 'relative' }}>
      <div style={{
        display: 'flex',
        alignItems: 'center',
        gap: 8,
        background: 'var(--surface-2)',
        borderRadius: 'var(--r-sm)',
        padding: '8px 12px',
        minWidth: 240
      }}>
        <Ico d={Icons.search} size={16} style={{ color: 'var(--ink-4)' }} />
        <input
          style={{
            border: 'none',
            outline: 'none',
            background: 'transparent',
            flex: 1,
            fontSize: 14
          }}
          placeholder="搜索考试、学科、备注..."
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          onFocus={() => query.length >= 2 && setShowResults(true)}
        />
        {loading && <div style={{ fontSize: 12, color: 'var(--ink-4)' }}>搜索中...</div>}
      </div>

      {showResults && results.length > 0 && (
        <>
          <div onClick={() => setShowResults(false)} style={{ position: 'fixed', inset: 0, zIndex: 49 }}></div>
          <div style={{
            position: 'absolute',
            top: 48,
            right: 0,
            width: 400,
            maxHeight: 400,
            overflowY: 'auto',
            background: 'white',
            borderRadius: 'var(--r)',
            boxShadow: 'var(--shadow-lg)',
            padding: 8,
            zIndex: 50
          }}>
            {results.map((result, i) => (
              <div
                key={i}
                style={{
                  padding: 12,
                  borderRadius: 8,
                  cursor: 'pointer',
                  display: 'flex',
                  flexDirection: 'column',
                  gap: 4
                }}
                onMouseEnter={(e) => e.currentTarget.style.background = 'var(--surface-2)'}
                onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}
                onClick={() => handleResultClick(result)}
              >
                <div style={{ fontWeight: 600, fontSize: 14 }}>{result.title}</div>
                <div style={{ fontSize: 13, color: 'var(--ink-3)' }}>{result.subtitle}</div>
              </div>
            ))}
          </div>
        </>
      )}
    </div>
  );
}

// 通知铃铛组件
function NotificationBell() {
  const { state, dispatch } = useStore();
  const [showNotificationCenter, setShowNotificationCenter] = React.useState(false);
  const [unreadCount, setUnreadCount] = React.useState(0);

  // 加载未读数量
  const loadUnreadCount = React.useCallback(async () => {
    if (!state.token) return;
    try {
      const resp = await fetch('/api/notifications', {
        headers: { Authorization: `Bearer ${state.token}` }
      });
      const data = await resp.json();
      if (data.success) {
        setUnreadCount(data.data.unreadCount || 0);
      }
    } catch (e) {
      console.error('加载通知失败:', e);
    }
  }, [state.token]);

  React.useEffect(() => {
    loadUnreadCount();
  }, [loadUnreadCount]);

  return (
    <>
      <button
        className="icon-btn"
        onClick={() => setShowNotificationCenter(true)}
        style={{ position: 'relative' }}
      >
        <Ico d={Icons.bell} size={19} />
        {unreadCount > 0 && (
          <span style={{
            position: 'absolute',
            top: 2,
            right: 2,
            width: 16,
            height: 16,
            borderRadius: '50%',
            background: 'var(--coral)',
            color: 'white',
            fontSize: 10,
            fontWeight: 700,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center'
          }}>
            {unreadCount > 9 ? '9+' : unreadCount}
          </span>
        )}
      </button>

      {showNotificationCenter && (
        <NotificationCenter onClose={() => setShowNotificationCenter(false)} />
      )}
    </>
  );
}

function Shell({ title, crumb, children }) {
  const { state, dispatch, activeChild } = useStore();
  const { route, go } = useNav();
  const role = state.role;
  const nav = NAV[role];
  const [accountMenuOpen, setAccountMenuOpen] = React.useState(false);
  const needsFamilySetup = role === 'parent' && state.requiresFamilySetup;
  const profile = state.user && state.user.profile;
  const accountName = profile && profile.nickname ? profile.nickname : (state.user && state.user.username) || '用户';
  const accountGrade = profile && profile.grade ? profile.grade : activeChild.grade;
  const accountInitial = accountName.trim().charAt(0) || '用';
  const roleInfo = role === 'parent'
    ? { ico: Icons.users, cls: 'bg-orange-soft', t: '家长账号', s: needsFamilySetup ? '待添加孩子' : '已绑定 ' + (state.authChildren && state.authChildren.length ? state.authChildren.length : state.children.length) + ' 名子女' }
    : { ico: Icons.cap, cls: 'bg-blue-soft', t: '学生账号', s: accountGrade + ' · ' + accountName };

  return <div className="app">
    <aside className="sidebar">
      <div className="brand">
        <div className="logo"><Ico d={Icons.cap} size={22} style={{ color: '#fff' }} /></div>
        <div className="name">学情星<small>STUDENT · GRADES</small></div>
      </div>
      <nav className="nav">
        {nav.map(g => (<React.Fragment key={g.label}>
          <div className="group-label">{g.label}</div>
          {g.items.map(it => (
            <a key={it.id} className={route.page === it.id ? 'active' : ''} onClick={() => go(it.id)} style={{ cursor: 'pointer' }}>
              <Ico d={it.icon} size={19} /><span>{it.text}</span>
              {it.dot && <span className="badge-dot">{activeChild.points}</span>}
            </a>
          ))}
        </React.Fragment>))}
      </nav>
      <div className="sidebar-foot" style={{ position: 'relative' }}>
        <div className="role-pill" onClick={() => setAccountMenuOpen(open => !open)} style={{ cursor: 'pointer' }}>
          <div className={'ico ' + roleInfo.cls}><Ico d={roleInfo.ico} size={17} /></div>
          <div><div className="t">{roleInfo.t}</div><div className="s">{roleInfo.s}</div></div>
          <div style={{ marginLeft: 'auto' }}><Ico d={Icons.chevron} size={15} sw={2.4} style={{ transform: accountMenuOpen ? 'rotate(180deg)' : '', transition: '.2s' }} /></div>
        </div>
        {accountMenuOpen && <>
          <div onClick={() => setAccountMenuOpen(false)} style={{ position: 'fixed', inset: 0, zIndex: 30 }}></div>
          <div className="card" style={{ position: 'absolute', left: 0, right: 0, bottom: 74, padding: 8, zIndex: 31, boxShadow: 'var(--shadow-lg)' }}>
            <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--ink-4)', padding: '6px 10px' }}>账号操作</div>
            <div onClick={() => { setAccountMenuOpen(false); dispatch({ type: 'LOGOUT' }); }} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '11px 10px', borderRadius: 10, cursor: 'pointer', color: 'var(--ink-2)', fontWeight: 800, fontSize: 13 }}>
              <Ico d={Icons.logout} size={18} /><span>退出登录</span>
            </div>
          </div>
        </>}
      </div>
    </aside>
    <div className="main">
      <header className="topbar">
        <div>
          <div className="page-title">{title}</div>
          {crumb && <div className="crumb">{crumb}</div>}
        </div>
        <div className="spacer"></div>
        <SearchBox />
        <NotificationBell />
        {role === 'parent' && !needsFamilySetup && <ChildSwitcher />}
        <div className={'avatar ' + (role === 'parent' ? 'av-orange' : 'av-blue')}>{role === 'parent' ? accountInitial : activeChild.initial}</div>
      </header>
      <main className="content"><div className="content-narrow">{children}</div></main>
    </div>
  </div>;
}

Object.assign(window, { NavProvider, useNav, Shell });
