// ui.jsx — shell + shared UI components
const { useState: useStateU } = React;

// ── Line icons (simple stroke set) ───────────────────────────────────
const ICONS = {
  overview: 'M3 13h8V3H3v10zm10 8h8V3h-8v18zM3 21h8v-6H3v6z',
  users: 'M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2 M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8 M23 21v-2a4 4 0 0 0-3-3.87 M16 3.13a4 4 0 0 1 0 7.75',
  households: 'M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z M9 22V12h6v10',
  engagement: 'M22 12h-4l-3 9L9 3l-3 9H2',
  content: 'M4 19.5A2.5 2.5 0 0 1 6.5 17H20 M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z',
  impact: 'M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.48 19 2c1 2 2 4.18 2 8 0 5.5-4.78 10-10 10z M2 21c0-3 1.85-5.36 5.08-6',
  revenue: 'M12 1v22 M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6',
  costs: 'M21 12V7H5a2 2 0 0 1 0-4h14v4 M3 5v14a2 2 0 0 0 2 2h16v-5 M18 12a2 2 0 0 0 0 4h4v-4z',
  geo: 'M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z M12 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6z',
  system: 'M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20z M12 8v4l3 2',
  search: 'M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16z M21 21l-4.3-4.3',
  bell: 'M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9 M13.7 21a2 2 0 0 1-3.4 0',
  arrowUp: 'M12 19V5 M5 12l7-7 7 7',
  arrowDown: 'M12 5v14 M5 12l7 7 7-7',
  download: 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 M7 10l5 5 5-5 M12 15V3',
  chevron: 'M9 18l6-6-6-6',
  dot: 'M12 12m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0',
  ext: 'M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6 M15 3h6v6 M10 14L21 3',
};
function Icon({ name, size = 18, sw = 1.7, color = 'currentColor', fill = 'none' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={fill} stroke={color} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink: 0 }}>
      {ICONS[name].split(' M').map((seg, i) => <path key={i} d={(i ? 'M' : '') + seg} />)}
    </svg>
  );
}

function Logo({ size = 30 }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
      <div style={{
        width: size, height: size, borderRadius: 9, flexShrink: 0,
        background: 'linear-gradient(135deg, var(--accent), var(--accent-2))',
        display: 'grid', placeItems: 'center', boxShadow: 'var(--glow)',
      }}>
        <svg width={size * 0.56} height={size * 0.56} viewBox="0 0 24 24" fill="none" stroke="var(--accent-ink)" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M6 2v6a3 3 0 0 0 3 3 M9 2v9 M18 2c-1.5 0-3 1.5-3 4s0 5 0 5 M15 2v9 M9 11v11 M15 11v11" />
        </svg>
      </div>
    </div>
  );
}

// ── Card ─────────────────────────────────────────────────────────────
function Card({ children, title, sub, right, pad = 18, span, style, className }) {
  return (
    <section className={'pw-card ' + (className || '')} style={{
      background: 'var(--card)', border: '1px solid var(--line)', borderRadius: 16,
      padding: pad, boxShadow: 'var(--shadow)', gridColumn: span ? `span ${span}` : undefined,
      display: 'flex', flexDirection: 'column', minWidth: 0, ...style,
    }}>
      {(title || right) && (
        <header style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12, marginBottom: 16 }}>
          <div style={{ minWidth: 0 }}>
            {title && <h3 style={{ margin: 0, fontSize: 14.5, fontWeight: 700, color: 'var(--ink)', letterSpacing: '-0.01em' }}>{title}</h3>}
            {sub && <p style={{ margin: '4px 0 0', fontSize: 12.5, color: 'var(--ink-3)' }}>{sub}</p>}
          </div>
          {right && <div style={{ flexShrink: 0 }}>{right}</div>}
        </header>
      )}
      {children}
    </section>
  );
}

// ── Delta pill (up/down %) ───────────────────────────────────────────
function Delta({ value, suffix = '%', invert = false }) {
  if (value === 0 || value == null) return <span style={{ fontSize: 12, color: 'var(--ink-3)', fontWeight: 600 }}>—</span>;
  const up = value > 0;
  const good = invert ? !up : up;
  const col = good ? 'var(--pos)' : 'var(--neg)';
  const bg = good ? 'var(--pos-soft)' : 'var(--neg-soft)';
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 3, fontSize: 12, fontWeight: 700, color: col, background: bg, padding: '3px 7px', borderRadius: 7 }}>
      <Icon name={up ? 'arrowUp' : 'arrowDown'} size={12} sw={2.4} color={col} />
      {Math.abs(value)}{suffix}
    </span>
  );
}

