// App shell — sidebar (drawer on mobile), topbar, tweak panel
// Design system: see DESIGN.md ("The Climbing Wall")
const { PEOPLE, METRICS, HISTORY, TODAY_ENTRIES, ROCKS, MANUAL_ISSUES, AI_INSIGHTS, TEAMS_MESSAGES } = window.NORWILL_DATA;

const VIEWS = [
  { id: 'dashboard', label: 'Dashboard',         icon: 'home',   roleScope: 'ceo' },
  { id: 'my',        label: 'My Scorecard',      icon: 'pulse',  roleScope: 'all' },
  { id: 'huddle',    label: 'Metric Entry',      icon: 'chat',   roleScope: 'all' },
  { id: 'scorecard', label: '13-Week Scorecard', icon: 'grid',   roleScope: 'all' },
  { id: 'rocks',     label: 'Rocks',             icon: 'rock',   roleScope: 'all' },
  { id: 'issues',    label: 'Issues / IDS',      icon: 'alert',  roleScope: 'all' },
  { id: 'metrics',   label: 'Metrics Map',       icon: 'map',    roleScope: 'all' },
  { id: 'notifications', label: 'Notifications', icon: 'bell',   roleScope: 'all' },
  { id: 'training',  label: 'Training',          icon: 'book',   roleScope: 'all' },
  { id: 'feedback',  label: 'Feedback',          icon: 'chat',   roleScope: 'ceo' },
  { id: 'access',    label: 'User Access',       icon: 'users',  roleScope: 'ceo' },
];

// Bottom tab bar surfaces the 5 most-used mobile views. The drawer covers
// everything else (Dashboard, Planner, Metrics Map, Notifications, Feedback,
// User Access). Order is the daily flow: enter → check trends → quarter
// progress → discuss issues → check personal scorecard.
const MOBILE_TABS = ['huddle', 'scorecard', 'rocks', 'issues', 'my'];
const MOBILE_TAB_LABELS = {
  huddle:    'Entry',
  scorecard: 'Score',
  rocks:     'Rocks',
  issues:    'Issues',
  my:        'My',
};

function visibleViews(authUser, persona) {
  const canSeeCeoViews = authUser
    ? (authUser.role === 'admin' || authUser.role === 'owner')
    : (persona && persona.id === 'olie');
  return VIEWS.filter(v => canSeeCeoViews || v.roleScope === 'all');
}

