// Dashboard — editable widget grid with drag/drop, widget library, customization

const DEFAULT_LAYOUT = [
  { id: 'kpi_pipeline', w: 1 },
  { id: 'kpi_wonMonth', w: 1 },
  { id: 'kpi_cash', w: 1 },
  { id: 'kpi_ar', w: 1 },
  { id: 'pipeline_chart', w: 2 },
  { id: 'finance_attention', w: 2 },
  { id: 'activity_feed', w: 2 },
  { id: 'renewals_upcoming', w: 2 },
  { id: 'headcount_dept', w: 2 },
  { id: 'top_deals', w: 2 },
];

function Dashboard({ user, onNavigate, onQuickCreate, onDailySummary }) {
  const D = window.HitcentsData;
  const [layout, setLayout] = useState(() => {
    try {
      const saved = localStorage.getItem('hc-dashboard-layout');
      if (saved) return JSON.parse(saved);
    } catch {}
    return DEFAULT_LAYOUT;
  });
  const [editMode, setEditMode] = useState(false);
  const [libraryOpen, setLibraryOpen] = useState(false);
  const [drag, setDrag] = useState(null);
  const [hoverIdx, setHoverIdx] = useState(null);

  useEffect(() => {
    localStorage.setItem('hc-dashboard-layout', JSON.stringify(layout));
  }, [layout]);

  function removeWidget(id) {
    setLayout(l => l.filter(x => x.id !== id));
  }
  function setWidth(id, w) {
    setLayout(l => l.map(x => x.id === id ? { ...x, w } : x));
  }
  function addWidget(id) {
    const meta = WIDGET_CATALOG[id];
    setLayout(l => [...l, { id, w: meta.defaultWidth }]);
  }
  function reset() {
    if (confirm('Reset dashboard to default layout?')) {
      setLayout(DEFAULT_LAYOUT);
    }
  }

  // DnD reorder
  function handleDrop(targetIdx) {
    if (drag == null) return;
    setLayout(l => {
      const out = l.slice();
      const [moved] = out.splice(drag, 1);
      const insertAt = targetIdx > drag ? targetIdx - 1 : targetIdx;
      out.splice(insertAt, 0, moved);
      return out;
    });
    setDrag(null);
    setHoverIdx(null);
  }

  const addedIds = new Set(layout.map(x => x.id));

  return (
    <div data-screen-label="Dashboard">
      <div className="page-head">
        <div>
          <h1>{editMode ? 'Customize your dashboard' : `Good morning, ${user.name.split(' ')[0]}`}</h1>
          <div className="sub">
            {editMode
              ? 'Drag widgets to reorder · click size buttons to resize · remove with the × · add more from the library'
              : `Friday, May 15, 2026 · ${NAV_SECTIONS.length} workspaces · 28 teammates online`}
          </div>
        </div>
        <div className="row gap-2">
          {editMode ? (
            <>
              <Button variant="ghost" icon="x" onClick={reset}>Reset</Button>
              <Button variant="secondary" icon="plus" onClick={() => setLibraryOpen(true)}>Add widget</Button>
              <Button variant="primary" icon="check" onClick={() => setEditMode(false)}>Done</Button>
            </>
          ) : (
            <>
              <Button variant="secondary" icon="pencil" onClick={() => setEditMode(true)}>Customize</Button>
            </>
          )}
        </div>
      </div>

      <div className={`dash-grid ${editMode ? 'edit-mode' : ''}`}>
        {layout.map((item, i) => {
          const meta = WIDGET_CATALOG[item.id];
          if (!meta) return null;
          const isDragging = drag === i;
          const showHoverLine = editMode && hoverIdx === i && drag != null && drag !== i;
          return (
            <React.Fragment key={item.id}>
              {showHoverLine && <div className="dash-drop-indicator" style={{ gridColumn: `span ${item.w}` }} />}
              <div
                draggable={editMode}
                onDragStart={() => setDrag(i)}
                onDragOver={editMode ? (e) => { e.preventDefault(); setHoverIdx(i); } : undefined}
                onDragEnd={() => { setDrag(null); setHoverIdx(null); }}
                onDrop={editMode ? () => handleDrop(i) : undefined}
                className={`dash-widget ${isDragging ? 'dragging' : ''}`}
                style={{ gridColumn: `span ${item.w}` }}>
                {editMode && (
                  <div className="dash-widget-chrome">
                    <div className="dash-widget-drag"><Icon name="drag" size={12} /></div>
                    <span className="dash-widget-name">{meta.name}</span>
                    <div className="row gap-1" style={{ marginLeft: 'auto' }}>
                      <div className="dash-width-toggle">
                        {[1,2,3,4].map(w => (
                          <button key={w} onClick={() => setWidth(item.id, w)}
                                  className={item.w === w ? 'active' : ''}
                                  title={`Span ${w} column${w === 1 ? '' : 's'}`}>{w}</button>
                        ))}
                      </div>
                      <button className="icon-btn" onClick={() => removeWidget(item.id)} title="Remove">
                        <Icon name="x" size={12} />
                      </button>
                    </div>
                  </div>
                )}
                <div className="dash-widget-body">
                  {meta.render({ onNavigate, user })}
                </div>
              </div>
            </React.Fragment>
          );
        })}

        {/* Drop indicator at end */}
        {editMode && hoverIdx === layout.length && drag != null && (
          <div className="dash-drop-indicator" style={{ gridColumn: 'span 4' }} />
        )}

        {/* Drop zone at end */}
        {editMode && (
          <div
            onDragOver={(e) => { e.preventDefault(); setHoverIdx(layout.length); }}
            onDrop={() => handleDrop(layout.length)}
            onClick={() => setLibraryOpen(true)}
            className="dash-add-tile"
            style={{ gridColumn: 'span 2' }}>
            <Icon name="plus" size={20} />
            <span>Add widget</span>
          </div>
        )}
      </div>

      {libraryOpen && <WidgetLibrary onClose={() => setLibraryOpen(false)} onAdd={(id) => { addWidget(id); setLibraryOpen(false); }} addedIds={addedIds} />}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// Widget catalog
// ─────────────────────────────────────────────────────────────────────────────

function Kpi({ label, value, delta, tone, onClick }) {
  return (
    <div className="kpi-inner" onClick={onClick} style={{ cursor: onClick ? 'pointer' : 'default' }}>
      <div className="label">{label}</div>
      <div className="value">{value}</div>
      {delta && (
        <div className={`delta ${tone || ''}`}>
          {tone === 'up' && <Icon name="arrow_u" size={11} />}
          {tone === 'down' && <Icon name="arrow_d" size={11} />}
          {delta}
        </div>
      )}
    </div>
  );
}

const WIDGET_CATALOG = {
  // ────────────── KPIs ──────────────
  kpi_pipeline: {
    id: 'kpi_pipeline', name: 'Open pipeline', group: 'KPIs', defaultWidth: 1, icon: 'card',
    description: 'Total value of deals not yet won or lost.',
    render: ({ onNavigate }) => {
      const D = window.HitcentsData;
      const v = D.DEALS.filter(d => !['won','lost'].includes(d.stage)).reduce((s,d) => s + d.value, 0);
      return <Kpi label="Open pipeline" value={fmtMoney(v)} delta="+8.4% wk over wk" tone="up" onClick={() => onNavigate('crm')} />;
    }
  },
  kpi_wonMonth: {
    id: 'kpi_wonMonth', name: 'Closed won this month', group: 'KPIs', defaultWidth: 1, icon: 'star',
    description: 'Won deals in the current month.',
    render: ({ onNavigate }) => {
      const D = window.HitcentsData;
      const v = D.DEALS.filter(d => d.stage === 'won').reduce((s,d) => s + d.value, 0);
      return <Kpi label="Closed won — May" value={fmtMoney(v)} delta="1 deal · Marigold" tone="up" onClick={() => onNavigate('crm')} />;
    }
  },
  kpi_cash: {
    id: 'kpi_cash', name: 'Cash on hand', group: 'KPIs', defaultWidth: 1, icon: 'card',
    description: 'Total balance across cash accounts.',
    render: ({ onNavigate }) => {
      const D = window.HitcentsData;
      const v = D.FIN_BANK_ACCOUNTS.filter(a => a.type !== 'Credit card').reduce((s,a) => s + a.balance, 0);
      return <Kpi label="Cash on hand" value={fmtMoney(v)} delta={`${D.FIN_BANK_ACCOUNTS.filter(a => a.type !== 'Credit card').length} accounts`} tone="up" onClick={() => onNavigate('fin-banking')} />;
    }
  },
  kpi_ar: {
    id: 'kpi_ar', name: 'Accounts receivable', group: 'KPIs', defaultWidth: 1, icon: 'doc',
    description: 'Outstanding customer invoices.',
    render: ({ onNavigate }) => {
      const D = window.HitcentsData;
      const v = D.FIN_INVOICES.filter(i => i.status === 'Sent' || i.status === 'Overdue').reduce((s,i) => s + window.invoiceTotal(i), 0);
      const od = D.FIN_INVOICES.filter(i => i.status === 'Overdue').length;
      return <Kpi label="Accounts receivable" value={fmtMoney(v)} delta={`${od} overdue`} tone={od > 0 ? 'down' : undefined} onClick={() => onNavigate('fin-invoices')} />;
    }
  },
  kpi_ap: {
    id: 'kpi_ap', name: 'Accounts payable', group: 'KPIs', defaultWidth: 1, icon: 'card',
    description: 'Open vendor bills awaiting payment.',
    render: ({ onNavigate }) => {
      const D = window.HitcentsData;
      const v = D.FIN_BILLS.filter(b => b.status === 'Open' || b.status === 'Overdue').reduce((s,b) => s + b.amount, 0);
      const od = D.FIN_BILLS.filter(b => b.status === 'Overdue').length;
      return <Kpi label="Accounts payable" value={fmtMoney(v)} delta={`${od} overdue`} tone={od > 0 ? 'down' : undefined} onClick={() => onNavigate('fin-bills')} />;
    }
  },
  kpi_mrr: {
    id: 'kpi_mrr', name: 'MRR', group: 'KPIs', defaultWidth: 1, icon: 'card',
    description: 'Monthly recurring revenue from active customers.',
    render: ({ onNavigate }) => {
      const D = window.HitcentsData;
      const v = D.CUSTOMERS.reduce((s,c) => s + (c.mrr || 0), 0);
      return <Kpi label="MRR" value={fmtMoney(v)} delta="+$3.2k mo/mo" tone="up" onClick={() => onNavigate('crm')} />;
    }
  },
  kpi_employees: {
    id: 'kpi_employees', name: 'Employee count', group: 'KPIs', defaultWidth: 1, icon: 'users',
    description: 'Total active employees.',
    render: ({ onNavigate }) => {
      const D = window.HitcentsData;
      return <Kpi label="Employees" value={D.EMPLOYEES.length} delta="4 open reqs · 2 starting" tone="up" onClick={() => onNavigate('hrm')} />;
    }
  },
  kpi_acv: {
    id: 'kpi_acv', name: 'ACV under contract', group: 'KPIs', defaultWidth: 1, icon: 'doc',
    description: 'Customer revenue under active contract.',
    render: ({ onNavigate }) => {
      const D = window.HitcentsData;
      const v = D.CONTRACTS.filter(c => c.status === 'Active' && c.type === 'customer').reduce((s,c) => s + c.value, 0);
      return <Kpi label="ACV under contract" value={fmtMoney(v)} delta="3 renewing in Q2" tone="up" onClick={() => onNavigate('contracts')} />;
    }
  },
  kpi_runway: {
    id: 'kpi_runway', name: 'Runway', group: 'KPIs', defaultWidth: 1, icon: 'clock',
    description: 'Months of operating runway at current burn.',
    render: () => <Kpi label="Runway" value="22 mo" delta="burn $480k/mo" />
  },
  kpi_innovation: {
    id: 'kpi_innovation', name: 'Innovation pipeline', group: 'KPIs', defaultWidth: 1, icon: 'bulb',
    description: 'Ideas in shaping or building.',
    render: ({ onNavigate }) => {
      const D = window.HitcentsData;
      const c = D.IDEAS.filter(i => ['shaping','next','building'].includes(i.col)).length;
      return <Kpi label="Innovation pipeline" value={c} delta="3 building · 2 shipped this Q" tone="up" onClick={() => onNavigate('innovation')} />;
    }
  },

  // ────────────── Big widgets ──────────────
  finance_attention: {
    id: 'finance_attention', name: 'Finance — needs attention', group: 'Finance', defaultWidth: 2, icon: 'card',
    description: 'Overdue invoices and bills that need action.',
    render: ({ onNavigate }) => <FinanceAttentionWidget onNavigate={onNavigate} />
  },
  recent_transactions: {
    id: 'recent_transactions', name: 'Recent transactions', group: 'Finance', defaultWidth: 2, icon: 'layers',
    description: 'Latest bank transactions across accounts.',
    render: ({ onNavigate }) => <RecentTransactionsWidget onNavigate={onNavigate} />
  },
  pipeline_chart: {
    id: 'pipeline_chart', name: 'Pipeline by stage', group: 'Revenue', defaultWidth: 2, icon: 'card',
    description: 'Bar chart of pipeline value distributed across deal stages.',
    render: () => <PipelineChartWidget />
  },
  activity_feed: {
    id: 'activity_feed', name: 'Recent activity', group: 'Operations', defaultWidth: 2, icon: 'bolt',
    description: 'Latest activity across the whole workspace.',
    render: ({ onNavigate }) => <ActivityWidget onNavigate={onNavigate} />
  },
  headcount_dept: {
    id: 'headcount_dept', name: 'Headcount by dept', group: 'People', defaultWidth: 2, icon: 'users',
    description: 'Employee count by department.',
    render: ({ onNavigate }) => <HeadcountWidget onNavigate={onNavigate} />
  },
  renewals_upcoming: {
    id: 'renewals_upcoming', name: 'Renewals coming up', group: 'Revenue', defaultWidth: 2, icon: 'doc',
    description: 'Customer contracts expiring soon.',
    render: ({ onNavigate }) => <RenewalsWidget onNavigate={onNavigate} />
  },
  top_deals: {
    id: 'top_deals', name: 'Top open deals', group: 'Revenue', defaultWidth: 2, icon: 'card',
    description: 'Largest open deals by value.',
    render: ({ onNavigate }) => <TopDealsWidget onNavigate={onNavigate} />
  },
  innovation_board: {
    id: 'innovation_board', name: 'Innovation board snapshot', group: 'Operations', defaultWidth: 2, icon: 'bulb',
    description: "What's brewing on the innovation board.",
    render: ({ onNavigate }) => <InnovationBoardWidget onNavigate={onNavigate} />
  },
  onboarding: {
    id: 'onboarding', name: 'Onboarding progress', group: 'People', defaultWidth: 2, icon: 'check',
    description: 'New hires and their onboarding completion.',
    render: ({ onNavigate }) => <OnboardingWidget onNavigate={onNavigate} />
  },
  birthdays: {
    id: 'birthdays', name: 'Birthdays & anniversaries', group: 'People', defaultWidth: 1, icon: 'star',
    description: 'Upcoming celebrations.',
    render: ({ onNavigate }) => <BirthdaysWidget onNavigate={onNavigate} />
  },
  team_directory: {
    id: 'team_directory', name: 'Team online now', group: 'People', defaultWidth: 1, icon: 'globe',
    description: 'Quick directory of who is active.',
    render: ({ onNavigate }) => <TeamOnlineWidget onNavigate={onNavigate} />
  },
};

// ─────────────────────────────────────────────────────────────────────────────
// Widget implementations
// ─────────────────────────────────────────────────────────────────────────────

function FinanceAttentionWidget({ onNavigate }) {
  const D = window.HitcentsData;
  const overdueInv = D.FIN_INVOICES.filter(i => i.status === 'Overdue');
  const overdueBills = D.FIN_BILLS.filter(b => b.status === 'Overdue');
  return (
    <div>
      <div className="widget-h">
        <h3>Needs attention</h3>
        <div className="sub">{overdueInv.length + overdueBills.length} overdue</div>
      </div>
      <div className="col" style={{ gap: 8 }}>
        {overdueInv.map(i => {
          const c = getCustomer(i.customer);
          return (
            <div key={i.id} onClick={() => onNavigate('fin-invoices')} className="row gap-2" style={{ padding: '9px 11px', background: 'var(--red-tint)', borderRadius: 8, cursor: 'pointer' }}>
              <Icon name="arrow_u" size={13} style={{ color: 'var(--red)' }} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 12.5, fontWeight: 500 }}>{c?.name}</div>
                <div className="dim" style={{ fontSize: 11 }}>{i.id} · receivable overdue</div>
              </div>
              <span className="mono" style={{ fontSize: 12, fontWeight: 600, color: '#832E1C' }}>{fmtMoneyFull(window.invoiceTotal(i))}</span>
            </div>
          );
        })}
        {overdueBills.map(b => (
          <div key={b.id} onClick={() => onNavigate('fin-bills')} className="row gap-2" style={{ padding: '9px 11px', background: 'var(--amber-tint)', borderRadius: 8, cursor: 'pointer' }}>
            <Icon name="arrow_d" size={13} style={{ color: 'var(--amber)' }} />
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 12.5, fontWeight: 500 }}>{b.vendor}</div>
              <div className="dim" style={{ fontSize: 11 }}>{b.id} · payable past due</div>
            </div>
            <span className="mono" style={{ fontSize: 12, fontWeight: 600, color: '#8A5713' }}>{fmtMoneyFull(b.amount)}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

function RecentTransactionsWidget({ onNavigate }) {
  const D = window.HitcentsData;
  return (
    <div>
      <div className="widget-h">
        <h3>Recent transactions</h3>
        <Button variant="ghost" iconRight="arrow_r" size="sm" onClick={() => onNavigate('fin-banking')}>Banking</Button>
      </div>
      <div className="col" style={{ gap: 0 }}>
        {D.FIN_TRANSACTIONS.slice(0, 6).map((t, i) => (
          <div key={t.id} onClick={() => onNavigate('fin-banking')} className="row gap-3" style={{ padding: '8px 0', borderTop: i ? '1px solid var(--border)' : 'none', cursor: 'pointer' }}>
            <span className="muted mono" style={{ fontSize: 11, width: 44 }}>{fmtDateShort(t.date)}</span>
            <span style={{ flex: 1, fontSize: 12.5, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{t.desc}</span>
            <span className="mono" style={{ fontWeight: 500, fontSize: 12, color: t.amount < 0 ? 'var(--red)' : 'var(--green)' }}>{t.amount < 0 ? '−' : '+'}{fmtMoneyFull(Math.abs(t.amount))}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

function PipelineChartWidget() {
  const D = window.HitcentsData;
  const byStage = D.DEAL_STAGES.filter(s => !['won','lost'].includes(s.id)).map(s => {
    const dealsInStage = D.DEALS.filter(d => d.stage === s.id);
    return { ...s, value: dealsInStage.reduce((sum, d) => sum + d.value, 0), count: dealsInStage.length };
  });
  const max = Math.max(...byStage.map(s => s.value), 1);
  return (
    <div>
      <div className="widget-h">
        <h3>Pipeline by stage</h3>
        <div className="sub">Open · weighted ${(byStage.reduce((s,b) => s + b.value*0.5, 0)/1000).toFixed(0)}k</div>
      </div>
      <div className="col" style={{ gap: 10 }}>
        {byStage.map(s => (
          <div key={s.id} className="row gap-3">
            <div style={{ width: 96, fontSize: 12 }}>{s.name}</div>
            <div style={{ flex: 1, position: 'relative', background: 'var(--bg-canvas)', borderRadius: 4, height: 22 }}>
              <div style={{ position: 'absolute', inset: 0, width: `${(s.value/max)*100}%`, background: s.color, borderRadius: 4, display: 'flex', alignItems: 'center', padding: '0 8px', color: '#fff', fontSize: 11, fontWeight: 500 }}>
                {fmtMoney(s.value)}
              </div>
            </div>
            <div className="mono dim" style={{ width: 22, textAlign: 'right', fontSize: 11.5 }}>{s.count}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

function ActivityWidget({ onNavigate }) {
  const D = window.HitcentsData;
  return (
    <div>
      <div className="widget-h"><h3>Recent activity</h3><div className="sub">Across the workspace</div></div>
      <div className="col" style={{ gap: 10 }}>
        {D.ACTIVITY.slice(0, 6).map(a => {
          const who = getEmployee(a.who);
          return (
            <div key={a.id} className="row gap-3" style={{ alignItems: 'flex-start' }}>
              <Avatar person={who} size={24} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 12 }}>
                  <strong>{who?.name.split(' ')[0]}</strong> <span className="muted">{a.what}</span> <span style={{ fontWeight: 500 }}>{a.obj}</span>
                </div>
                <div className="dim" style={{ fontSize: 11 }}>{a.detail} · <span className="mono">{a.when}</span></div>
              </div>
              <Badge>{a.section}</Badge>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function HeadcountWidget({ onNavigate }) {
  const D = window.HitcentsData;
  return (
    <div>
      <div className="widget-h">
        <h3>Headcount by dept</h3>
        <Button variant="ghost" iconRight="arrow_r" size="sm" onClick={() => onNavigate('hrm')}>HRM</Button>
      </div>
      <div className="grid g-2" style={{ gap: 8 }}>
        {D.DEPTS.map(d => {
          const count = D.EMPLOYEES.filter(e => e.dept === d.id).length;
          const max = 8;
          return (
            <div key={d.id} style={{ padding: '8px 10px', background: 'var(--bg-elev)', borderRadius: 6 }}>
              <div className="row spread" style={{ marginBottom: 4 }}>
                <div className="row gap-2"><div style={{ width: 8, height: 8, borderRadius: 4, background: d.color }} /><span style={{ fontSize: 12 }}>{d.name}</span></div>
                <span className="mono" style={{ fontSize: 11.5, fontWeight: 600 }}>{count}</span>
              </div>
              <div style={{ height: 4, background: 'var(--bg-canvas)', borderRadius: 2 }}>
                <div style={{ height: '100%', width: `${count/max*100}%`, background: d.color, borderRadius: 2 }} />
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function RenewalsWidget({ onNavigate }) {
  const D = window.HitcentsData;
  const today = new Date('2026-05-15');
  const upcoming = D.CONTRACTS
    .filter(c => c.endDate && c.status === 'Active' && c.type === 'customer')
    .map(c => ({ ...c, daysLeft: Math.round((new Date(c.endDate) - today) / (1000*60*60*24)) }))
    .filter(c => c.daysLeft >= 0 && c.daysLeft <= 240)
    .sort((a,b) => a.daysLeft - b.daysLeft)
    .slice(0, 4);
  return (
    <div>
      <div className="widget-h">
        <h3>Renewals coming up</h3>
        <Button variant="ghost" iconRight="arrow_r" size="sm" onClick={() => onNavigate('contracts')}>Contracts</Button>
      </div>
      <div className="col" style={{ gap: 8 }}>
        {upcoming.map(c => {
          const urgent = c.daysLeft <= 60;
          return (
            <div key={c.id} onClick={() => onNavigate('contracts')}
                 style={{ padding: '10px 12px', background: urgent ? 'var(--brand-orange-tint)' : 'var(--bg-elev)', borderLeft: `3px solid ${urgent ? 'var(--brand-orange)' : 'var(--green)'}`, borderRadius: 6, cursor: 'pointer' }}>
              <div className="row spread" style={{ marginBottom: 2 }}>
                <strong style={{ fontSize: 12.5 }}>{c.counterparty}</strong>
                <span className="mono" style={{ fontSize: 11, fontWeight: 600, color: urgent ? 'var(--brand-orange)' : 'var(--text-muted)' }}>{c.daysLeft}d</span>
              </div>
              <div className="dim" style={{ fontSize: 11 }}>{fmtMoneyFull(c.value)} · ends {fmtDateShort(c.endDate)}</div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function TopDealsWidget({ onNavigate }) {
  const D = window.HitcentsData;
  const top = D.DEALS.filter(d => !['won','lost'].includes(d.stage)).sort((a,b) => b.value - a.value).slice(0, 5);
  return (
    <div>
      <div className="widget-h">
        <h3>Top open deals</h3>
        <Button variant="ghost" iconRight="arrow_r" size="sm" onClick={() => onNavigate('crm')}>CRM</Button>
      </div>
      <div className="col" style={{ gap: 0 }}>
        {top.map((d, i) => {
          const stage = D.DEAL_STAGES.find(s => s.id === d.stage);
          const owner = getEmployee(d.owner);
          return (
            <div key={d.id} onClick={() => onNavigate('crm')} className="row gap-3" style={{ padding: '8px 0', borderTop: i ? '1px solid var(--border)' : 'none', cursor: 'pointer' }}>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 12.5, fontWeight: 500 }}>{d.name}</div>
                <div className="dim" style={{ fontSize: 11 }}>{stage.name} · {d.probability}% · {fmtDateShort(d.close)}</div>
              </div>
              <span className="mono" style={{ fontWeight: 600, fontSize: 12 }}>{fmtMoney(d.value)}</span>
              <Avatar person={owner} size={20} />
            </div>
          );
        })}
      </div>
    </div>
  );
}

function InnovationBoardWidget({ onNavigate }) {
  const D = window.HitcentsData;
  const building = D.IDEAS.filter(i => i.col === 'building').slice(0, 4);
  return (
    <div>
      <div className="widget-h">
        <h3>Innovation — building now</h3>
        <Button variant="ghost" iconRight="arrow_r" size="sm" onClick={() => onNavigate('innovation')}>Board</Button>
      </div>
      <div className="col" style={{ gap: 8 }}>
        {building.map(i => {
          const owner = getEmployee(i.owner);
          return (
            <div key={i.id} onClick={() => onNavigate('innovation')} style={{ padding: 10, background: 'var(--bg-elev)', borderRadius: 6, cursor: 'pointer' }}>
              <div style={{ fontSize: 12.5, fontWeight: 500 }}>{i.title}</div>
              <div className="row gap-2" style={{ marginTop: 4 }}>
                <Avatar person={owner} size={18} />
                <span className="dim" style={{ fontSize: 11 }}>{owner?.name.split(' ')[0]}</span>
                <span style={{ marginLeft: 'auto' }} className="row gap-2">
                  <Badge tone={i.priority === 'High' ? 'red' : i.priority === 'Med' ? 'amber' : 'neutral'}>{i.priority}</Badge>
                  <span className="mono dim" style={{ fontSize: 10.5 }}>↑ {i.votes}</span>
                </span>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function OnboardingWidget({ onNavigate }) {
  const hires = [
    { name: 'Pratik Sundar', start: 'Started Mar 4', pct: 82 },
    { name: 'Caleb Otieno', start: 'Started Sep 11, 2023', pct: 100 },
    { name: 'Wendy Kobayashi', start: 'Starts Jun 2', pct: 18 },
    { name: 'Marc Lemieux', start: 'Offer pending — Jun 15', pct: 0 },
  ];
  return (
    <div>
      <div className="widget-h">
        <h3>Onboarding progress</h3>
        <Button variant="ghost" iconRight="arrow_r" size="sm" onClick={() => onNavigate('hrm')}>HRM</Button>
      </div>
      <div className="col" style={{ gap: 10 }}>
        {hires.map((h, i) => (
          <div key={i}>
            <div className="row spread" style={{ marginBottom: 4 }}>
              <div>
                <div style={{ fontSize: 12.5, fontWeight: 500 }}>{h.name}</div>
                <div className="dim" style={{ fontSize: 11 }}>{h.start}</div>
              </div>
              <span className="mono" style={{ fontSize: 12, fontWeight: 600 }}>{h.pct}%</span>
            </div>
            <div className="progress"><div className="fill" style={{ width: `${h.pct}%`, background: h.pct === 100 ? 'var(--green)' : 'var(--brand-orange)' }} /></div>
          </div>
        ))}
      </div>
    </div>
  );
}

function BirthdaysWidget({ onNavigate }) {
  const items = [
    { who: 'e10', date: 'today', kind: 'birthday', label: '🎂 Birthday' },
    { who: 'e23', date: 'May 19', kind: 'birthday', label: '🎂 Birthday' },
    { who: 'e2',  date: 'Aug 15', kind: 'anniversary', label: '14 years' },
    { who: 'e8',  date: 'Feb 14, 2027', kind: 'anniversary', label: '9 years' },
  ];
  return (
    <div>
      <div className="widget-h"><h3>Celebrations</h3></div>
      <div className="col" style={{ gap: 8 }}>
        {items.map((it, i) => {
          const p = getEmployee(it.who);
          return (
            <div key={i} onClick={() => onNavigate('hrm')} className="row gap-2" style={{ padding: '6px 0', cursor: 'pointer', borderTop: i ? '1px solid var(--border)' : 'none' }}>
              <Avatar person={p} size={24} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 12.5, fontWeight: 500 }}>{p?.name}</div>
                <div className="dim" style={{ fontSize: 11 }}>{it.label}</div>
              </div>
              <span className="mono dim" style={{ fontSize: 11 }}>{it.date}</span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function TeamOnlineWidget({ onNavigate }) {
  const D = window.HitcentsData;
  const online = D.EMPLOYEES.slice(0, 8);
  return (
    <div>
      <div className="widget-h"><h3>Team online</h3><div className="sub">{online.length} active</div></div>
      <div className="col" style={{ gap: 8 }}>
        {online.slice(0, 6).map(e => (
          <div key={e.id} onClick={() => onNavigate('hrm')} className="row gap-2" style={{ cursor: 'pointer' }}>
            <div style={{ position: 'relative' }}>
              <Avatar person={e} size={26} />
              <span style={{ position: 'absolute', bottom: -1, right: -1, width: 8, height: 8, borderRadius: 4, background: 'var(--green)', border: '2px solid var(--bg-card)' }} />
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 12, fontWeight: 500, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{e.name}</div>
              <div className="dim" style={{ fontSize: 10.5 }}>{e.title}</div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// Widget Library modal
// ─────────────────────────────────────────────────────────────────────────────

function WidgetLibrary({ onClose, onAdd, addedIds }) {
  const [q, setQ] = useState('');
  const [group, setGroup] = useState('All');
  const widgets = Object.values(WIDGET_CATALOG);
  const groups = ['All', ...new Set(widgets.map(w => w.group))];
  const filtered = widgets.filter(w => {
    if (group !== 'All' && w.group !== group) return false;
    if (q && !`${w.name} ${w.description}`.toLowerCase().includes(q.toLowerCase())) return false;
    return true;
  });

  return (
    <div className="cmdk-scrim" onClick={onClose} style={{ paddingTop: '8vh' }}>
      <div onClick={e => e.stopPropagation()}
           style={{ width: 820, maxWidth: '94vw', maxHeight: '80vh', background: 'var(--bg-card)', borderRadius: 14, border: '1px solid var(--border)', boxShadow: 'var(--shadow-lg)', overflow: 'hidden', display: 'flex', flexDirection: 'column' }}>
        <div style={{ padding: '16px 22px 12px', borderBottom: '1px solid var(--border)' }}>
          <div className="row spread" style={{ marginBottom: 10 }}>
            <div>
              <h2 style={{ margin: 0, fontSize: 17, fontWeight: 600 }}>Widget library</h2>
              <p className="muted" style={{ margin: '4px 0 0', fontSize: 12.5 }}>Choose from {widgets.length} system widgets. {addedIds.size} already on your dashboard.</p>
            </div>
            <button className="icon-btn" onClick={onClose}><Icon name="x" size={16} /></button>
          </div>
          <div className="row gap-2">
            <div className="search-inline" style={{ flex: 1 }}>
              <Icon name="search" size={14} />
              <input autoFocus placeholder="Search widgets…" value={q} onChange={e => setQ(e.target.value)} />
            </div>
          </div>
          <div className="row gap-2" style={{ marginTop: 10, flexWrap: 'wrap' }}>
            {groups.map(g => (
              <button key={g} onClick={() => setGroup(g)} className={`btn btn-sm ${group === g ? 'btn-primary' : 'btn-ghost'}`}>{g}</button>
            ))}
          </div>
        </div>

        <div style={{ overflowY: 'auto', flex: 1, padding: 14 }}>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))', gap: 10 }}>
            {filtered.map(w => {
              const added = addedIds.has(w.id);
              return (
                <button key={w.id} onClick={() => onAdd(w.id)} disabled={added}
                        style={{ textAlign: 'left', padding: 14, border: `1px solid var(--border)`, borderRadius: 10, background: added ? 'var(--bg-elev)' : 'var(--bg-card)', cursor: added ? 'default' : 'pointer', opacity: added ? 0.6 : 1, display: 'flex', flexDirection: 'column', gap: 8 }}
                        onMouseEnter={e => { if (!added) e.currentTarget.style.borderColor = 'var(--brand-orange)'; }}
                        onMouseLeave={e => e.currentTarget.style.borderColor = 'var(--border)'}>
                  <div className="row gap-2">
                    <div style={{ width: 32, height: 32, borderRadius: 8, background: 'var(--brand-orange-tint)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--brand-orange)' }}>
                      <Icon name={w.icon} size={14} />
                    </div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 13.5, fontWeight: 600 }}>{w.name}</div>
                      <div className="dim" style={{ fontSize: 10.5 }}>{w.group} · default {w.defaultWidth} col</div>
                    </div>
                    {added && <Badge tone="green"><Icon name="check" size={9} stroke={3} /> Added</Badge>}
                  </div>
                  <p style={{ margin: 0, fontSize: 12, color: 'var(--text-muted)', lineHeight: 1.45 }}>{w.description}</p>
                </button>
              );
            })}
          </div>
          {filtered.length === 0 && <div className="dim" style={{ textAlign: 'center', padding: 40 }}>No widgets match.</div>}
        </div>

        <div style={{ padding: '12px 22px', borderTop: '1px solid var(--border)', background: 'var(--bg-elev)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div className="muted" style={{ fontSize: 11.5 }}>💡 Custom widgets are coming soon — KPI builder, metric query, embedded reports</div>
          <Button variant="ghost" onClick={onClose}>Done</Button>
        </div>
      </div>
    </div>
  );
}

window.Dashboard = Dashboard;
