/* Sidebar — focuses on the current top-nav section.
   Top bar handles primary navigation; sidebar shows section-specific content. */

const SIDEBAR_DEFAULT_LAYOUT = {
  workspace: [],
  reports: [],
  activity: [],
};

function useSidebarLayout() {
  const [layout, setLayout] = React.useState(() => {
    try {
      const stored = JSON.parse(localStorage.getItem('tashhub-sidebar-layout') || 'null');
      if (stored) return { ...SIDEBAR_DEFAULT_LAYOUT, ...stored };
    } catch (e) {}
    return SIDEBAR_DEFAULT_LAYOUT;
  });
  const persist = (next) => { setLayout(next); try { localStorage.setItem('tashhub-sidebar-layout', JSON.stringify(next)); } catch (e) {} };
  return [layout, persist];
}

function Sidebar({ activeView, onView, filters, onToggleFilter, onOpenSettings, savedViews = [], onApplySavedView, onDeleteSavedView }) {
  const section =
    activeView === 'queues' || activeView.startsWith('queue:') ? 'queues' :
    activeView === 'workspace'  ? 'workspace' :
    activeView === 'dashboards' || activeView === 'reports' || ['dashboard','workload','time','audit'].includes(activeView) ? 'dashboards' :
    activeView === 'settings'   ? 'settings' :
    'my-work';

  return (
    <aside style={{
      width: 248, flexShrink: 0,
      borderRight: '1px solid rgb(var(--rule))',
      display: 'flex', flexDirection: 'column',
      background: 'rgb(var(--bg))',
      overflow: 'hidden',
    }}>
      <nav style={{ flex: 1, overflowY: 'auto', padding: '12px 8px 10px' }}>
        {section === 'my-work'   && <MyWorkSidebar    activeView={activeView} onView={onView} savedViews={savedViews} onApplySavedView={onApplySavedView} onDeleteSavedView={onDeleteSavedView} filters={filters} onToggleFilter={onToggleFilter} />}
        {section === 'queues'    && <QueuesSidebar    activeView={activeView} onView={onView} filters={filters} onToggleFilter={onToggleFilter} />}
        {section === 'workspace' && <WorkspaceSidebar activeView={activeView} onView={onView} filters={filters} onToggleFilter={onToggleFilter} />}
        {section === 'dashboards'&& <DashboardsSidebar activeView={activeView} onView={onView} />}
        {section === 'reports'   && <ReportsSidebar    activeView={activeView} onView={onView} />}
        {section === 'settings'  && <SettingsSidebar   activeView={activeView} onView={onView} />}
      </nav>

      <div style={{
        borderTop: '1px solid rgb(var(--rule))', padding: '10px 12px',
        display: 'flex', alignItems: 'center', gap: 10, background: 'rgb(var(--surface))',
      }}>
        <Avatar user={userById(1)} size={28} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 12.5, fontWeight: 600, color: 'rgb(var(--ink))' }}>Alex Harley</div>
          <div style={{ fontSize: 10.5, color: 'rgb(var(--muted))', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>billing@harleymindcare.com</div>
        </div>
        <button onClick={onOpenSettings} title="Settings"
          style={{ fontSize: 15, color: 'rgb(var(--muted))', padding: '4px 6px', borderRadius: 6, lineHeight: 1 }}>⋯</button>
      </div>
    </aside>
  );
}

function sectionGlyph(s) { return { 'my-work':'◉', queues:'☰', workspace:'◐', dashboards:'◇', reports:'⊟', settings:'⚙' }[s] || '◉'; }
function sectionLabel(s) { return { 'my-work':'My Work', queues:'Queues', workspace:'Workspace', dashboards:'Dashboards', reports:'Reports', settings:'Settings' }[s] || 'My Work'; }
function sectionSub(s)   { return { 'my-work':'Your personal queue', queues:'Team inboxes', workspace:'Spaces · statuses · members', dashboards:'Pinned & custom', reports:'Analytics', settings:'Profile & workspace' }[s] || ''; }