// ── KPI stat card ────────────────────────────────────────────────────
function StatCard({ label, value, delta, spark, sparkColor = 'var(--accent)', sub, invert, accent, prefix, suffix }) {
  return (
    <div style={{
      background: 'var(--card)', border: '1px solid var(--line)', borderRadius: 15, padding: 16,
      boxShadow: 'var(--shadow)', display: 'flex', flexDirection: 'column', gap: 4, minWidth: 0, position: 'relative', overflow: 'hidden',
    }}>
      {accent && <div style={{ position: 'absolute', left: 0, top: 14, bottom: 14, width: 3, borderRadius: 3, background: accent }}></div>}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>
        <span style={{ fontSize: 12.5, color: 'var(--ink-3)', fontWeight: 600, letterSpacing: '0.01em' }}>{label}</span>
        {delta != null && <Delta value={delta} invert={invert} />}
      </div>
      <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 10 }}>
        <div style={{ fontSize: 27, fontWeight: 800, color: 'var(--ink)', letterSpacing: '-0.02em', lineHeight: 1.05, fontVariantNumeric: 'tabular-nums' }}>
          {prefix}{value}{suffix && <span style={{ fontSize: 15, color: 'var(--ink-3)', fontWeight: 700 }}>{suffix}</span>}
        </div>
        {spark && <Sparkline data={spark} color={sparkColor} w={84} h={32} />}
      </div>
      {sub && <span style={{ fontSize: 11.5, color: 'var(--ink-3)' }}>{sub}</span>}
    </div>
  );
}

// ── Badge ────────────────────────────────────────────────────────────
function Badge({ children, tone = 'neutral' }) {
  const map = {
    neutral: ['var(--ink-2)', 'var(--line-2)'],
    pos: ['var(--pos)', 'var(--pos-soft)'],
    neg: ['var(--neg)', 'var(--neg-soft)'],
    warn: ['var(--warn)', 'var(--warn-soft)'],
    info: ['var(--info)', 'var(--info-soft)'],
    accent: ['var(--accent)', 'var(--accent-soft)'],
  };
  const [c, b] = map[tone] || map.neutral;
  return <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, fontSize: 11.5, fontWeight: 700, color: c, background: b, padding: '3px 9px', borderRadius: 20, whiteSpace: 'nowrap' }}>{children}</span>;
}

// ── Segmented control ────────────────────────────────────────────────
function Segmented({ options, value, onChange, size = 'md' }) {
  const py = size === 'sm' ? '5px' : '7px';
  const fs = size === 'sm' ? 12 : 12.5;
  return (
    <div style={{ display: 'inline-flex', background: 'var(--card-2)', border: '1px solid var(--line)', borderRadius: 10, padding: 3, gap: 2 }}>
      {options.map(o => {
        const active = o.value === value;
        return (
          <button key={o.value} onClick={() => onChange(o.value)} style={{
            border: 'none', cursor: 'pointer', borderRadius: 7, padding: `${py} 11px`, fontSize: fs, fontWeight: 600,
            fontFamily: 'inherit', display: 'inline-flex', alignItems: 'center', gap: 6,
            background: active ? 'var(--card)' : 'transparent', color: active ? 'var(--ink)' : 'var(--ink-3)',
            boxShadow: active ? 'var(--shadow)' : 'none', transition: 'all .15s',
          }}>{o.icon}{o.label}</button>
        );
      })}
    </div>
  );
}

