// Shared components: Sidebar, Header, Drawer, Modal, Sparkline, Monogram, etc.

const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ── Monogram ────────────────────────────────────────────────────────────────
function Monogram({ initials, tone = 'forest', size = 36 }) {
  const isGold = tone === 'gold';
  const styles = {
    width: size, height: size, flex: 'none',
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
    fontFamily: 'Inter', fontWeight: 700,
    fontSize: size <= 28 ? 10 : 11.5, letterSpacing: '0.04em',
    border: '1.5px solid currentColor', borderRadius: 0,
    background: isGold ? 'rgba(248,197,48,.12)' : 'rgba(27,67,50,.06)',
    color: isGold ? '#7a5605' : 'var(--forest-700)',
    position: 'relative'
  };
  return <span style={{ ...styles, background: "rgb(251, 250, 247)", color: "rgb(15, 42, 31)" }}>{initials}</span>;
}

// ── DC Logo ─────────────────────────────────────────────────────────────────
function DCLogo({ onDark = false, compact = false }) {
  const top = onDark ? 'var(--paper-50)' : 'var(--ink)';
  const sub = onDark ? 'rgba(244,239,230,.65)' : 'var(--ink-soft)';
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
      <span className="dc-stamp" style={{ color: top }}>DC</span>
      {!compact &&
      <div style={{ display: 'flex', flexDirection: 'column', lineHeight: 1.05 }}>
          <span style={{ fontSize: 10.5, fontWeight: 600, letterSpacing: '0.14em', textTransform: 'uppercase', color: top }}>Digital</span>
          <span style={{ fontSize: 10.5, fontWeight: 600, letterSpacing: '0.14em', textTransform: 'uppercase', color: sub }}>Contractors</span>
        </div>
      }
    </div>);

}

// ── Card / Section header ───────────────────────────────────────────────────
function WidgetCard({ eyebrow, title, action, children, padded = true, dense = false }) {
  return (
    <section className="card" style={padded ? {} : { padding: 0 }}>
      {(eyebrow || title || action) &&
      <header style={{
        display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between',
        gap: 12, marginBottom: dense ? 10 : 14,
        padding: padded ? 0 : 'var(--pad-card)',
        paddingBottom: padded ? 0 : 0
      }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
            {eyebrow && <span className="eyebrow">{eyebrow}</span>}
            {title && <h2 className="serif" style={{ margin: 0, fontSize: 22, fontWeight: 400, lineHeight: 1.05 }}>{title}</h2>}
          </div>
          {action}
        </header>
      }
      {children}
    </section>);

}

// ── Sparkline ───────────────────────────────────────────────────────────────
function Sparkline({ series, width = 140, height = 36, color, fill = true, sentiment, goodIs = 'up' }) {
  if (!series || series.length < 2) return null;
  const min = Math.min(...series);
  const max = Math.max(...series);
  const range = max - min || 1;
  const stepX = width / (series.length - 1);
  const points = series.map((v, i) => {
    const x = i * stepX;
    const y = height - (v - min) / range * (height - 4) - 2;
    return [x, y];
  });
  const path = points.map(([x, y], i) => i === 0 ? `M ${x.toFixed(1)} ${y.toFixed(1)}` : `L ${x.toFixed(1)} ${y.toFixed(1)}`).join(' ');
  const fillPath = `${path} L ${width} ${height} L 0 ${height} Z`;
  const last = points[points.length - 1];
  const dir = series[series.length - 1] > series[0] ? 'up' : series[series.length - 1] < series[0] ? 'down' : 'flat';
  // Auto-color: if sentiment is given, use it; else derive from goodIs vs direction.
  let strokeColor = color;
  if (!strokeColor) {
    const isGood = goodIs === 'up' && dir === 'up' || goodIs === 'down' && dir === 'down';
    const isBad = goodIs === 'up' && dir === 'down' || goodIs === 'down' && dir === 'up';
    strokeColor = sentiment === 'good' || isGood ? 'var(--status-green)' :
    sentiment === 'bad' || isBad ? 'var(--status-red)' :
    'var(--forest-700)';
  }
  return (
    <svg className="spark" width={width} height={height} viewBox={`0 0 ${width} ${height}`} style={{ display: 'block' }}>
      {fill && <path d={fillPath} fill={strokeColor} fillOpacity={0.08} />}
      <path d={path} fill="none" stroke={strokeColor} strokeWidth="1.5" />
      <circle cx={last[0]} cy={last[1]} r="2.5" fill={strokeColor} />
      <line x1="0" y1={height - 0.5} x2={width} y2={height - 0.5} stroke="var(--rule-soft)" strokeWidth="0.5" />
    </svg>);

}

// ── Drawer (right slide-in) ─────────────────────────────────────────────────
function Drawer({ open, onClose, children }) {
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => {if (e.key === 'Escape') onClose();};
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, onClose]);
  return (
    <React.Fragment>
      <div className={`scrim ${open ? 'open' : ''}`} onClick={onClose} />
      <aside className={`drawer ${open ? 'open' : ''}`} aria-hidden={!open}>
        {children}
      </aside>
    </React.Fragment>);

}