function MyWorkSidebar({ activeView, onView, savedViews, onApplySavedView, onDeleteSavedView, filters, onToggleFilter }) {
  return (
    <>
      <p className="eyebrow" style={{ fontSize: 9.5, padding: '0 10px 8px', margin: 0 }}>Quick views</p>
      {[
        ['my-day',    'My Day',    '☀'],
        ['important', 'Important', '★'],
        ['mentions',  'Mentions',  '@'],
        ['planned',   'Planned',   '◳'],
        ['all',       'All Tasks', '⊞'],
        ['snoozed',   'Snoozed',   '◴'],
        ['archived',  'Archived',  '◰'],
      ].map(([k, lbl, g]) => (
        <NavLink key={k} active={activeView === k} onClick={() => onView(k)} glyph={g} label={lbl} sub />
      ))}
      <div style={{ height: 1, background: 'rgb(var(--rule))', margin: '10px 8px' }} />
      <PulseSection />
      <NavLink active={activeView === 'my-work'} onClick={() => onView('my-work')} glyph="◉" label="Overview" />
      <NavLink active={activeView === 'views'}   onClick={() => onView('views')}   glyph="◇" label="Views hub" />
      <div style={{ height: 1, background: 'rgb(var(--rule))', margin: '10px 8px' }} />
      <MyWorkWorkspacePicker />
      {savedViews.length > 0 && <SavedViewsSection savedViews={savedViews} onApply={onApplySavedView} onDelete={onDeleteSavedView} />}
      <TagsSection filters={filters} onToggleFilter={onToggleFilter} />
    </>
  );
}

function MyWorkWorkspacePicker() {
  const [ws, setWs] = React.useState(() => {
    try {
      const v = localStorage.getItem('tashhub-mywork-ws');
      if (v === null) return [1];
      const parsed = JSON.parse(v);
      return Array.isArray(parsed) ? parsed : [parsed];
    } catch (e) { return [1]; }
  });
  const persist = (next) => { setWs(next); try { localStorage.setItem('tashhub-mywork-ws', JSON.stringify(next)); } catch (e) {} };
  const toggleWs = (id) => persist(ws.includes(id) ? ws.filter(x => x !== id) : [...ws, id]);
  const [open, setOpen] = React.useState(false);
  const label = ws.length === 0 ? 'All workspaces' : ws.length === 1 ? (WORKSPACES.find(w => w.id === ws[0])?.name || '—') : `${ws.length} workspaces`;
  return (
    <div style={{ padding: '0 10px 14px', position: 'relative' }}>
      <p style={{ margin: '0 0 6px', fontSize: 9.5, fontWeight: 700, color: 'rgb(var(--muted))', letterSpacing: '0.06em', textTransform: 'uppercase' }}>Workspace</p>
      <button onClick={() => setOpen(o => !o)} style={{
        display: 'flex', alignItems: 'center', gap: 8,
        width: '100%', padding: '6px 10px',
        background: 'rgb(var(--surface))', border: '1px solid rgb(var(--rule))',
        borderRadius: 8, fontSize: 12, fontWeight: 500, color: 'rgb(var(--ink))',
        textAlign: 'left',
      }}>
        <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{label}</span>
        <span style={{ fontSize: 10, color: 'rgb(var(--muted))' }}>▾</span>
      </button>
      {open && (
        <>
          <span onClick={() => setOpen(false)} style={{ position: 'fixed', inset: 0, zIndex: 60 }} />
          <div className="shadow-pop fadein" style={{
            position: 'absolute', top: '100%', left: 10, right: 10, marginTop: 4,
            background: 'rgb(var(--surface))', border: '1px solid rgb(var(--rule))',
            borderRadius: 10, padding: 4, zIndex: 61,
          }}>
            <button onClick={() => persist([])} style={{
              display: 'flex', alignItems: 'center', gap: 9, width: '100%',
              padding: '6px 10px', borderRadius: 6, fontSize: 12, textAlign: 'left',
              background: ws.length === 0 ? 'rgb(var(--accent-soft))' : 'transparent',
              color: ws.length === 0 ? 'rgb(var(--accent-2))' : 'rgb(var(--ink-2))',
              fontWeight: ws.length === 0 ? 700 : 500,
            }}
              onMouseEnter={e => { if (ws.length !== 0) e.currentTarget.style.background = 'rgb(var(--paper-2))'; }}
              onMouseLeave={e => { if (ws.length !== 0) e.currentTarget.style.background = 'transparent'; }}>
              <span style={{ width: 14 }}>{ws.length === 0 ? '✓' : ''}</span>
              All workspaces
            </button>
            <div style={{ height: 1, background: 'rgb(var(--rule))', margin: '3px 4px' }} />
            {WORKSPACES.map(w => {
              const on = ws.includes(w.id);
              return (
                <button key={w.id} onClick={() => toggleWs(w.id)} style={{
                  display: 'flex', alignItems: 'center', gap: 9, width: '100%',
                  padding: '6px 10px', borderRadius: 6, fontSize: 12, textAlign: 'left',
                  fontWeight: on ? 600 : 500, color: 'rgb(var(--ink-2))',
                }}
                  onMouseEnter={e => e.currentTarget.style.background = 'rgb(var(--paper-2))'}
                  onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                  <span style={{
                    width: 14, height: 14, borderRadius: 4,
                    background: on ? 'rgb(var(--accent))' : 'transparent',
                    border: '1.5px solid ' + (on ? 'rgb(var(--accent))' : 'rgb(var(--rule-2))'),
                    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                    color: 'white', fontSize: 10, fontWeight: 700,
                  }}>{on && '✓'}</span>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div>{w.name}</div>
                    <div style={{ fontSize: 10.5, color: 'rgb(var(--muted))' }}>{w.sub}</div>
                  </div>
                </button>
              );
            })}
          </div>
        </>
      )}
    </div>
  );
}