function Sidebar({ view, setView, persona, authUser, onOpenFeedback, feedbackAwaiting, drawerOpen, onCloseDrawer }) {
  const isMobile = useMedia('(max-width: 760px)');
  const visible = visibleViews(authUser, persona);

  // Auto-close drawer when navigating to a different view (mobile only).
  const pickView = (id) => {
    setView(id);
    if (isMobile && onCloseDrawer) onCloseDrawer();
  };

  // Esc closes drawer
  React.useEffect(() => {
    if (!drawerOpen) return;
    const onKey = (e) => { if (e.key === 'Escape') onCloseDrawer && onCloseDrawer(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [drawerOpen, onCloseDrawer]);

  return (
    <React.Fragment>
      {isMobile && drawerOpen && (
        <div
          className="shell-drawer-backdrop"
          onClick={onCloseDrawer}
          aria-hidden="true"
        />
      )}
      <aside
        className={'shell-sidebar' + (drawerOpen ? ' is-open' : '')}
        aria-hidden={isMobile && !drawerOpen ? 'true' : undefined}
        style={{
          height: '100vh',
          background: 'var(--surface-card)',
          borderRight: isMobile ? 'none' : '1px solid var(--hairline)',
          display: 'flex', flexDirection: 'column',
          position: isMobile ? 'fixed' : 'sticky',
          top: 0,
          zIndex: isMobile ? 220 : 10,
        }}>
        <div style={{ padding: '20px 18px 14px', display: 'flex', alignItems: 'center', gap: 12 }}>
          <NorwillMark size={42}/>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 17, letterSpacing: '-0.01em', color: 'var(--ink-900)', lineHeight: 1.1 }}>
              Norwill
            </div>
            <div className="eyebrow" style={{ fontSize: 9.5, marginTop: 2 }}>Scorecard OS</div>
          </div>
          {isMobile && (
            <button
              onClick={onCloseDrawer}
              aria-label="Close menu"
              className="btn btn-quiet btn-sm"
              style={{ padding: 8, minHeight: 0 }}
            >
              <Icon.close/>
            </button>
          )}
        </div>

        <nav aria-label="Primary" style={{ padding: '6px 10px', display: 'flex', flexDirection: 'column', gap: 2, flex: 1, overflowY: 'auto' }}>
          {visible.map(v => {
            const active = view === v.id;
            const I = Icon[v.icon];
            const showBadge = v.id === 'feedback' && feedbackAwaiting > 0;
            return (
              <button
                key={v.id}
                onClick={() => pickView(v.id)}
                aria-current={active ? 'page' : undefined}
                style={{
                  display: 'flex', alignItems: 'center', gap: 10,
                  padding: isMobile ? '14px 12px' : '10px 12px',
                  background: active ? 'var(--forest-mist)' : 'transparent',
                  color: active ? 'var(--norwill-forest)' : 'var(--ink-700)',
                  border: 'none', borderRadius: 9,
                  fontSize: isMobile ? 15 : 13.5,
                  fontWeight: active ? 600 : 500,
                  textAlign: 'left',
                  position: 'relative',
                  cursor: 'pointer',
                  minHeight: isMobile ? 48 : undefined,
                  transition: 'background 160ms var(--ease-out), color 160ms var(--ease-out)',
                }}
                onMouseOver={(e) => { if (!active) e.currentTarget.style.background = 'var(--surface-sunk)'; }}
                onMouseOut={(e) => { if (!active) e.currentTarget.style.background = 'transparent'; }}
              >
                {active && (
                  <span aria-hidden="true" style={{
                    position: 'absolute', left: -10, top: 6, bottom: 6,
                    width: 3, borderRadius: '0 3px 3px 0',
                    background: 'var(--norwill-forest)',
                  }}/>
                )}
                <I/>
                <span style={{ flex: 1 }}>{v.label}</span>
                {v.badge && (
                  <span style={{
                    background: 'var(--amber)', color: '#fff',
                    fontSize: 9.5, padding: '2px 7px', borderRadius: 99,
                    fontWeight: 700, letterSpacing: 0.06,
                  }}>{v.badge}</span>
                )}
                {showBadge && (
                  <span style={{
                    background: 'var(--caution)', color: '#fff',
                    fontSize: 10, padding: '1px 6px', borderRadius: 99, fontWeight: 700,
                  }}>{feedbackAwaiting}</span>
                )}
              </button>
            );
          })}
        </nav>

        <div style={{ padding: '6px 10px' }}>
          <FeedbackButton collapsed={false} onClick={() => { onOpenFeedback && onOpenFeedback(); if (isMobile && onCloseDrawer) onCloseDrawer(); }}/>
        </div>

        <QuarterCard/>
      </aside>
    </React.Fragment>
  );
}

function QuarterCard() {
  const q = window.NORWILL_DATA.currentQuarter();
  const w = window.NORWILL_DATA.weekOfQuarter();
  const pct = Math.round(w / 13 * 100);
  return (
    <div style={{ padding: 12 }}>
      <div style={{
        padding: '14px 16px', borderRadius: 12,
        background: 'var(--forest-mist)',
        border: '1px solid rgba(53, 94, 44, 0.12)',
      }}>
        <div className="eyebrow" style={{ color: 'var(--norwill-forest)' }}>{q.label}</div>
        <div style={{
          fontFamily: 'var(--font-display)', fontWeight: 500, letterSpacing: '-0.01em',
          fontSize: 22, color: 'var(--ink-900)', margin: '4px 0 8px',
        }}>
          Week <span className="numeric" style={{ fontFamily: 'var(--font-mono)', fontWeight: 600 }}>{w}</span> of 13
        </div>
        <div style={{ height: 4, background: 'rgba(53, 94, 44, 0.14)', borderRadius: 99, overflow: 'hidden' }}>
          <div style={{ width: pct + '%', height: '100%', background: 'var(--norwill-forest)', transition: 'width 220ms var(--ease-out)' }}/>
        </div>
      </div>
    </div>
  );
}

function ModeToggle({ mode, setMode, compact }) {
  return (
    <div className="mode-toggle" role="radiogroup" aria-label="Workspace mode">
      <button
        type="button"
        role="radio"
        aria-checked={mode === 'working'}
        className={mode === 'working' ? 'active' : ''}
        onClick={() => setMode('working')}
        title="Working mode"
      >
        <Icon.pulse/>
        {!compact && 'Working'}
      </button>
      <button
        type="button"
        role="radio"
        aria-checked={mode === 'meeting'}
        className={mode === 'meeting' ? 'active' : ''}
        onClick={() => setMode('meeting')}
        title="Meeting mode"
      >
        <Icon.users/>
        {!compact && 'Meeting'}
      </button>
    </div>
  );
}

function Topbar({ persona, onOpenTweaks, aiOn, density, mode, setMode, authUser, realAuthUser, onSignOut, onOpenDrawer, drawerBadge }) {
  const isMobile = useMedia('(max-width: 760px)');
  const realRole = realAuthUser ? realAuthUser.role : (authUser ? authUser.role : 'member');
  const canImpersonate = realRole === 'admin' || realRole === 'owner';
  const impersonating = !!authUser?._impersonating;
  const PEOPLE = (window.NORWILL_DATA && window.NORWILL_DATA.PEOPLE) || [];
  const targets = PEOPLE.filter(p => p.status === 'active' && p.id !== (realAuthUser?.personaId));

  function onPick(e) {
    const v = e.target.value;
    if (!window.norwillImpersonation) return;
    if (!v) window.norwillImpersonation.clear();
    else    window.norwillImpersonation.set(v);
  }

  return (
    <header
      data-shell-topbar="true"
      style={{
        minHeight: 64,
        borderBottom: '1px solid var(--hairline)',
        display: 'flex', alignItems: 'center',
        padding: '10px 24px', gap: 12,
        background: 'var(--surface-card)',
        position: 'sticky', top: 0, zIndex: 50,
        flexWrap: 'wrap',
      }}>
      {isMobile && (
        <button
          type="button"
          onClick={onOpenDrawer}
          aria-label="Open menu"
          aria-haspopup="true"
          className="shell-drawer-toggle"
          style={{ position: 'relative' }}
        >
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
            <line x1="3" y1="6" x2="21" y2="6"/>
            <line x1="3" y1="12" x2="21" y2="12"/>
            <line x1="3" y1="18" x2="21" y2="18"/>
          </svg>
          {drawerBadge > 0 && <span className="badge-dot" aria-hidden="true"/>}
        </button>
      )}

      <div style={{ display: 'flex', alignItems: 'center', gap: 8, flex: '0 0 auto' }}>
        <span style={{
          width: 8, height: 8, borderRadius: 99,
          background: impersonating ? 'var(--caution)' : 'var(--summit)',
        }}/>
        <span style={{ fontSize: 12.5, color: 'var(--ink-600)' }}>
          {impersonating ? (isMobile ? 'Acting' : 'Viewing as ') + (isMobile ? '' : (authUser?.name || persona.name)) : 'Live'}
        </span>
      </div>

      {impersonating && !isMobile && (
        <button
          onClick={() => window.norwillImpersonation?.clear()}
          className="btn btn-ghost btn-sm"
          style={{ background: 'var(--caution-bg)', borderColor: 'rgba(181,118,23,0.4)', color: 'var(--caution)' }}
          title={'You are signed in as ' + (realAuthUser?.name || 'admin') + ' — click to exit view'}
        >
          ↩ Exit
        </button>
      )}
      {canImpersonate && !isMobile && (
        <label style={{
          display: 'flex', alignItems: 'center', gap: 6,
          padding: '4px 8px 4px 10px', borderRadius: 9,
          background: 'var(--surface-card)', border: '1px solid var(--hairline)',
          fontSize: 12, color: 'var(--ink-700)', fontWeight: 500,
        }}>
          <span style={{ color: 'var(--ink-500)' }}>View as:</span>
          <select
            value={impersonating ? authUser.personaId : ''}
            onChange={onPick}
            style={{
              border: 'none', background: 'transparent', fontSize: 12,
              fontWeight: 600, color: 'var(--ink-800)', cursor: 'pointer',
              padding: '2px 4px', outline: 'none',
            }}
          >
            <option value="">Self ({realAuthUser?.name || 'admin'})</option>
            {targets.map(p => (
              <option key={p.id} value={p.id}>{p.name} — {p.role}</option>
            ))}
          </select>
        </label>
      )}

      <div style={{ flex: 1 }}/>

      {setMode && <ModeToggle mode={mode} setMode={setMode} compact={isMobile}/>}

      {!isMobile && (
        <div style={{
          display: 'flex', alignItems: 'center', gap: 10, padding: '6px 14px 6px 6px',
          borderRadius: 99, background: 'var(--surface-sunk)',
          border: '1px solid var(--hairline)',
        }}>
          <Avatar person={persona} size={30}/>
          <div style={{ display: 'flex', flexDirection: 'column', lineHeight: 1.15 }}>
            <span style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--ink-900)' }}>
              {authUser ? authUser.name : persona.name}
            </span>
            <span style={{ fontSize: 10.5, color: 'var(--ink-500)' }}>
              {authUser ? authUser.title : persona.role}
            </span>
          </div>
        </div>
      )}
      {isMobile && <Avatar person={persona} size={32}/>}
      {onSignOut && !isMobile && (
        <button onClick={onSignOut} title="Sign out" className="btn btn-ghost btn-sm">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
          Sign out
        </button>
      )}
    </header>
  );
}

