// Shared UI primitives for the prototype
// palette, buttons, chips, cards, nav shell, hours ring, etc.

function buildPal(tweaks) {
  const t = tweaks;
  const dark = t.theme === 'dark';
  return dark ? {
    bg: '#0b1120', card: '#0f1923', warm: '#141d2b', border: '#1e2d3d',
    navy: '#e6edf3', text: '#b0bec5', textStrong: '#e6edf3', muted: '#7a8b99', dim: '#4a5d70',
    accent: t.accent, success: '#3fb950', warn: '#e7b56b', danger: '#e47070',
    ringTrack: '#1e2d3d',
    chipBg: 'rgba(143,170,184,0.1)',
    onAccent: '#0b1120',
    dark: true,
  } : {
    bg: '#f8f5f0', card: '#ffffff', warm: '#f8f5f0', border: '#dde4ea',
    navy: '#12253d', text: '#3a3a3a', textStrong: '#12253d', muted: '#6b7c8a', dim: '#a8b5c0',
    accent: t.accent, success: '#2a7d5f', warn: '#c26a3a', danger: '#b54545',
    ringTrack: '#dde4ea',
    chipBg: 'rgba(18,37,61,0.06)',
    onAccent: '#ffffff',
    dark: false,
  };
}
window.buildPal = buildPal;

function hexToRgb(hex) {
  const h = (hex || '#000').replace('#', '');
  const n = parseInt(h.length === 3 ? h.split('').map(c => c + c).join('') : h, 16);
  return `${(n >> 16) & 255},${(n >> 8) & 255},${n & 255}`;
}
window.hexToRgb = hexToRgb;

function Kicker({ pal, children, color }) {
  return (
    <div style={{
      fontSize: 11, fontWeight: 700, letterSpacing: '0.14em', textTransform: 'uppercase',
      color: color || pal.accent, marginBottom: 10,
    }}>{children}</div>
  );
}

function Display({ pal, children, size = 42, style }) {
  return (
    <h1 style={{
      fontFamily: "'Playfair Display', serif", fontSize: size, fontWeight: 800,
      color: pal.navy, letterSpacing: '-0.025em', lineHeight: 1.05, margin: 0,
      ...style,
    }}>{children}</h1>
  );
}

function Card({ pal, children, style, padding }) {
  return (
    <div style={{
      background: pal.card, border: `1px solid ${pal.border}`, borderRadius: 14,
      boxShadow: pal.dark ? '0 1px 3px rgba(0,0,0,0.3)' : '0 1px 3px rgba(18,37,61,0.04)',
      padding: padding || 0,
      ...style,
    }}>{children}</div>
  );
}