function SidebarSpaces({ filters, onToggleFilter }) {
  return (
    <div style={{ marginBottom: 14 }}>
      <p className="eyebrow" style={{ fontSize: 9.5, padding: '0 10px 8px', margin: 0 }}>Spaces</p>
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, padding: '2px 6px 0' }}>
        {D.spaces.map(sp => {
          const active = filters.spaces.includes(sp.id);
          const cnt = D.tasks.filter(t => t.spaceId === sp.id && t.statusId !== 6).length;
          return (
            <button key={sp.id} onClick={() => onToggleFilter('spaces', sp.id)} style={{
              display: 'inline-flex', alignItems: 'center', gap: 5,
              fontSize: 10.5, fontWeight: 500, padding: '3px 9px',
              background: active ? sp.colour + '14' : 'rgb(var(--paper-2) / 0.5)',
              color: active ? sp.colour : 'rgb(var(--ink-2))',
              border: `1px solid ${active ? sp.colour + '60' : 'transparent'}`,
              borderRadius: 999,
            }}>
              <span style={{ width: 6, height: 6, background: sp.colour, borderRadius: 2 }} />
              {sp.name}
              <span style={{ opacity: 0.6 }}>{cnt}</span>
            </button>
          );
        })}
      </div>
    </div>
  );
}

const WORKSPACES = [
  { id: 1, name: 'Harley Mindcare',   sub: 'Clinical' },
  { id: 2, name: 'Mindcare Research', sub: 'Pilots'    },
  { id: 3, name: 'Personal',          sub: 'You'       },
];

