// Core components, shared styles, and icons for the admin dashboard.
// Brand-matched palette: #0a0a0a background, #ff5a1f accent, Archivo display,
// Inter UI, JetBrains Mono for labels / numbers / timestamps.

const DATA = window.PSData;

// Density scale — app-wide tweak. Compact is the default shown in the design.
const DENSITY = {
  compact:     { rowH: 36, cardPad: 18, sectPad: 20, fs: 13, kpiNum: 34, gap: 12 },
  comfortable: { rowH: 44, cardPad: 24, sectPad: 28, fs: 14, kpiNum: 42, gap: 18 },
  spacious:    { rowH: 54, cardPad: 32, sectPad: 36, fs: 15, kpiNum: 54, gap: 24 },
};

// ── Icons ──────────────────────────────────────────────────────────────
const Icon = {
  dash:    (p) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3" y="3" width="7" height="9"/><rect x="14" y="3" width="7" height="5"/><rect x="14" y="12" width="7" height="9"/><rect x="3" y="16" width="7" height="5"/></svg>,
  inbox:   (p) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="22 12 16 12 14 15 10 15 8 12 2 12"/><path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/></svg>,
  users:   (p) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>,
  mail:    (p) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>,
  press:   (p) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="6 9 6 2 18 2 18 9"/><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"/><rect x="6" y="14" width="12" height="8"/></svg>,
  phone:   (p) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>,
  finance: (p) => <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>,
  search:  (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>,
  up:      (p) => <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="18 15 12 9 6 15"/></svg>,
  down:    (p) => <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" {...p}><polyline points="6 9 12 15 18 9"/></svg>,
  plus:    (p) => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" {...p}><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>,
};

// ── Formatting helpers ─────────────────────────────────────────────────
function fmtMoney(n) { return '$' + n.toLocaleString('en-US'); }
function fmtNum(n)   { return n.toLocaleString('en-US'); }
function relTime(iso) {
  const d = Date.now() - new Date(iso).getTime();
  const mins = Math.floor(d / 60000);
  if (mins < 1) return 'just now';
  if (mins < 60) return `${mins}m`;
  const hrs = Math.floor(mins / 60);
  if (hrs < 24) return `${hrs}h`;
  const days = Math.floor(hrs / 24);
  if (days < 30) return `${days}d`;
  return new Date(iso).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
}

// ── Shared styles ──────────────────────────────────────────────────────
const mono = { fontFamily: 'JetBrains Mono, monospace', fontSize: 12, color: 'rgba(245,243,239,0.75)', fontWeight: 500 };
const btnPrimary = {
  background: '#ff5a1f', color: '#0a0a0a', border: 'none',
  padding: '8px 14px', borderRadius: 7, fontFamily: 'Inter, sans-serif',
  fontSize: 12, fontWeight: 700, cursor: 'pointer', letterSpacing: '-0.005em',
  display: 'inline-flex', alignItems: 'center', gap: 6,
};
const btnSecondary = {
  background: 'transparent', color: 'rgba(245,243,239,0.8)',
  border: '1px solid rgba(255,255,255,0.12)',
  padding: '7px 14px', borderRadius: 7, fontFamily: 'Inter, sans-serif',
  fontSize: 12, fontWeight: 600, cursor: 'pointer',
};

// ── Status pill ────────────────────────────────────────────────────────
function Status({ kind }) {
  const map = {
    'new':           { bg: '#ff5a1f22', fg: '#ff5a1f', label: 'New' },
    'contacted':     { bg: '#ffffff10', fg: '#bfbcb3', label: 'Contacted' },
    'qualified':     { bg: '#ffb83322', fg: '#ffb833', label: 'Qualified' },
    'customer':      { bg: '#34c75922', fg: '#34c759', label: 'Customer' },
    'active':        { bg: '#34c75922', fg: '#34c759', label: 'Active' },
    'paused':        { bg: '#ffffff10', fg: '#bfbcb3', label: 'Paused' },
    'draft':         { bg: '#ffffff10', fg: '#bfbcb3', label: 'Draft' },
    'scheduled':     { bg: '#ffb83322', fg: '#ffb833', label: 'Scheduled' },
    'in-production': { bg: '#ff5a1f22', fg: '#ff5a1f', label: 'In production' },
    'mailed':        { bg: '#34c75922', fg: '#34c759', label: 'Mailed' },
    'completed':     { bg: '#ffffff10', fg: '#bfbcb3', label: 'Completed' },
  };
  const s = map[kind] || map['draft'];
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      padding: '3px 9px', borderRadius: 999, background: s.bg, color: s.fg,
      fontSize: 11, fontWeight: 700, letterSpacing: '-0.005em',
      fontFamily: 'Inter, sans-serif', whiteSpace: 'nowrap',
    }}>
      <span style={{ width: 6, height: 6, borderRadius: 999, background: s.fg }} />
      {s.label}
    </span>
  );
}

