// shell.jsx — portal chrome + the shared PortalContext (provided by main.jsx).
const { useState: uS, useRef: uR, useEffect: uE, useMemo: uM, createContext: cC, useContext: uC } = React;

const PortalContext = cC(null);
function usePortal(){ return uC(PortalContext); }

/* ===================== Đồng hồ + lịch trên topbar ===================== */
// Chỉ component này tick mỗi giây → KHÔNG re-render cả topbar/lịch (giữ perf).
function ClockText(){
  const { lang } = useLang();
  const [now, setNow] = React.useState(() => new Date());
  React.useEffect(() => { const id = setInterval(() => setNow(new Date()), 1000); return () => clearInterval(id); }, []);
  const loc = lang === 'vi' ? 'vi-VN' : 'en-US';
  return (
    <>
      <span className="clk-date">{now.toLocaleDateString(loc, { day:'2-digit', month:'2-digit', year:'numeric' })}</span>
      <span className="clk-time mono">{now.toLocaleTimeString(loc, { hour12:false })}</span>
    </>
  );
}

// Lịch tháng chỉ-để-xem (điều hướng tháng, hôm nay tô đậm) — mở từ chip đồng hồ.
function MiniCalendar(){
  const { lang } = useLang();
  const loc = lang === 'vi' ? 'vi-VN' : 'en-US';
  const today = new Date();
  const [view, setView] = React.useState(() => new Date(today.getFullYear(), today.getMonth(), 1));
  const y = view.getFullYear(), m = view.getMonth();
  const startDow = (new Date(y, m, 1).getDay() + 6) % 7;         // thứ 2 đầu tuần (0 = T2)
  const daysInMonth = new Date(y, m + 1, 0).getDate();
  const cells = [];
  for (let i = 0; i < startDow; i++) cells.push(null);
  for (let d = 1; d <= daysInMonth; d++) cells.push(d);
  while (cells.length % 7 !== 0) cells.push(null);
  const dow = lang === 'vi' ? ['T2','T3','T4','T5','T6','T7','CN'] : ['Mo','Tu','We','Th','Fr','Sa','Su'];
  const isToday = (d) => d && y === today.getFullYear() && m === today.getMonth() && d === today.getDate();
  return (
    <div className="mini-cal">
      <div className="mc-head">
        <button className="iconbtn" onClick={() => setView(new Date(y, m - 1, 1))} aria-label="prev"><i className="bi bi-chevron-left"></i></button>
        <span className="mc-title">{view.toLocaleDateString(loc, { month:'long', year:'numeric' })}</span>
        <button className="iconbtn" onClick={() => setView(new Date(y, m + 1, 1))} aria-label="next"><i className="bi bi-chevron-right"></i></button>
      </div>
      <div className="mc-grid mc-dow">{dow.map((w, i) => <span key={i} className="mc-w">{w}</span>)}</div>
      <div className="mc-grid">{cells.map((d, i) => <span key={i} className={'mc-day' + (d ? '' : ' mc-empty') + (isToday(d) ? ' is-today' : '')}>{d || ''}</span>)}</div>
      <div className="mc-foot">
        <span className="subtle">{today.toLocaleDateString(loc, { weekday:'long', day:'2-digit', month:'2-digit', year:'numeric' })}</span>
        <button className="btn btn-sm btn-ghost" style={{ height:24, padding:'0 8px', color:'var(--primary)' }} onClick={() => setView(new Date(today.getFullYear(), today.getMonth(), 1))}>{lang === 'vi' ? 'Hôm nay' : 'Today'}</button>
      </div>
    </div>
  );
}

function TopbarClock(){
  const { lang } = useLang();
  return (
    <Popover align="right" width={264} button={({ toggle, open }) => (
      <button className={'clock-chip hide-sm' + (open ? ' is-open' : '')} onClick={toggle} title={lang === 'vi' ? 'Xem lịch' : 'Open calendar'}>
        <i className="bi bi-calendar3"></i><ClockText />
      </button>
    )}>
      {() => <MiniCalendar />}
    </Popover>
  );
}