function MobileTabBar({ view, setView, authUser }) {
  const all = visibleViews(authUser, null);
  const ordered = MOBILE_TABS
    .map(id => all.find(v => v.id === id))
    .filter(Boolean);
  if (ordered.length === 0) return null;
  return (
    <nav className="shell-bottom-tabs" aria-label="Primary navigation">
      {ordered.map(v => {
        const active = view === v.id;
        const I = Icon[v.icon];
        return (
          <button
            key={v.id}
            type="button"
            className={'tab' + (active ? ' active' : '')}
            onClick={() => setView(v.id)}
            aria-current={active ? 'page' : undefined}
          >
            <I/>
            <span>{MOBILE_TAB_LABELS[v.id] || v.label.split(' ')[0]}</span>
          </button>
        );
      })}
    </nav>
  );
}

function TweaksPanel({ open, onClose, state, setState }) {
  return (
    <div className={'tweaks-panel' + (open ? ' open' : '')}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 6 }}>
        <h4 style={{margin:0}}>Tweaks</h4>
        <button onClick={onClose} style={{ background: 'none', border: 'none', color: 'var(--ink-500)', cursor: 'pointer' }}><Icon.close/></button>
      </div>
      <div className="tweak-row">
        <label>Theme</label>
        <select value={state.theme} onChange={(e) => setState({...state, theme: e.target.value})}>
          <option value="light">Light</option>
          <option value="dark">Dark</option>
        </select>
      </div>
      <div className="tweak-row">
        <label>Density</label>
        <select value={state.density} onChange={(e) => setState({...state, density: e.target.value})}>
          <option value="comfortable">Comfortable</option>
          <option value="compact">Compact</option>
        </select>
      </div>
      <div style={{ fontSize: 11, color: 'var(--ink-500)', marginTop: 10, lineHeight: 1.5 }}>
        Theme and density are per-device preferences. Saved automatically.
      </div>
    </div>
  );
}

Object.assign(window, { Sidebar, Topbar, TweaksPanel, MobileTabBar, ModeToggle, VIEWS });