function QueuesSidebar({ activeView, onView, filters, onToggleFilter }) {
  const [ws, setWs] = React.useState(() => {
    try {
      const v = localStorage.getItem('tashhub-queue-ws');
      if (v === null) return [1];
      if (v === 'all') return [];
      const parsed = JSON.parse(v);
      return Array.isArray(parsed) ? parsed : [parsed];
    } catch (e) { return [1]; }
  });
  const persist = (next) => { setWs(next); try { localStorage.setItem('tashhub-queue-ws', JSON.stringify(next)); } catch (e) {} };
  const toggleWs = (id) => persist(ws.includes(id) ? ws.filter(x => x !== id) : [...ws, id]);
  const [open, setOpen] = React.useState(false);

  const queues = (window.__liveQueues || D.queues).filter(q => ws.length === 0 || ws.includes(q.workspaceId || 1));

  const label = ws.length === 0 ? 'All workspaces'
              : ws.length === 1 ? (WORKSPACES.find(w => w.id === ws[0])?.name || '—')
              : `${ws.length} workspaces`;

  return (
    <>
      <div style={{ padding: '8px 10px 6px', position: 'relative' }}>
        <p style={{ margin: '0 0 6px', fontSize: 9.5, fontWeight: 700, color: 'rgb(var(--muted))', letterSpacing: '0.06em', textTransform: 'uppercase' }}>Workspace</p>
        <button onClick={() => setOpen(o => !o)} style={{
          display: 'flex', alignItems: 'center', gap: 8,
          width: '100%', padding: '6px 10px',
          background: 'rgb(var(--surface))', border: '1px solid rgb(var(--rule))',
          borderRadius: 8, fontSize: 12, fontWeight: 500, color: 'rgb(var(--ink))',
          textAlign: 'left',
        }}>
          <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{label}</span>
          <span style={{ fontSize: 10, color: 'rgb(var(--muted))' }}>▾</span>
        </button>
        {open && (
          <>
            <span onClick={() => setOpen(false)} style={{ position: 'fixed', inset: 0, zIndex: 60 }} />
            <div className="shadow-pop fadein" style={{
              position: 'absolute', top: '100%', left: 10, right: 10, marginTop: 4,
              background: 'rgb(var(--surface))', border: '1px solid rgb(var(--rule))',
              borderRadius: 10, padding: 4, zIndex: 61,
            }}>
              <button onClick={() => { persist([]); }} style={{
                display: 'flex', alignItems: 'center', gap: 9, width: '100%',
                padding: '6px 10px', borderRadius: 6, fontSize: 12, textAlign: 'left',
                background: ws.length === 0 ? 'rgb(var(--accent-soft))' : 'transparent',
                color: ws.length === 0 ? 'rgb(var(--accent-2))' : 'rgb(var(--ink-2))',
                fontWeight: ws.length === 0 ? 700 : 500,
              }}
                onMouseEnter={e => { if (ws.length !== 0) e.currentTarget.style.background = 'rgb(var(--paper-2))'; }}
                onMouseLeave={e => { if (ws.length !== 0) e.currentTarget.style.background = 'transparent'; }}>
                <span style={{ width: 14 }}>{ws.length === 0 ? '✓' : ''}</span>
                All workspaces
              </button>
              <div style={{ height: 1, background: 'rgb(var(--rule))', margin: '3px 4px' }} />
              {WORKSPACES.map(w => {
                const on = ws.includes(w.id);
                return (
                  <button key={w.id} onClick={() => toggleWs(w.id)} style={{
                    display: 'flex', alignItems: 'center', gap: 9, width: '100%',
                    padding: '6px 10px', borderRadius: 6, fontSize: 12, textAlign: 'left',
                    fontWeight: on ? 600 : 500, color: 'rgb(var(--ink-2))',
                  }}
                    onMouseEnter={e => e.currentTarget.style.background = 'rgb(var(--paper-2))'}
                    onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                    <span style={{
                      width: 14, height: 14, borderRadius: 4,
                      background: on ? 'rgb(var(--accent))' : 'transparent',
                      border: '1.5px solid ' + (on ? 'rgb(var(--accent))' : 'rgb(var(--rule-2))'),
                      display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                      color: 'white', fontSize: 10, fontWeight: 700,
                    }}>{on && '✓'}</span>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div>{w.name}</div>
                      <div style={{ fontSize: 10.5, color: 'rgb(var(--muted))' }}>{w.sub}</div>
                    </div>
                  </button>
                );
              })}
            </div>
          </>
        )}
      </div>

      <div style={{ height: 1, background: 'rgb(var(--rule))', margin: '6px 8px' }} />
      <p className="eyebrow" style={{ fontSize: 9.5, padding: '0 10px 8px', margin: 0 }}>
        Team queues {ws.length > 0 && ws.length < WORKSPACES.length && <span style={{ color: 'rgb(var(--accent))' }}>· {label}</span>}
      </p>
      {queues.length === 0 && (
        <p style={{ margin: 0, padding: '6px 10px', fontSize: 11, color: 'rgb(var(--muted))', fontStyle: 'italic' }}>No queues in this workspace yet.</p>
      )}
      {queues.map(q => {
        const active = activeView === `queue:${q.id}`;
        return (
          <button key={q.id} onClick={() => onView(`queue:${q.id}`)} style={{
            display: 'flex', alignItems: 'center', gap: 9,
            width: '100%', padding: '6px 10px', marginBottom: 2, borderRadius: 8,
            background: active ? q.colour + '14' : 'transparent',
            color: active ? q.colour : 'rgb(var(--ink-2))',
            fontWeight: active ? 600 : 500,
            border: '1px solid ' + (active ? q.colour + '40' : 'transparent'),
          }}
            onMouseEnter={e => { if (!active) e.currentTarget.style.background = 'rgb(var(--paper-2) / 0.5)'; }}
            onMouseLeave={e => { if (!active) e.currentTarget.style.background = 'transparent'; }}>
            <span style={{ width: 8, height: 8, background: q.colour, borderRadius: '50%' }} />
            <span style={{ fontSize: 12.5, flex: 1, textAlign: 'left' }}>{q.name}</span>
            <span style={{ fontSize: 10.5, color: 'rgb(var(--muted))' }}>{q.count}</span>
          </button>
        );
      })}
      <div style={{ padding: '6px 10px', marginTop: 4, marginBottom: 14 }}>
        <button className="btn btn-secondary" style={{ fontSize: 11.5, width: '100%' }}>+ New queue</button>
      </div>
    </>
  );
}