// ── Modal ───────────────────────────────────────────────────────────────────
function Modal({ open, onClose, children }) {
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => {if (e.key === 'Escape') onClose();};
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, onClose]);
  return (
    <React.Fragment>
      <div className={`scrim ${open ? 'open' : ''}`} onClick={onClose} style={{ zIndex: 95 }} />
      <div className={`modal ${open ? 'open' : ''}`} role="dialog" aria-modal="true" onClick={onClose}>
        <div className="modal-card" onClick={(e) => e.stopPropagation()}>
          {children}
        </div>
      </div>
    </React.Fragment>);

}

// ── Empty state ─────────────────────────────────────────────────────────────
function Empty({ icon = '·', title, hint }) {
  return (
    <div style={{
      display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
      padding: '32px 16px', gap: 6, color: 'var(--ink-soft)', textAlign: 'center',
      border: '1px dashed var(--rule-soft)'
    }}>
      <span className="serif" style={{ fontSize: 36, lineHeight: 1, color: 'var(--rule)' }}>{icon}</span>
      <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)' }}>{title}</div>
      {hint && <div style={{ fontSize: 12 }}>{hint}</div>}
    </div>);

}

// ── External-link arrow ─────────────────────────────────────────────────────
function ExtArrow({ size = 11 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 11 11" fill="none" style={{ flex: 'none' }}>
      <path d="M3 8L8 3M8 3H4M8 3V7" stroke="currentColor" strokeWidth="1.2" strokeLinecap="round" strokeLinejoin="round" />
    </svg>);

}