// ── Sparkline (mini chart on KPI cards) ────────────────────────────────
function Spark({ data, w = 120, h = 32, color = '#ff5a1f' }) {
  const max = Math.max(...data, 1);
  const step = w / (data.length - 1);
  const pts = data.map((v, i) => `${i * step},${h - (v / max) * h}`).join(' ');
  const area = `0,${h} ${pts} ${w},${h}`;
  return (
    <svg width={w} height={h} style={{ display: 'block' }}>
      <defs>
        <linearGradient id="sparkGrad" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.3" />
          <stop offset="100%" stopColor={color} stopOpacity="0" />
        </linearGradient>
      </defs>
      <polygon points={area} fill="url(#sparkGrad)" />
      <polyline points={pts} fill="none" stroke={color} strokeWidth="1.6" />
    </svg>
  );
}

// ── KPI card ───────────────────────────────────────────────────────────
function Kpi({ label, value, unit, delta, spark, density }) {
  const D = DENSITY[density];
  const positive = delta !== undefined && delta >= 0;
  return (
    <div style={{
      padding: D.cardPad,
      background: '#141414',
      border: '1px solid rgba(255,255,255,0.08)',
      borderRadius: 14,
      display: 'flex', flexDirection: 'column', gap: D.gap - 8,
      minHeight: D.kpiNum + D.cardPad * 2 + 20,
      position: 'relative', overflow: 'hidden',
    }}>
      <div style={{
        fontFamily: 'JetBrains Mono, monospace', fontSize: 10,
        letterSpacing: '0.14em', textTransform: 'uppercase',
        color: 'rgba(245,243,239,0.55)', fontWeight: 600,
      }}>{label}</div>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, flexWrap: 'wrap' }}>
        <div style={{
          fontFamily: 'Archivo, sans-serif', fontWeight: 900,
          fontSize: D.kpiNum, lineHeight: 1, letterSpacing: '-0.03em',
          color: '#f5f3ef',
        }}>{value}</div>
        {unit && <div style={{ fontSize: 14, color: 'rgba(245,243,239,0.5)', fontWeight: 600 }}>{unit}</div>}
      </div>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        {delta !== undefined && (
          <div style={{
            display: 'inline-flex', alignItems: 'center', gap: 4,
            color: positive ? '#34c759' : '#ff3b30', fontSize: 12, fontWeight: 700,
            fontFamily: 'JetBrains Mono, monospace',
          }}>
            {positive ? <Icon.up /> : <Icon.down />}
            {Math.abs(delta)}%
            <span style={{ color: 'rgba(245,243,239,0.45)', fontWeight: 500, marginLeft: 4 }}>vs prev</span>
          </div>
        )}
        {spark && <Spark data={spark} />}
      </div>
    </div>
  );
}