function WorkspaceSidebar({ activeView, onView, filters, onToggleFilter }) {
  return (
    <>
      <NavLink active={activeView === 'workspace'} onClick={() => onView('workspace')} glyph="◐" label="Overview" />
      <div style={{ height: 1, background: 'rgb(var(--rule))', margin: '10px 8px' }} />
      <p className="eyebrow" style={{ fontSize: 9.5, padding: '0 10px 8px', margin: 0 }}>Spaces</p>
      {D.spaces.map(sp => {
        const active = filters.spaces.includes(sp.id);
        const cnt = D.tasks.filter(t => t.spaceId === sp.id && t.statusId !== 6).length;
        return (
          <button key={sp.id} onClick={() => onToggleFilter('spaces', sp.id)} style={{
            display: 'flex', alignItems: 'center', gap: 9,
            width: '100%', padding: '5px 10px', marginBottom: 1, borderRadius: 8,
            background: active ? 'rgb(var(--paper-2))' : 'transparent',
            fontWeight: active ? 600 : 500,
          }}
            onMouseEnter={e => { if (!active) e.currentTarget.style.background = 'rgb(var(--paper-2) / 0.5)'; }}
            onMouseLeave={e => { if (!active) e.currentTarget.style.background = 'transparent'; }}>
            <span style={{ width: 8, height: 8, background: sp.colour, borderRadius: 3 }} />
            <span style={{ fontSize: 12.5, flex: 1, textAlign: 'left' }}>{sp.name}</span>
            <span className="num" style={{ fontSize: 10.5, color: 'rgb(var(--muted))' }}>{cnt}</span>
          </button>
        );
      })}
      <p className="eyebrow" style={{ fontSize: 9.5, padding: '14px 10px 8px', margin: 0 }}>Statuses</p>
      {D.statuses.map(s => (
        <div key={s.id} style={{ display: 'flex', alignItems: 'center', gap: 9, padding: '4px 10px', fontSize: 12, color: 'rgb(var(--ink-2))' }}>
          <span className="pip" style={{ background: s.colour }} />
          <span style={{ flex: 1 }}>{s.title}</span>
          <span style={{ fontSize: 10.5, color: 'rgb(var(--muted))' }}>{D.tasks.filter(t => t.statusId === s.id).length}</span>
        </div>
      ))}
    </>
  );
}