/* ===================== Topbar ===================== */
function Topbar() {
  const p = usePortal();
  const { lang, setLang, t, tt } = useLang();
  const me = p.me;
  const roleColors = { staff:'var(--text-muted)', manager:'var(--accent)', admin:'var(--primary)' };
  const unread = p.notifs.filter(n => n.unread).length;
  return (
    <div className="topbar">
      <button className="iconbtn mobile-only" onClick={() => p.setDrawerOpen(true)} aria-label="Menu"><i className="bi bi-list" style={{ fontSize:20 }}></i></button>
      <span className="bname mobile-only" style={{ marginRight:2 }}>{(p.branding && p.branding.name) || 'My S.W.O'}</span>
      <button className="topsearch" onClick={p.openCmdk}>
        <i className="bi bi-search"></i><span className="grow" style={{ textAlign:'left' }}>{t('shell.search')}</span>
        <kbd>⌘K</kbd>
      </button>
      <div className="spacer"></div>

      {/* DEMO: badge + chuyển nhanh vai trò (demo/demo-ui.jsx, chỉ render ở bản demo) */}
      {window.SWO_CONFIG.IS_DEMO && <DemoRoleSwitch />}

      {/* ngày · giờ hiện tại + nút mở lịch */}
      <TopbarClock />

      {/* language */}
      <span className="lang-seg"><Segmented value={lang} onChange={setLang} options={[{ value:'vi', label:'VI' }, { value:'en', label:'EN' }]} /></span>

      {/* notifications */}
      <Popover align="right" width={330} button={({ toggle }) => (
        <button className="iconbtn" onClick={toggle} aria-label="Notifications">
          <i className="bi bi-bell"></i>{unread > 0 && <span className="nbadge">{unread}</span>}
        </button>
      )}>
        {({ close }) => (
          <>
            <div className="flex items-center justify-between" style={{ padding:'8px 10px 4px' }}>
              <span className="menu-label" style={{ padding:0 }}>{t('nav.notifs')}{unread > 0 ? ' · ' + unread : ''}</span>
              {unread > 0 && <button className="btn btn-ghost btn-sm" style={{ height:22, padding:'0 6px', color:'var(--primary)' }} onClick={() => p.markAllNotifsRead()}>{t('notif.markAll')}</button>}
            </div>
            <div className="menu-sep"></div>
            {p.notifs.length === 0 && <div className="subtle" style={{ padding:14, textAlign:'center', fontSize:'var(--fs-base)' }}>{t('notif.empty')}</div>}
            {p.notifs.slice(0, 6).map(n => { const ty = NOTIF_TYPES[n.type] || {}; return (
              <button key={n.id} className={'menu-item' + (n.unread ? ' is-unread' : '')} style={{ height:'auto', alignItems:'flex-start', padding:'8px 9px' }}
                onClick={() => { p.markNotifRead(n.id); if (n.link) p.navigate(n.link); close(); }}>
                <i className={'bi ' + ty.icon} style={{ color:ty.color, marginTop:1 }}></i>
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontWeight:n.unread ? 600 : 400, whiteSpace:'normal', lineHeight:1.35 }}>{tt(n.text)}</div>
                  <div className="subtle" style={{ fontSize:'var(--fs-sm)' }}>{n.time}</div>
                </div>
                {n.unread && <span className="rdot" style={{ width:6, height:6, borderRadius:'50%', background:'var(--primary)', marginTop:5, flex:'none' }}></span>}
              </button>
            ); })}
            <div className="menu-sep"></div>
            <button className="menu-item" onClick={() => { p.navigate({ name:'notifs' }); close(); }} style={{ justifyContent:'center', color:'var(--primary)', fontWeight:600 }}>{t('c.viewAll')}<i className="bi bi-arrow-right"></i></button>
          </>
        )}
      </Popover>

      {/* app launcher */}
      <Popover align="right" button={({ toggle }) => (
        <button className="iconbtn hide-sm" onClick={toggle} aria-label="Apps"><span className="dot9">{Array.from({length:9}).map((_,i)=><i key={i}></i>)}</span></button>
      )}>
        {({ close }) => <AppLauncher onClose={close} />}
      </Popover>

      {/* user menu */}
      <Popover align="right" width={210} button={({ toggle }) => (
        <button className="iconbtn" onClick={toggle} style={{ width:'auto', gap:7, paddingLeft:4 }}>
          <Avatar name={me.name} size={26} />
        </button>
      )}>
        {({ close }) => (
          <>
            <div style={{ padding:'8px 10px 6px' }}>
              <div className="flex items-center g8" style={{ justifyContent:'space-between' }}>
                <span style={{ fontWeight:600 }}>{me.name}</span>
                <span className="badge badge-neutral"><span className="rdot" style={{ width:6, height:6, borderRadius:'50%', background:roleColors[p.role] }}></span>{t('role.' + p.role)}</span>
              </div>
              <div className="subtle mono" style={{ fontSize:'var(--fs-sm)' }}>{me.email}</div>
            </div>
            <div className="menu-sep"></div>
            <button className="menu-item" onClick={() => { p.navigate({ name:'settings' }); close(); }}><i className="bi bi-gear"></i>{t('nav.settings')}</button>
            {p.role === 'admin' && <button className="menu-item" onClick={() => { p.navigate({ name:'admin', tab:'system' }); close(); }}><i className="bi bi-sliders2"></i>{t('sys.menu')}</button>}
            <div className="menu-sep"></div>
            <button className="menu-item danger" onClick={() => { p.logout(); close(); }}><i className="bi bi-box-arrow-right"></i>{lang === 'vi' ? 'Đăng xuất' : 'Sign out'}</button>
          </>
        )}
      </Popover>
    </div>
  );
}