// ── Card primitive (used to frame every section) ───────────────────────
function Card({ title, subtitle, right, children, pad, style }) {
  return (
    <div style={{
      background: '#141414',
      border: '1px solid rgba(255,255,255,0.08)',
      borderRadius: 14, overflow: 'hidden', ...style,
    }}>
      {(title || right) && (
        <div style={{
          padding: `${pad - 4}px ${pad}px`,
          borderBottom: '1px solid rgba(255,255,255,0.06)',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          gap: 16, minHeight: 48,
        }}>
          <div>
            {title && <div style={{
              fontFamily: 'Archivo, sans-serif', fontWeight: 800,
              fontSize: 15, letterSpacing: '-0.01em', color: '#f5f3ef',
            }}>{title}</div>}
            {subtitle && <div style={{
              marginTop: 2, fontSize: 12, color: 'rgba(245,243,239,0.55)',
            }}>{subtitle}</div>}
          </div>
          {right}
        </div>
      )}
      {children}
    </div>
  );
}

// ── Reusable table ─────────────────────────────────────────────────────
function Table({ rows, cols, density, onRowClick }) {
  const D = DENSITY[density];
  return (
    <div>
      <div style={{
        display: 'grid', gridTemplateColumns: cols.map(c => c.w).join(' '),
        padding: `10px ${D.cardPad}px`, borderBottom: '1px solid rgba(255,255,255,0.06)',
        fontFamily: 'JetBrains Mono, monospace', fontSize: 10,
        color: 'rgba(245,243,239,0.5)', letterSpacing: '0.12em',
        textTransform: 'uppercase', fontWeight: 700, gap: 16,
      }}>
        {cols.map((c, i) => (
          <div key={i} style={{ textAlign: c.align || 'left' }}>{c.label}</div>
        ))}
      </div>
      <div>
        {rows.map((row, i) => (
          <div key={row.id || i} onClick={() => onRowClick && onRowClick(row)} style={{
            display: 'grid', gridTemplateColumns: cols.map(c => c.w).join(' '),
            padding: `0 ${D.cardPad}px`,
            height: D.rowH,
            alignItems: 'center',
            borderBottom: i < rows.length - 1 ? '1px solid rgba(255,255,255,0.04)' : 'none',
            fontSize: D.fs, color: 'rgba(245,243,239,0.8)',
            cursor: onRowClick ? 'pointer' : 'default', gap: 16,
            transition: 'background .1s',
          }}
          onMouseEnter={e => { if (onRowClick) e.currentTarget.style.background = 'rgba(255,255,255,0.02)'; }}
          onMouseLeave={e => { if (onRowClick) e.currentTarget.style.background = 'transparent'; }}
          >
            {cols.map((c, j) => (
              <div key={j} style={{ textAlign: c.align || 'left', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                {c.render(row)}
              </div>
            ))}
          </div>
        ))}
      </div>
    </div>
  );
}

// ── Bigger chart (used on Overview) ────────────────────────────────────
function BigChart({ data }) {
  const w = 720, h = 200;
  const max = Math.max(...data, 1);
  const barW = (w - 20) / data.length - 4;
  return (
    <svg viewBox={`0 0 ${w} ${h}`} style={{ width: '100%', height: 200, display: 'block' }}>
      {[0.25, 0.5, 0.75, 1].map((r, i) => (
        <line key={i} x1="0" x2={w} y1={h - h * r} y2={h - h * r} stroke="rgba(255,255,255,0.05)" strokeDasharray="2 4" />
      ))}
      {data.map((v, i) => {
        const bh = (v / max) * (h - 20);
        return (
          <rect key={i} x={10 + i * (barW + 4)} y={h - bh} width={barW} height={bh}
            rx="2" fill="#ff5a1f" opacity={i >= data.length - 7 ? 1 : 0.35} />
        );
      })}
    </svg>
  );
}

// ── Sidebar ────────────────────────────────────────────────────────────
function Sidebar({ page, setPage, role, setRole }) {
  const items = [
    { id: 'overview',    label: 'Overview',    icon: Icon.dash,    roles: ['all','kyle','chad','aden','max'] },
    { id: 'signups',     label: 'Signups',     icon: Icon.inbox,   roles: ['all','kyle','aden'], badge: 18 },
    { id: 'customers',   label: 'Customers',   icon: Icon.users,   roles: ['all','kyle','aden','max'] },
    { id: 'campaigns',   label: 'Campaigns',   icon: Icon.mail,    roles: ['all','kyle','aden'] },
    { id: 'production',  label: 'Production',  icon: Icon.press,   roles: ['all','chad','kyle'], badge: 6 },
    { id: 'attribution', label: 'Attribution', icon: Icon.phone,   roles: ['all','kyle','aden'] },
    { id: 'finance',     label: 'Finance',     icon: Icon.finance, roles: ['all','max','kyle'] },
  ];
  const roles = [
    { id: 'all',  label: 'All' },
    { id: 'kyle', label: 'Kyle' },
    { id: 'chad', label: 'Chad' },
    { id: 'aden', label: 'Aden' },
    { id: 'max',  label: 'Max' },
  ];

  return (
    <aside style={{
      width: 232, flexShrink: 0,
      background: '#0a0a0a',
      borderRight: '1px solid rgba(255,255,255,0.08)',
      padding: '24px 16px',
      display: 'flex', flexDirection: 'column', gap: 24,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '4px 6px' }}>
        <div style={{
          width: 32, height: 32, background: '#ff5a1f', borderRadius: 4,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: '#000', fontWeight: 900, fontSize: 16, transform: 'rotate(-3deg)',
          fontFamily: 'Archivo, sans-serif',
        }}>P</div>
        <div style={{
          fontFamily: 'Archivo, sans-serif', fontWeight: 900,
          fontSize: 15, letterSpacing: '-0.02em', textTransform: 'uppercase',
          color: '#f5f3ef', lineHeight: 1.1,
        }}>
          Print &amp; Send
          <div style={{
            fontSize: 9, fontFamily: 'JetBrains Mono, monospace',
            color: '#ff5a1f', fontWeight: 700, letterSpacing: '0.14em',
            textTransform: 'uppercase', marginTop: 2,
          }}>Admin · v0.4</div>
        </div>
      </div>

      <div>
        <div style={{
          fontFamily: 'JetBrains Mono, monospace', fontSize: 10,
          color: 'rgba(245,243,239,0.45)', letterSpacing: '0.14em',
          textTransform: 'uppercase', padding: '0 6px 10px', fontWeight: 700,
        }}>Scope</div>
        <div style={{ display: 'flex', gap: 4, padding: 3, background: '#141414', borderRadius: 8, border: '1px solid rgba(255,255,255,0.06)' }}>
          {roles.map(r => (
            <button key={r.id} onClick={() => setRole(r.id)} style={{
              flex: 1, padding: '6px 0', border: 'none',
              background: role === r.id ? '#ff5a1f' : 'transparent',
              color: role === r.id ? '#0a0a0a' : 'rgba(245,243,239,0.7)',
              fontFamily: 'Inter, sans-serif', fontSize: 11, fontWeight: 700,
              borderRadius: 6, cursor: 'pointer', transition: 'background .12s',
            }}>{r.label}</button>
          ))}
        </div>
      </div>

      <nav style={{ display: 'flex', flexDirection: 'column', gap: 2, flex: 1 }}>
        <div style={{
          fontFamily: 'JetBrains Mono, monospace', fontSize: 10,
          color: 'rgba(245,243,239,0.45)', letterSpacing: '0.14em',
          textTransform: 'uppercase', padding: '0 6px 10px', fontWeight: 700,
        }}>Workspace</div>
        {items.filter(it => role === 'all' || it.roles.includes(role)).map(it => {
          const active = page === it.id;
          const IconC = it.icon;
          return (
            <button key={it.id} onClick={() => setPage(it.id)} style={{
              display: 'flex', alignItems: 'center', gap: 10,
              padding: '9px 12px', border: 'none',
              background: active ? 'rgba(255,90,31,0.12)' : 'transparent',
              color: active ? '#ff5a1f' : 'rgba(245,243,239,0.75)',
              fontFamily: 'Inter, sans-serif', fontSize: 13, fontWeight: active ? 600 : 500,
              textAlign: 'left', borderRadius: 7, cursor: 'pointer',
              position: 'relative', transition: 'background .12s, color .12s',
            }}>
              <IconC />
              <span style={{ flex: 1 }}>{it.label}</span>
              {it.badge && (
                <span style={{
                  background: active ? '#ff5a1f' : 'rgba(255,90,31,0.18)',
                  color: active ? '#0a0a0a' : '#ff5a1f',
                  fontSize: 10, fontWeight: 800, fontFamily: 'JetBrains Mono, monospace',
                  padding: '1px 6px', borderRadius: 999, minWidth: 20, textAlign: 'center',
                }}>{it.badge}</span>
              )}
            </button>
          );
        })}
      </nav>

      <div style={{
        padding: '14px 14px', background: '#141414',
        border: '1px solid rgba(255,255,255,0.08)', borderRadius: 10,
        display: 'flex', flexDirection: 'column', gap: 6,
      }}>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 8,
          fontFamily: 'JetBrains Mono, monospace', fontSize: 10,
          color: '#ff5a1f', fontWeight: 700, letterSpacing: '0.12em',
          textTransform: 'uppercase',
        }}>
          <span style={{ width: 6, height: 6, borderRadius: 999, background: '#34c759', boxShadow: '0 0 6px #34c75988' }} />
          Kent facility · Online
        </div>
        <div style={{ fontSize: 12, color: 'rgba(245,243,239,0.65)', lineHeight: 1.4 }}>
          Press 1 &amp; 2 running. Next pickup Tue 4:00pm.
        </div>
      </div>
    </aside>
  );
}