// ── Nav icons (one stroke-based glyph per route, designed for clarity at 14px)
function NavIcon({ name }) {
  const props = { width: 14, height: 14, viewBox: '0 0 14 14', fill: 'none', stroke: 'currentColor', strokeWidth: 1.4, strokeLinecap: 'round', strokeLinejoin: 'round', style: { flex: 'none', display: 'block' } };
  switch (name) {
    case 'overview':return <svg {...props}><rect x="1.5" y="1.5" width="4.5" height="4.5" /><rect x="8" y="1.5" width="4.5" height="4.5" /><rect x="1.5" y="8" width="4.5" height="4.5" /><rect x="8" y="8" width="4.5" height="4.5" /></svg>;
    case 'agents':return <svg {...props}><path d="M7 1.5v3M7 9.5v3M1.5 7h3M9.5 7h3M3.5 3.5l1.5 1.5M9 9l1.5 1.5M3.5 10.5l1.5-1.5M9 5l1.5-1.5" /></svg>;
    case 'blockers':return <svg {...props}><path d="M7 1.5L12.5 11.5h-11L7 1.5z" /><path d="M7 5.5v3" /><circle cx="7" cy="10" r=".5" fill="currentColor" stroke="none" /></svg>;
    case 'clients':return <svg {...props}><path d="M1.5 7h2l1-2 2 4 1.5-3 1 1.5h3.5" /></svg>;
    case 'goals':return <svg {...props}><circle cx="7" cy="7" r="5.25" /><circle cx="7" cy="7" r="3" /><circle cx="7" cy="7" r=".9" fill="currentColor" stroke="none" /></svg>;
    case 'transcripts':return <svg {...props}><path d="M2 3.5h10v6h-4l-2.5 2v-2H2v-6z" /><path d="M4 5.5h6M4 7.5h4" /></svg>;
    case 'at-risk':return <svg {...props}><path d="M1.5 3l3.5 4 2.5-2 5 6" /><path d="M12.5 11h-3M12.5 11V8" /></svg>;
    case 'neglected':return <svg {...props}><circle cx="7" cy="7" r="5.25" /><path d="M7 4v3l2 1.5" /></svg>;
    case 'tasks':return <svg {...props}><rect x="1.5" y="1.5" width="11" height="11" rx="1" /><path d="M4 7.25l2 2 4-4.5" /></svg>;
    case 'creative':return <svg {...props}><rect x="1.5" y="3.5" width="9" height="7" /><path d="M3.5 5.5h5M3.5 7.5h3" /><path d="M11.5 2.5v8" /></svg>;
    case 'wins':return <svg {...props}><path d="M4 1.5h6v3a3 3 0 01-6 0v-3z" /><path d="M4 2.5H2.5v1.5a1.5 1.5 0 001.5 1.5M10 2.5h1.5v1.5a1.5 1.5 0 01-1.5 1.5" /><path d="M5.5 8v2.5h3V8M4 12.5h6" /></svg>;
    case 'ext':return <svg {...props}><path d="M3 8.5L9 2.5M9 2.5H5M9 2.5v4" /></svg>;
    case 'clickup':return <svg {...props}><rect x="1.5" y="1.5" width="11" height="11" rx="2.5" /><path d="M4 7.25l2 2 4-4.5" /></svg>;
    case 'ghl':return <svg {...props}><path d="M8 1.5L3 8h3l-1 4.5L10 6H7l1-4.5z" /></svg>;
    case 'meta':return <svg {...props}><path d="M2 7c0-1.7 1.1-3 2.5-3 1.6 0 2.7 1.4 4 3.5C9.8 9.6 10.9 11 12.5 11c1.4 0 2-1.3 2-3s-.6-3-2-3c-1.6 0-2.7 1.4-4 3.5C7.2 10.6 6.1 12 4.5 12 3.1 12 2 10.7 2 9z" /></svg>;
    default:return <svg {...props}><circle cx="7" cy="7" r="2" /></svg>;
  }
}