function CardHead({ pal, label, action, onAction }) {
  return (
    <div style={{ padding: '18px 24px', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
      <div style={{ fontFamily: "'Playfair Display', serif", fontSize: 18, fontWeight: 700, color: pal.navy, letterSpacing: '-0.01em' }}>{label}</div>
      {action && <a onClick={onAction} style={{ fontSize: 12, color: pal.accent, fontWeight: 600, cursor: 'pointer' }}>{action} →</a>}
    </div>
  );
}

function BtnPrimary({ pal, children, onClick, style, disabled }) {
  return (
    <button onClick={onClick} disabled={disabled} style={{
      padding: '11px 22px', fontSize: 13, fontWeight: 700,
      background: pal.accent, color: pal.onAccent,
      border: 'none', borderRadius: 100, cursor: disabled ? 'not-allowed' : 'pointer',
      opacity: disabled ? 0.5 : 1,
      fontFamily: 'inherit', letterSpacing: '0.01em',
      ...style,
    }}>{children}</button>
  );
}

function BtnGhost({ pal, children, onClick, style, active }) {
  return (
    <button onClick={onClick} style={{
      padding: '10px 18px', fontSize: 13, fontWeight: 600,
      background: active ? pal.chipBg : 'transparent', color: pal.textStrong,
      border: `1px solid ${pal.border}`, borderRadius: 100, cursor: 'pointer',
      fontFamily: 'inherit',
      ...style,
    }}>{children}</button>
  );
}

function BtnText({ pal, children, onClick, style }) {
  return (
    <button onClick={onClick} style={{
      padding: '6px 2px', fontSize: 12, fontWeight: 600,
      background: 'transparent', color: pal.accent,
      border: 'none', cursor: 'pointer',
      fontFamily: 'inherit', ...style,
    }}>{children}</button>
  );
}

function Pill({ pal, children, active, onClick, tone }) {
  const rgb = hexToRgb(pal.accent);
  const bg = active ? `rgba(${rgb},0.16)` : pal.chipBg;
  const fg = active ? pal.accent : pal.muted;
  return (
    <button onClick={onClick} style={{
      padding: '6px 14px', fontSize: 12, fontWeight: 600,
      background: bg, color: fg, border: 'none', borderRadius: 20,
      cursor: 'pointer', fontFamily: 'inherit', letterSpacing: '0.01em',
    }}>{children}</button>
  );
}

function TierBadge({ pal, tier }) {
  const rgb = hexToRgb(pal.accent);
  const styles = {
    Essentials: { bg: 'rgba(143,170,184,0.14)', fg: pal.muted },
    Growth: { bg: `rgba(${rgb},0.16)`, fg: pal.accent },
    Stewardship: { bg: 'rgba(231,181,107,0.18)', fg: '#e7b56b' },
  };
  const s = styles[tier] || styles.Essentials;
  return (
    <span style={{
      fontSize: 10, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase',
      padding: '3px 10px', borderRadius: 12, background: s.bg, color: s.fg,
    }}>{tier}</span>
  );
}

function StatusChip({ pal, s, size }) {
  const rgb = hexToRgb(pal.accent);
  const map = {
    'In progress': { bg: `rgba(${rgb},0.14)`, fg: pal.accent },
    'Awaiting you': { bg: 'rgba(231,181,107,0.16)', fg: '#e7b56b' },
    'Done': { bg: 'rgba(63,185,80,0.14)', fg: pal.success },
    'Queued': { bg: 'rgba(143,170,184,0.14)', fg: pal.muted },
    'New': { bg: `rgba(${rgb},0.14)`, fg: pal.accent },
  };
  const c = map[s] || map.Queued;
  const big = size === 'lg';
  return (
    <span style={{
      fontSize: big ? 11 : 9, fontWeight: 700,
      letterSpacing: '0.08em', textTransform: 'uppercase',
      padding: big ? '4px 10px' : '2px 8px', borderRadius: big ? 12 : 10,
      background: c.bg, color: c.fg, display: 'inline-block',
    }}>{s}</span>
  );
}

function HealthDot({ pal, status, label }) {
  const color = status === 'good' ? pal.success : status === 'warn' ? '#e7b56b' : '#e47070';
  const txt = label || (status === 'good' ? 'All good' : status === 'warn' ? 'Needs check' : 'Action');
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
      <span style={{ width: 8, height: 8, borderRadius: '50%', background: color, boxShadow: `0 0 0 3px ${color}22` }} />
      <span style={{ fontSize: 12, color: pal.muted }}>{txt}</span>
    </div>
  );
}

function Input({ pal, style, ...props }) {
  return (
    <input {...props} style={{
      padding: '10px 14px', fontSize: 13, border: `1px solid ${pal.border}`,
      background: pal.warm, color: pal.textStrong, borderRadius: 10,
      outline: 'none', fontFamily: 'inherit', width: '100%',
      ...style,
    }} />
  );
}

function Textarea({ pal, style, ...props }) {
  return (
    <textarea {...props} style={{
      padding: '12px 14px', fontSize: 13, border: `1px solid ${pal.border}`,
      background: pal.warm, color: pal.textStrong, borderRadius: 10,
      outline: 'none', fontFamily: 'inherit', width: '100%',
      minHeight: 96, resize: 'vertical',
      ...style,
    }} />
  );
}

function KV({ pal, label, v, mono }) {
  return (
    <div>
      <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.08em', textTransform: 'uppercase', color: pal.muted, marginBottom: 3 }}>{label}</div>
      <div style={{ fontSize: 13, color: pal.textStrong, fontWeight: 600, fontFamily: mono ? "'JetBrains Mono', ui-monospace, monospace" : 'inherit' }}>{v}</div>
    </div>
  );
}

function HoursRing({ pal, used, total, size = 176 }) {
  const left = total - used;
  const pct = Math.min(used / total, 1);
  const R = size / 2 - 16, C = 2 * Math.PI * R, cx = size / 2;
  return (
    <div style={{ position: 'relative', width: size, height: size, flexShrink: 0 }}>
      <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
        <circle cx={cx} cy={cx} r={R} stroke={pal.ringTrack} strokeWidth="10" fill="none" />
        <circle cx={cx} cy={cx} r={R} stroke={pal.accent} strokeWidth="10" fill="none"
          strokeLinecap="round" strokeDasharray={C} strokeDashoffset={C * (1 - pct)}
          transform={`rotate(-90 ${cx} ${cx})`} style={{ transition: 'stroke-dashoffset 0.5s ease' }} />
      </svg>
      <div style={{ position: 'absolute', inset: 0, display: 'grid', placeItems: 'center', textAlign: 'center' }}>
        <div>
          <div style={{ fontFamily: "'Playfair Display', serif", fontSize: size * 0.22, fontWeight: 800, color: pal.navy, lineHeight: 1 }}>
            {left.toFixed(2)}
          </div>
          <div style={{ fontSize: 10, color: pal.muted, marginTop: 4, letterSpacing: '0.08em', textTransform: 'uppercase' }}>hrs remaining</div>
        </div>
      </div>
    </div>
  );
}

function HoursBar({ pal, used, total, segments, compact }) {
  const segs = segments ?? Math.max(Math.round(total * 2), 4);
  return (
    <div>
      <div style={{ display: 'flex', gap: 3, height: compact ? 6 : 10 }}>
        {Array.from({ length: segs }).map((_, i) => {
          const segVal = (i + 1) / segs * total;
          const filled = segVal <= used + 0.001;
          return (
            <div key={i} style={{
              flex: 1, borderRadius: 2,
              background: filled ? pal.accent : pal.border,
              transition: 'background 0.2s',
            }} />
          );
        })}
      </div>
    </div>
  );
}

function EmptyState({ pal, title, body, icon, action, onAction }) {
  return (
    <div style={{ padding: '60px 24px', textAlign: 'center' }}>
      {icon && <div style={{ fontSize: 32, color: pal.accent, marginBottom: 16, opacity: 0.8 }}>{icon}</div>}
      <div style={{ fontFamily: "'Playfair Display', serif", fontSize: 22, fontWeight: 700, color: pal.navy, marginBottom: 8 }}>{title}</div>
      <div style={{ fontSize: 14, color: pal.muted, maxWidth: 440, margin: '0 auto 20px', lineHeight: 1.6, fontWeight: 300 }}>{body}</div>
      {action && <BtnPrimary pal={pal} onClick={onAction}>{action}</BtnPrimary>}
    </div>
  );
}

// Top-level app shell: nav sidebar + content area
function AppShell({ pal, nav, setNav, children, onNewRequest, jm, compact, view, setView, user }) {
  const items = [
    ['overview','Overview','◈'],
    ['requests','Requests','⊞'],
    ['resources','Resources','☰'],
    ['activity','Activity','≡'],
    ['messages','Messages','✉'],
    ['billing','Billing','$'],
  ];
  const isAdmin = view === 'admin';
  return (
    <div style={{ minHeight: '100vh', background: pal.bg, color: pal.text, display: 'flex', flexDirection: 'column' }}>
      <TopBar pal={pal} view={view} setView={setView} user={user} />
      <div style={{ display: 'flex', flex: 1, minHeight: 0 }}>
        {!isAdmin && (
          <Sidebar pal={pal} nav={nav} setNav={setNav} items={items} onNewRequest={onNewRequest} jm={jm} />
        )}
        <div style={{ flex: 1, overflow: 'auto', minWidth: 0 }}>
          {children}
        </div>
      </div>
    </div>
  );
}

function TopBar({ pal, view, setView, user }) {
  return (
    <div style={{
      height: 62, padding: '0 28px', flexShrink: 0,
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      borderBottom: `1px solid ${pal.border}`, background: pal.card,
    }}>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 20 }}>
        <div style={{ fontFamily: "'Playfair Display', serif", fontSize: 20, fontWeight: 800, color: pal.navy, letterSpacing: '-0.02em' }}>
          State of <em style={{ color: pal.accent, fontStyle: 'italic' }}>Motion</em>
        </div>
        <div style={{ fontSize: 11, color: pal.muted, textTransform: 'uppercase', letterSpacing: '0.12em' }}>Client Portal</div>
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
        <div style={{ display: 'flex', background: pal.warm, borderRadius: 100, padding: 3, border: `1px solid ${pal.border}` }}>
          {[['admin','Admin'],['client','Client view']].map(([v,l]) => (
            <button key={v} onClick={() => setView(v)} style={{
              padding: '6px 14px', fontSize: 12, fontWeight: 600,
              border: 'none', cursor: 'pointer', borderRadius: 100,
              background: view === v ? pal.accent : 'transparent',
              color: view === v ? pal.onAccent : pal.muted,
              fontFamily: 'inherit',
            }}>{l}</button>
          ))}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, fontSize: 13, color: pal.muted }}>
          <div style={{ width: 30, height: 30, borderRadius: '50%', background: pal.accent, color: pal.onAccent, display: 'grid', placeItems: 'center', fontSize: 11, fontWeight: 800 }}>{user.initials}</div>
          <span style={{ color: pal.textStrong, fontWeight: 500 }}>{user.name}</span>
        </div>
      </div>
    </div>
  );
}