// ── Sidebar ──────────────────────────────────────────────────────────
function Sidebar({ page, setPage, lang, collapsed, onLogout }) {
  const groups = [
    { g: 'nav_groups_main', items: ['overview'] },
    { g: 'nav_groups_product', items: ['users', 'households', 'engagement', 'content'] },
    { g: 'nav_groups_business', items: ['impact', 'revenue', 'costs', 'geo'] },
    { g: 'nav_groups_ops', items: ['system'] },
  ];
  return (
    <aside style={{
      width: collapsed ? 0 : 248, flexShrink: 0, background: 'var(--sidebar)', borderRight: '1px solid var(--line)',
      display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden', transition: 'width .2s',
    }}>
      <div style={{ padding: '20px 20px 14px', display: 'flex', alignItems: 'center', gap: 11 }}>
        <Logo />
        <div style={{ lineHeight: 1.1 }}>
          <div style={{ fontSize: 16, fontWeight: 800, color: 'var(--ink)', letterSpacing: '-0.02em' }}>{tA(lang, 'brand')}</div>
          <div style={{ fontSize: 10.5, color: 'var(--ink-3)', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em' }}>{tA(lang, 'console')}</div>
        </div>
      </div>
      <nav style={{ flex: 1, overflowY: 'auto', padding: '6px 12px 20px' }}>
        {groups.map(grp => (
          <div key={grp.g} style={{ marginBottom: 14 }}>
            <div style={{ fontSize: 10.5, fontWeight: 700, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.09em', padding: '6px 10px' }}>{tA(lang, grp.g)}</div>
            {grp.items.map(key => {
              const active = page === key;
              return (
                <button key={key} onClick={() => setPage(key)} className="pw-nav" style={{
                  width: '100%', display: 'flex', alignItems: 'center', gap: 11, padding: '9px 10px', marginBottom: 1,
                  border: 'none', borderRadius: 9, cursor: 'pointer', fontFamily: 'inherit', textAlign: 'left',
                  fontSize: 13.5, fontWeight: active ? 700 : 500,
                  background: active ? 'var(--accent-soft)' : 'transparent',
                  color: active ? 'var(--accent)' : 'var(--ink-2)', transition: 'all .12s', position: 'relative',
                }}>
                  <Icon name={key} size={18} color={active ? 'var(--accent)' : 'var(--ink-3)'} />
                  {tA(lang, 'nav_' + key)}
                  {key === 'system' && <span style={{ marginLeft: 'auto', fontSize: 10.5, fontWeight: 800, color: 'var(--neg)', background: 'var(--neg-soft)', borderRadius: 10, padding: '1px 7px' }}>{SYSTEM.openBugs}</span>}
                </button>
              );
            })}
          </div>
        ))}
      </nav>
      <div style={{ padding: 14, borderTop: '1px solid var(--line)', display: 'flex', flexDirection: 'column', gap: 8 }}>
        <a href="https://pantry-wise.com/" target="_blank" rel="noopener" style={{ display: 'flex', alignItems: 'center', gap: 9, padding: '9px 10px', borderRadius: 9, textDecoration: 'none', color: 'var(--ink-2)', fontSize: 12.5, fontWeight: 600, background: 'var(--card-2)' }}>
          <Icon name="ext" size={15} color="var(--ink-3)" />
          {lang === 'fr' ? "Ouvrir l'app" : 'Open the app'}
        </a>
        {onLogout && (
          <button onClick={onLogout} style={{ display: 'flex', alignItems: 'center', gap: 9, padding: '9px 10px', borderRadius: 9, border: 'none', cursor: 'pointer', color: 'var(--ink-2)', fontSize: 12.5, fontWeight: 600, background: 'transparent', fontFamily: 'inherit', textAlign: 'left' }}>
            <Icon name="ext" size={15} color="var(--ink-3)" />
            {lang === 'fr' ? 'Se déconnecter' : 'Sign out'}
          </button>
        )}
      </div>
    </aside>
  );
}

// ── Topbar ───────────────────────────────────────────────────────────
function Topbar({ lang, setLang, theme, setTheme, period, setPeriod, title, sub }) {
  const periodOpts = [
    { value: '7d', label: tA(lang, 'p_7d') }, { value: '30d', label: tA(lang, 'p_30d') },
    { value: '90d', label: tA(lang, 'p_90d') }, { value: '12m', label: tA(lang, 'p_12m') },
  ];
  return (
    <header style={{
      display: 'flex', alignItems: 'center', gap: 16, padding: '14px 26px', borderBottom: '1px solid var(--line)',
      background: 'color-mix(in oklab, var(--panel) 86%, transparent)', backdropFilter: 'blur(10px)',
      position: 'sticky', top: 0, zIndex: 20, flexWrap: 'wrap',
    }}>
      <div style={{ minWidth: 0, marginRight: 'auto', flexShrink: 0 }}>
        <h1 style={{ margin: 0, fontSize: 19, fontWeight: 800, color: 'var(--ink)', letterSpacing: '-0.02em', lineHeight: 1.2, whiteSpace: 'nowrap' }}>{title}</h1>
        <p style={{ margin: '3px 0 0', fontSize: 12.5, color: 'var(--ink-3)', whiteSpace: 'nowrap' }}>{sub}</p>
      </div>
      <div style={{ position: 'relative', display: 'flex', alignItems: 'center', minWidth: 200, flex: '0 1 280px' }}>
        <span style={{ position: 'absolute', left: 11, display: 'flex' }}><Icon name="search" size={16} color="var(--ink-3)" /></span>
        <input placeholder={tA(lang, 'search')} style={{
          width: '100%', padding: '9px 12px 9px 34px', borderRadius: 10, border: '1px solid var(--line)',
          background: 'var(--card-2)', color: 'var(--ink)', fontSize: 13, fontFamily: 'inherit', outline: 'none',
        }} />
      </div>
      <Segmented options={periodOpts} value={period} onChange={setPeriod} size="sm" />
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        {/* theme switcher — the 3 directions */}
        <div style={{ display: 'inline-flex', gap: 4, background: 'var(--card-2)', border: '1px solid var(--line)', borderRadius: 10, padding: 4 }}>
          {Object.values(ADMIN_THEMES).map(th => (
            <button key={th.key} onClick={() => setTheme(th.key)} title={th.label[lang]} style={{
              width: 26, height: 26, borderRadius: 7, cursor: 'pointer', padding: 0,
              border: theme === th.key ? '2px solid var(--accent)' : '1px solid var(--line)',
              background: `linear-gradient(135deg, ${th.swatch[0]} 0 50%, ${th.swatch[1]} 50% 100%)`,
              outline: theme === th.key ? '2px solid var(--accent-soft)' : 'none',
            }}></button>
          ))}
        </div>
        <button onClick={() => setLang(lang === 'fr' ? 'en' : 'fr')} style={{
          padding: '8px 12px', borderRadius: 10, border: '1px solid var(--line)', background: 'var(--card-2)',
          color: 'var(--ink-2)', fontSize: 12.5, fontWeight: 700, cursor: 'pointer', fontFamily: 'inherit',
        }}>{lang === 'fr' ? 'FR' : 'EN'}</button>
        <button style={{ width: 38, height: 38, borderRadius: 10, border: '1px solid var(--line)', background: 'var(--card-2)', display: 'grid', placeItems: 'center', cursor: 'pointer', position: 'relative' }}>
          <Icon name="bell" size={17} color="var(--ink-2)" />
          <span style={{ position: 'absolute', top: 8, right: 9, width: 7, height: 7, borderRadius: 4, background: 'var(--neg)', border: '2px solid var(--panel)' }}></span>
        </button>
        <div style={{ width: 38, height: 38, borderRadius: 10, background: 'linear-gradient(135deg, var(--accent), var(--accent-2))', display: 'grid', placeItems: 'center', color: 'var(--accent-ink)', fontWeight: 800, fontSize: 14 }}>A</div>
      </div>
    </header>
  );
}

// ── Section grid helper ──────────────────────────────────────────────
function Grid({ children, cols = 12, gap = 16, style }) {
  return <div style={{ display: 'grid', gridTemplateColumns: `repeat(${cols}, 1fr)`, gap, ...style }}>{children}</div>;
}

// ── Simple data table ────────────────────────────────────────────────
function Table({ columns, rows, lang }) {
  return (
    <div style={{ overflowX: 'auto', margin: '0 -2px' }}>
      <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13 }}>
        <thead>
          <tr>{columns.map((c, i) => <th key={i} style={{ textAlign: c.align || 'left', padding: '9px 12px', fontSize: 11.5, fontWeight: 700, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.04em', borderBottom: '1px solid var(--line)', whiteSpace: 'nowrap' }}>{c.head}</th>)}</tr>
        </thead>
        <tbody>
          {rows.map((r, ri) => (
            <tr key={ri} className="pw-row" style={{ transition: 'background .12s' }}>
              {columns.map((c, ci) => <td key={ci} style={{ textAlign: c.align || 'left', padding: '11px 12px', borderBottom: '1px solid var(--line-2)', color: 'var(--ink-2)', verticalAlign: 'middle', whiteSpace: c.wrap ? 'normal' : 'nowrap' }}>{c.render(r)}</td>)}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function PageHead({ children }) {
  return <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>{children}</div>;
}

Object.assign(window, { Icon, Logo, Card, Delta, StatCard, Badge, Segmented, Sidebar, Topbar, Grid, Table, PageHead });