/* ===================== App launcher popover ===================== */
function AppLauncher({ onClose }) {
  const p = usePortal();
  const { tt, t } = useLang();
  const apps = p.apps.slice(0, 9);
  return (
    <div className="launcher">
      <div className="lgrid">
        {apps.map(a => (
          <button key={a.id} className="ltile" onClick={() => { p.openApp(a); onClose(); }}>
            <span className="ic" style={{ background:a.color }}><i className={'bi ' + a.icon}></i></span>
            <span className="lt">{tt(a.name)}</span>
          </button>
        ))}
      </div>
      <div className="menu-sep"></div>
      <button className="menu-item" onClick={() => { p.navigate({ name:'allapps' }); onClose(); }} style={{ justifyContent:'center', color:'var(--primary)', fontWeight:600 }}>
        {t('shell.allApps')}<i className="bi bi-arrow-right"></i>
      </button>
    </div>
  );
}

/* ===================== Brandbar ===================== */
function Brandbar() {
  const p = usePortal();
  return (
    <div className="brandbar">
      <button className="brand-logo-btn" onClick={() => p.setCollapsed(c => !c)} aria-label="Toggle sidebar" title={p.collapsed ? 'Mở rộng thanh bên' : 'Thu gọn thanh bên'}>
        <BrandLogo branding={p.branding} size={26} fontSize={10} />
      </button>
      <span className="bname">{(p.branding && p.branding.name) || 'My S.W.O'}</span>
      <button className="iconbtn collapse-btn" onClick={() => p.setCollapsed(c => !c)} aria-label="Collapse sidebar" title="Thu gọn thanh bên">
        <i className="bi bi-chevron-double-left"></i>
      </button>
    </div>
  );
}