function Sidebar({ pal, nav, setNav, items, onNewRequest, jm }) {
  const plan = window.JOY_MOVE.plans[window.TWEAKS.tier] || Object.values(window.JOY_MOVE.plans)[0];
  const cycle = window.JOY_MOVE.cycle;
  const brand = window.JOY_MOVE.brand;
  const filler = window.TWEAKS.demo !== 'clean';
  const used = filler ? Math.min(cycle.hoursUsed, plan.hoursIncluded) : 0;
  // Split client name into first / rest so we can italicize the second word
  const nameParts = brand.name.split(/\s+/);
  const firstWord = nameParts[0];
  const restWord = nameParts.slice(1).join(' ');
  return (
    <div style={{
      width: 232, flexShrink: 0,
      borderRight: `1px solid ${pal.border}`, background: pal.card,
      padding: '24px 0', display: 'flex', flexDirection: 'column',
    }}>
      {/* Client chip */}
      <div style={{ padding: '0 20px 20px', borderBottom: `1px solid ${pal.border}`, marginBottom: 16 }}>
        <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: pal.muted, marginBottom: 6 }}>Client</div>
        {brand.logo ? (
          <img src={brand.logo} alt={brand.name} style={{ maxHeight: 32, maxWidth: '100%', display: 'block', filter: pal.bg.match(/^#0/) ? 'none' : 'none' }} />
        ) : (
          <div style={{ fontFamily: "'Playfair Display', serif", fontSize: 20, fontWeight: 700, color: pal.navy, letterSpacing: '-0.01em', lineHeight: 1.15 }}>
            {firstWord}
            {restWord && <> <em style={{ color: pal.accent }}>{restWord}</em></>}
          </div>
        )}
        <div style={{ fontSize: 11, color: pal.muted, marginTop: 2 }}>{brand.site}</div>
      </div>

      <BtnPrimary pal={pal} onClick={onNewRequest} style={{ margin: '0 20px 18px', padding: '10px 16px', fontSize: 13, borderRadius: 10 }}>
        + New request
      </BtnPrimary>

      <div style={{ flex: 1 }}>
        {items.map(([id, label, icon]) => (
          <button key={id} onClick={() => setNav(id)} style={{
            display: 'flex', alignItems: 'center', gap: 12,
            width: '100%', border: 'none', background: 'transparent',
            padding: '11px 24px',
            fontSize: 13, fontWeight: nav === id ? 700 : 500,
            color: nav === id ? pal.textStrong : pal.muted,
            cursor: 'pointer', textAlign: 'left',
            borderLeft: nav === id ? `2px solid ${pal.accent}` : '2px solid transparent',
            fontFamily: 'inherit',
          }}>
            <span style={{ fontSize: 13, opacity: 0.7, color: nav === id ? pal.accent : pal.dim }}>{icon}</span>
            {label}
          </button>
        ))}
      </div>

      <div style={{ padding: '16px 20px', borderTop: `1px solid ${pal.border}` }}>
        <div style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.1em', textTransform: 'uppercase', color: pal.muted, marginBottom: 8 }}>Cycle · {cycle.periodLabel}</div>
        <HoursBar pal={pal} used={used} total={plan.hoursIncluded} segments={plan.hoursIncluded * 2} compact />
        <div style={{ marginTop: 8, display: 'flex', justifyContent: 'space-between', fontSize: 11 }}>
          <span style={{ color: pal.muted }}>{used.toFixed(2)} / {plan.hoursIncluded}</span>
          <span style={{ color: pal.accent, fontWeight: 600 }}>{(plan.hoursIncluded - used).toFixed(2)} left</span>
        </div>
      </div>
    </div>
  );
}

window.Kicker = Kicker;
window.Display = Display;
window.Card = Card;
window.CardHead = CardHead;
window.BtnPrimary = BtnPrimary;
window.BtnGhost = BtnGhost;
window.BtnText = BtnText;
window.Pill = Pill;
window.TierBadge = TierBadge;
window.StatusChip = StatusChip;
window.HealthDot = HealthDot;
window.Input = Input;
window.Textarea = Textarea;
window.KV = KV;
window.HoursRing = HoursRing;
window.HoursBar = HoursBar;
window.EmptyState = EmptyState;
window.AppShell = AppShell;