function DashboardsSidebar({ activeView, onView }) {
  return (
    <>
      <NavLink active={activeView === 'dashboards'} onClick={() => onView('dashboards')} glyph="◇" label="All dashboards" />
      <div style={{ height: 1, background: 'rgb(var(--rule))', margin: '10px 8px' }} />
      <p className="eyebrow" style={{ fontSize: 9.5, padding: '0 10px 8px', margin: 0 }}>Pinned</p>
      <NavLink active={false} onClick={() => onView('dashboards')} glyph="☀" label="My Focus" sub />
      <NavLink active={false} onClick={() => onView('dashboards')} glyph="◐" label="Team Pulse" sub />
      <NavLink active={false} onClick={() => onView('dashboards')} glyph="◉" label="Practice manager" sub />
      <div style={{ padding: '8px 10px 12px' }}>
        <button className="btn btn-secondary" style={{ fontSize: 11.5, width: '100%' }}>+ New dashboard</button>
      </div>
      <div style={{ height: 1, background: 'rgb(var(--rule))', margin: '6px 8px 10px' }} />
      <p className="eyebrow" style={{ fontSize: 9.5, padding: '0 10px 8px', margin: 0 }}>Reports</p>
      <NavLink active={activeView === 'reports'}   onClick={() => onView('reports')}   glyph="⊟" label="Overview" sub />
      <NavLink active={activeView === 'dashboard'} onClick={() => onView('dashboard')} glyph="◐" label="KPIs & trends" sub />
      <NavLink active={activeView === 'workload'}  onClick={() => onView('workload')}  glyph="⊟" label="Workload" sub />
      <NavLink active={activeView === 'time'}      onClick={() => onView('time')}      glyph="⏱" label="Time tracking" sub />
      <NavLink active={activeView === 'audit'}     onClick={() => onView('audit')}     glyph="⌬" label="Audit log" sub />
    </>
  );
}

function ReportsSidebar({ activeView, onView }) {
  return (
    <>
      <NavLink active={activeView === 'reports'}  onClick={() => onView('reports')}  glyph="⊟" label="Reports overview" />
      <div style={{ height: 1, background: 'rgb(var(--rule))', margin: '10px 8px' }} />
      <p className="eyebrow" style={{ fontSize: 9.5, padding: '0 10px 8px', margin: 0 }}>Reports</p>
      <NavLink active={activeView === 'dashboard'} onClick={() => onView('dashboard')} glyph="◐" label="KPIs & trends" sub />
      <NavLink active={activeView === 'workload'}  onClick={() => onView('workload')}  glyph="⊟" label="Workload" sub />
      <NavLink active={activeView === 'time'}      onClick={() => onView('time')}      glyph="⏱" label="Time tracking" sub />
      <NavLink active={activeView === 'audit'}     onClick={() => onView('audit')}     glyph="⌬" label="Audit log" sub />
    </>
  );
}

function SettingsSidebar({ activeView, onView }) {
  return (
    <>
      <NavLink active onClick={() => onView('settings')} glyph="⚙" label="Open settings" />
      <p style={{ margin: '12px 10px 0', fontSize: 11.5, color: 'rgb(var(--muted))' }}>Settings are managed in the main pane — use the sub-nav inside to switch sections.</p>
    </>
  );
}

function NavLink({ active, onClick, glyph, label, sub = false }) {
  return (
    <button onClick={onClick} style={{
      display: 'flex', alignItems: 'center', gap: 10,
      width: '100%', padding: sub ? '4px 10px' : '7px 10px', marginBottom: 2, borderRadius: 8,
      fontSize: sub ? 12 : 13, fontWeight: active ? 700 : 500,
      color: active ? 'rgb(var(--accent-2))' : 'rgb(var(--ink-2))',
      background: active ? 'rgb(var(--accent-soft))' : 'transparent',
    }}
      onMouseEnter={e => { if (!active) e.currentTarget.style.background = 'rgb(var(--paper-2))'; }}
      onMouseLeave={e => { if (!active) e.currentTarget.style.background = 'transparent'; }}>
      <span style={{ fontSize: sub ? 11 : 12, width: 14, textAlign: 'center', color: active ? 'rgb(var(--accent))' : 'rgb(var(--muted))' }}>{glyph}</span>
      <span style={{ flex: 1, textAlign: 'left' }}>{label}</span>
    </button>
  );
}