// ── Sidebar nav ─────────────────────────────────────────────────────────────
function Sidebar({ role, view, setView, collapsed, onClose, sidebarStyle }) {
  const henryGroups = [
  { label: 'Workspace', items: [
    { id: 'overview', label: 'Overview' },
    { id: 'agents', label: 'AI Agents' },
    { id: 'blockers', label: 'Blockers' },
    { id: 'clients', label: 'Client Health' },
    { id: 'goals', label: 'Goals' },
    { id: 'transcripts', label: 'Transcript Recs' },
    { id: 'tasks', label: 'My Tasks' }] },
  { label: 'Team', items: [
    { id: 'team-at-risk',   label: 'At-Risk Accounts', icon: 'at-risk' },
    { id: 'team-neglected', label: 'Neglected',        icon: 'neglected' },
    { id: 'team-creative',  label: 'Creative Log',     icon: 'creative' },
    { id: 'team-wins',      label: 'Account Wins',     icon: 'wins' }] }];

  const vukasiGroups = [
  { label: 'Workspace', items: [
    { id: 'overview', label: 'Overview' },
    { id: 'at-risk', label: 'At-Risk Accounts' },
    { id: 'neglected', label: 'Neglected' },
    { id: 'tasks', label: 'My Tasks' },
    { id: 'creative', label: 'Creative Log' },
    { id: 'wins', label: 'Account Wins' }] }];

  const groups = role === 'owner' ? henryGroups : vukasiGroups;
  const isLight = sidebarStyle === 'light';
  const isMinimal = sidebarStyle === 'minimal';
  // On phone, "collapsed" really means "off-canvas drawer closed" — handled by CSS.
  const isPhone = typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(max-width: 760px)').matches;
  return (
    <React.Fragment>
    <div className={`sidebar-backdrop ${!collapsed && isPhone ? 'is-open' : ''}`} onClick={onClose} />
    <aside className={`sidebar ${isLight ? 'light' : ''} ${!collapsed ? 'is-open' : ''}`} style={{
      width: collapsed ? 0 : 240,
      minWidth: collapsed ? 0 : 240,
      transition: 'width .2s ease, min-width .2s ease',
      display: 'flex', flexDirection: 'column',
      overflow: 'hidden',
      ...(isMinimal ? { background: 'transparent', color: 'var(--ink)', borderRight: '1px solid var(--border)' } : {})
    }}>
      <div style={{ padding: '18px 18px 14px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <DCLogo onDark={!isLight && !isMinimal} />
        <button
          onClick={onClose}
          aria-label="Close sidebar"
          style={{ display: 'none', background: 'transparent', border: 0, color: 'inherit', cursor: 'pointer', fontSize: 18, padding: 4 }}
          className="sidebar-close-btn">
          ×</button>
      </div>

      {/* Role / user card */}
      <div style={{ padding: '0 14px 12px' }}>
        <div style={{
          padding: '12px',
          background: isLight ? 'var(--paper-100)' : isMinimal ? 'var(--paper-100)' : 'rgba(255,255,255,.04)',
          border: isMinimal ? '1px solid var(--border)' : 'none',
          display: 'flex', alignItems: 'center', gap: 10
        }}>
          <Monogram initials={role === 'owner' ? 'HS' : 'VP'} tone="gold" size={32} />
          <div style={{ display: 'flex', flexDirection: 'column', minWidth: 0 }}>
            <span style={{ fontSize: 12.5, fontWeight: 600, lineHeight: 1.2 }}>
              {role === 'owner' ? 'Henry' : 'Vukasi'}
            </span>
            <span style={{ fontSize: 10.5, opacity: .6, letterSpacing: '0.06em', textTransform: 'uppercase' }}>
              {role === 'owner' ? 'Owner' : 'Media buyer'}
            </span>
          </div>
        </div>
      </div>

      {/* Nav */}
      <nav style={{ padding: '6px 10px', display: 'flex', flexDirection: 'column', gap: 2, flex: 1, overflowY: 'auto' }}>
        {groups.map((g, gi) => (
          <React.Fragment key={g.label}>
            <div className="eyebrow" style={{ padding: gi === 0 ? '8px 12px 4px' : '16px 12px 4px', opacity: isLight || isMinimal ? .7 : .5, color: "rgb(255, 255, 255)" }}>{g.label}</div>
            {g.items.map((n) =>
              <button key={n.id}
                className={`nav-item ${view === n.id ? 'active' : ''}`}
                onClick={() => setView(n.id)}>
                <span style={{ width: 14, height: 14, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', opacity: view === n.id ? .9 : .65 }}><NavIcon name={n.icon || n.id} /></span>
                <span style={{ flex: 1 }}>{n.label}</span>
              </button>
            )}
          </React.Fragment>
        ))}

        <div className="eyebrow" style={{ padding: '16px 12px 4px', opacity: isLight || isMinimal ? .7 : .5, color: "rgb(244, 239, 230)" }}>Connected</div>
        {[
        { label: 'ClickUp', host: 'app.clickup.com', icon: 'clickup' },
        { label: 'GoHighLevel', host: 'app.gohighlevel.com', icon: 'ghl' },
        { label: 'Meta Ads Manager', host: 'business.facebook.com', icon: 'meta' }].
        map((s) =>
        <a key={s.label}
        href={`https://${s.host}`} target="_blank" rel="noreferrer"
        className="nav-item"
        style={{ textDecoration: 'none' }}>
            <span style={{ width: 14, height: 14, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', opacity: .55 }}><NavIcon name={s.icon} /></span>
            <span style={{ flex: 1 }}>{s.label}</span>
            <ExtArrow />
          </a>
        )}
      </nav>

      {/* Footer removed: role is determined by SSO in production. */}
    </aside>
    </React.Fragment>);

}

// ── Header / page chrome ────────────────────────────────────────────────────
function PageHeader({ role, scenario, onScenario, onMenuToggle, onTweaksToggle }) {
  const today = new Date('2026-04-29T09:00:00Z');
  const dateStr = today.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' });
  return (
    <header className="page-header" style={{
      padding: '10px var(--page-pad, 24px)',
      borderBottom: '1px solid var(--border)',
      background: 'var(--bg)',
      display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12,
      position: 'sticky', top: 0, zIndex: 20
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
        <button onClick={onMenuToggle} aria-label="Menu" style={{
          background: 'transparent', border: '1px solid var(--border)',
          width: 36, height: 36, cursor: 'pointer', color: 'var(--ink)',
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center'
        }}>
          <svg width="14" height="14" viewBox="0 0 14 14"><path d="M1 3h12M1 7h12M1 11h12" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" /></svg>
        </button>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
          <div className="eyebrow" style={{ fontSize: 9.5 }}>{dateStr} · {role === 'owner' ? 'Owner view' : 'Media buyer view'}</div>
          <h1 className="serif" style={{ margin: 0, fontSize: 22, lineHeight: 1.1, fontWeight: 400 }}>
            {role === 'owner' ? 'Good morning, Henry.' : "Vukasi's desk"}
          </h1>
        </div>
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
        <div className="freshness-pill" style={{
          display: 'flex', alignItems: 'center', gap: 8, padding: '6px 10px',
          background: 'var(--paper-100)', border: '1px solid var(--border-soft)',
          fontSize: 10.5, color: 'var(--ink-soft)', letterSpacing: '0.04em'
        }}>
          <span style={{
            width: 6, height: 6, borderRadius: '50%', background: 'var(--status-green)',
            boxShadow: '0 0 0 3px rgba(58,90,64,.12)'
          }} />
          <span className="mono" style={{ textTransform: 'uppercase' }}>Updated 6m ago</span>
          <span style={{ opacity: .4 }}>·</span>
          <span style={{ textTransform: 'uppercase' }}>Meta 22m · ClickUp 4m</span>
        </div>
        <div style={{ display: 'flex', border: '1px solid var(--border)', background: 'var(--surface)' }}>
          {['calm', 'busy', 'crisis'].map((s) =>
          <button key={s} onClick={() => onScenario(s)}
          title={`${s} scenario`}
          style={{
            padding: '7px 12px', cursor: 'pointer',
            background: scenario === s ? 'var(--forest-700)' : 'transparent',
            color: scenario === s ? 'var(--paper-50)' : 'var(--ink-soft)',
            border: 0,
            fontSize: 10.5, fontWeight: 600, letterSpacing: '0.08em', textTransform: 'uppercase'
          }}>{s}</button>
          )}
        </div>
      </div>
    </header>);

}

window.DC = Object.assign(window.DC || {}, {
  Monogram, DCLogo, WidgetCard, Sparkline, Drawer, Modal, Empty, ExtArrow,
  Sidebar, PageHeader
});