// ── Top bar ────────────────────────────────────────────────────────────
function Topbar({ title, subtitle, right, density }) {
  const D = DENSITY[density];
  return (
    <header style={{
      padding: `${D.sectPad}px ${D.sectPad + 8}px`,
      borderBottom: '1px solid rgba(255,255,255,0.08)',
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      gap: 24, background: '#0a0a0a', position: 'sticky', top: 0, zIndex: 5,
    }}>
      <div style={{ minWidth: 0 }}>
        <h1 style={{
          margin: 0, fontFamily: 'Archivo, sans-serif', fontWeight: 900,
          fontSize: 28, letterSpacing: '-0.025em', color: '#f5f3ef', lineHeight: 1,
        }}>{title}</h1>
        {subtitle && <div style={{
          marginTop: 6, fontSize: 13, color: 'rgba(245,243,239,0.6)',
        }}>{subtitle}</div>}
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{
          display: 'flex', alignItems: 'center', gap: 8,
          padding: '8px 12px', background: '#141414',
          border: '1px solid rgba(255,255,255,0.08)', borderRadius: 8,
          color: 'rgba(245,243,239,0.45)', fontSize: 12, minWidth: 240,
        }}>
          <Icon.search />
          <span>Search signups, customers, campaigns…</span>
          <span style={{ marginLeft: 'auto', fontFamily: 'JetBrains Mono, monospace', fontSize: 10,
            padding: '2px 6px', background: 'rgba(255,255,255,0.05)', borderRadius: 4,
          }}>⌘K</span>
        </div>
        {right}
      </div>
    </header>
  );
}

Object.assign(window, {
  DATA, DENSITY, Icon, Status, Spark, Kpi, Card, Table, BigChart, Sidebar, Topbar,
  fmtMoney, fmtNum, relTime, mono, btnPrimary, btnSecondary,
});