function PulseSection() {
  const active   = D.tasks.filter(t => t.statusId !== 6 && !t.snoozedUntil).length;
  const overdue  = D.tasks.filter(t => t.dueDate && dayDelta(t.dueDate) < 0 && t.statusId !== 6).length;
  const myDay    = D.tasks.filter(t => t.myDay).length;
  return (
    <div style={{
      margin: '4px 4px 16px', padding: 11,
      background: 'rgb(var(--surface))', border: '1px solid rgb(var(--rule))',
      borderRadius: 10, boxShadow: 'var(--sh-sm)',
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 6 }}>
        <span style={{ width: 6, height: 6, background: 'rgb(var(--forest))', borderRadius: '50%', animation: 'pulse-dot 1.6s infinite' }} />
        <p className="eyebrow" style={{ fontSize: 9.5, margin: 0 }}>Today's pulse</p>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 6 }}>
        <PulseStat label="Active"  n={active}  tone="ink" />
        <PulseStat label="Overdue" n={overdue} tone={overdue > 0 ? 'brick' : 'ink'} />
        <PulseStat label="My Day"  n={myDay}   tone="warm" />
      </div>
    </div>
  );
}

function PulseStat({ label, n, tone }) {
  const colour =
    tone === 'brick'  ? 'rgb(var(--brick))' :
    tone === 'warm'   ? 'rgb(var(--warm))' :
                        'rgb(var(--ink))';
  return (
    <div>
      <div style={{ fontSize: 9, color: 'rgb(var(--muted))' }}>{label}</div>
      <div className="num" style={{ fontSize: 16, fontWeight: 700, color: colour, letterSpacing: '-0.02em' }}>{n}</div>
    </div>
  );
}

function TagsSection({ filters, onToggleFilter }) {
  return (
    <SectionHeader title="Tags">
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4, padding: '2px 6px 0' }}>
        {D.tags.map(t => {
          const active = filters.tags.includes(t.id);
          return (
            <button key={t.id} onClick={() => onToggleFilter('tags', t.id)} style={{
              display: 'inline-flex', alignItems: 'center', gap: 5,
              fontSize: 10.5, fontWeight: 500, padding: '3px 9px',
              background: active ? t.colour + '24' : t.colour + '14',
              color: t.colour,
              border: `1px solid ${active ? t.colour + '60' : 'transparent'}`,
              borderRadius: 999,
            }}>
              <span style={{ width: 5, height: 5, background: t.colour, borderRadius: '50%' }} />
              {t.name}
              <span style={{ opacity: 0.6 }}>{t.count}</span>
            </button>
          );
        })}
      </div>
    </SectionHeader>
  );
}

function SavedViewsSection({ savedViews, onApply, onDelete }) {
  return (
    <SectionHeader title="Saved views">
      {savedViews.map(v => (
        <div key={v.id} style={{
          display: 'flex', alignItems: 'center', gap: 8,
          padding: '4px 10px', marginBottom: 1, borderRadius: 8,
        }}
          onMouseEnter={e => e.currentTarget.style.background = 'rgb(var(--paper-2) / 0.6)'}
          onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
          <button onClick={() => onApply?.(v)} style={{
            display: 'flex', alignItems: 'center', gap: 8,
            flex: 1, minWidth: 0, textAlign: 'left',
            fontSize: 12, fontWeight: 500, color: 'rgb(var(--ink-2))',
          }}>
            <span style={{ fontSize: 11, color: 'rgb(var(--accent))' }}>{v.pinned ? '📌' : '◆'}</span>
            <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{v.name}</span>
          </button>
          <button onClick={() => onDelete?.(v.id)} title="Delete" style={{
            fontSize: 12, color: 'rgb(var(--muted))', padding: '0 4px', borderRadius: 4, opacity: 0.45,
          }}
            onMouseEnter={e => { e.currentTarget.style.opacity = '1'; e.currentTarget.style.color = 'rgb(var(--brick))'; }}
            onMouseLeave={e => { e.currentTarget.style.opacity = '0.45'; e.currentTarget.style.color = 'rgb(var(--muted))'; }}>×</button>
        </div>
      ))}
    </SectionHeader>
  );
}

function SectionHeader({ title, children, action }) {
  return (
    <div style={{ marginBottom: 14 }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0 10px 6px' }}>
        <p className="eyebrow" style={{ fontSize: 9.5, margin: 0 }}>{title}</p>
        {action && <span style={{ fontSize: 10, color: 'rgb(var(--muted))' }}>{action}</span>}
      </div>
      {children}
    </div>
  );
}

window.Sidebar = Sidebar;