/* ===================== Command palette ===================== */
function CommandPalette({ onClose }) {
  const p = usePortal();
  const { tt, t } = useLang();
  const [q, setQ] = uS('');
  const [idx, setIdx] = uS(0);
  const inputRef = uR();
  uE(() => { inputRef.current && inputRef.current.focus(); }, []);
  const nav = [
    { id:'dashboard', icon:'bi-grid-1x2', color:'var(--primary)', label:t('nav.dashboard'), run:() => p.navigate({ name:'dashboard' }) },
    { id:'allapps', icon:'bi-grid-3x3-gap', color:'var(--accent)', label:t('nav.allApps'), run:() => p.navigate({ name:'allapps' }) },
  ];
  const appItems = p.apps.map(a => ({ id:'app-' + a.id, icon:a.icon, color:a.color, label:tt(a.name), meta:'App', run:() => p.openApp(a) }));
  const all = [...nav, ...appItems];
  const filtered = q ? all.filter(i => i.label.toLowerCase().includes(q.toLowerCase())) : all;
  uE(() => { setIdx(0); }, [q]);
  const run = (i) => { const item = filtered[i]; if (item) { item.run(); onClose(); } };
  return (
    <div className="cmdk-overlay" onMouseDown={e => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="cmdk">
        <div className="cmdk-input">
          <i className="bi bi-search"></i>
          <input ref={inputRef} value={q} placeholder={lAng(t)}
            onChange={e => setQ(e.target.value)}
            onKeyDown={e => {
              if (e.key === 'ArrowDown') { e.preventDefault(); setIdx(i => Math.min(i + 1, filtered.length - 1)); }
              else if (e.key === 'ArrowUp') { e.preventDefault(); setIdx(i => Math.max(i - 1, 0)); }
              else if (e.key === 'Enter') { e.preventDefault(); run(idx); }
              else if (e.key === 'Escape') onClose();
            }} />
          <kbd>esc</kbd>
        </div>
        <div className="cmdk-list">
          {filtered.length === 0 && <div className="empty" style={{ padding:24 }}><div>{t('c.empty')}</div></div>}
          {filtered.map((i, n) => (
            <div key={i.id} className={'cmdk-item' + (n === idx ? ' is-active' : '')}
              onMouseEnter={() => setIdx(n)} onClick={() => run(n)}>
              <span className="ic" style={{ background:i.color }}><i className={'bi ' + i.icon}></i></span>
              <span>{i.label}</span>{i.meta && <span className="meta">{i.meta}</span>}
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}
function lAng(t){ return t('shell.search'); }

/* ===================== Portal FAB (draggable) ===================== */
function PortalFAB() {
  const p = usePortal();
  const { t } = useLang();
  const [pos, setPos] = usePersist('fab-pos', { x: window.innerWidth - 150, y: window.innerHeight - 70 });
  const drag = uR({ on:false, moved:false, dx:0, dy:0 });
  const onDown = (e) => {
    drag.current = { on:true, moved:false, dx:e.clientX - pos.x, dy:e.clientY - pos.y };
    const move = (ev) => {
      if (!drag.current.on) return;
      drag.current.moved = true;
      setPos({ x:Math.max(8, Math.min(window.innerWidth - 130, ev.clientX - drag.current.dx)),
               y:Math.max(8, Math.min(window.innerHeight - 50, ev.clientY - drag.current.dy)) });
    };
    const up = () => { drag.current.on = false; document.removeEventListener('mousemove', move); document.removeEventListener('mouseup', up); };
    document.addEventListener('mousemove', move); document.addEventListener('mouseup', up);
  };
  return (
    <button className="fab" style={{ left:pos.x, top:pos.y }}
      onMouseDown={onDown}
      onClick={() => { if (!drag.current.moved) p.navigate({ name:'dashboard' }); }}>
      <i className="bi bi-grid-1x2-fill"></i>{t('shell.backPortal')}
    </button>
  );
}

/* ===================== Thanh tab dưới (mobile) — ẩn trên desktop qua CSS ===================== */
function MobileTabBar(){
  const p = usePortal();
  const { lang } = useLang();
  const r = p.route || {};
  const L = (vi, en) => (lang === 'vi' ? vi : en);
  const unread = (p.notifs || []).filter(n => n.unread).length;
  const Tab = ({ icon, activeIcon, label, active, badge, onClick }) => (
    <button className={'mtab' + (active ? ' is-active' : '')} onClick={onClick}>
      <span className="mtab-ic">
        <i className={'bi ' + (active && activeIcon ? activeIcon : icon)}></i>
        {badge > 0 && <span className="mtab-badge">{badge > 9 ? '9+' : badge}</span>}
      </span>
      <span className="mtab-lb">{label}</span>
    </button>
  );
  return (
    <nav className="mobile-tabbar" aria-label="Primary">
      <Tab icon="bi-house-door" activeIcon="bi-house-door-fill" label={L('Trang chủ', 'Home')}
        active={r.name === 'dashboard'} onClick={() => p.navigate({ name:'dashboard' })} />
      <Tab icon="bi-grid" activeIcon="bi-grid-fill" label={L('Ứng dụng', 'Apps')}
        active={r.name === 'allapps' || r.name === 'module'} onClick={() => p.navigate({ name:'allapps' })} />
      <Tab icon="bi-search" label={L('Tìm', 'Search')} onClick={p.openCmdk} />
      <Tab icon="bi-bell" activeIcon="bi-bell-fill" label={L('Thông báo', 'Alerts')} badge={unread}
        active={r.name === 'notifs'} onClick={() => p.navigate({ name:'notifs' })} />
      <Tab icon="bi-list" label="Menu" onClick={() => p.setDrawerOpen(true)} />
    </nav>
  );
}

Object.assign(window, { PortalContext, usePortal, Topbar, Brandbar, AppLauncher, CommandPalette, PortalFAB, MobileTabBar });
