// shared.jsx — data + atomic components used across all variations

// ─── Tokens (shorthand) ───────────────────────────────────────────
const T = {
  // App (light, on-course)
  bg: '#F6F5F0',
  card: '#FFFFFF',
  ink: '#1B3A2D',
  inkSub: '#5A6B5E',
  inkFaint: '#8a948e',
  primary: '#1B4D3E',
  primaryDeep: '#1B3A2D',
  secondary: '#27AE60',
  accent: '#E67E22',
  mint: '#EBF5F0',
  divider: '#E8E4DD',
  win: '#2D6A4F',
  loss: '#C0392B',
  gold: '#D4A94B',
  silver: '#9AADBD',
  bronze: '#C08B5C',
  warn: '#F2C94C',
  // Web (dark, editorial)
  webBg: '#091910',
  webBg2: '#0E2219',
  webBg3: '#1B3A2D',
  webGold: '#C9A84C',
  webGoldLight: '#D9BE6F',
  webGoldDark: '#9C7E36',
  webText: '#F0EBE0',
  webMuted: '#8E8773',
  fontApp: '"Open Sans", -apple-system, system-ui, sans-serif',
  fontDisplay: '"Playfair Display", Georgia, serif',
  fontBody: '"DM Sans", -apple-system, system-ui, sans-serif',
  fontMono: '"JetBrains Mono", ui-monospace, monospace',
};

// ─── Data ─────────────────────────────────────────────────────────
const D = {
  user: { id: 'me', name: 'Mike Lawson', first: 'Mike', initials: 'ML', hcp: 7.9, balance: 24550, ghin: '8432198' },
  players: [
    { id: 'me',    name: 'Mike Lawson', first: 'Mike',  initials: 'ML', hcp: 7.9,  color: '#1B4D3E', isMe: true },
    { id: 'sara',  name: 'Sarah Chen',  first: 'Sarah', initials: 'SC', hcp: 12.4, color: '#C9A84C' },
    { id: 'jay',   name: 'Jay Patel',   first: 'Jay',   initials: 'JP', hcp: 4.2,  color: '#7A4C2A' },
    { id: 'tom',   name: 'Tom Walker',  first: 'Tom',   initials: 'TW', hcp: 15.0, color: '#5A6B5E' },
  ],
  course: { name: 'Miami Golf Center', tee: 'Blue · 72.4/132', par: 72, holes: 18 },
  round: {
    name: 'Saturday at MGC',
    course: 'Miami Golf Center',
    tee: 'Blue tees',
    date: 'Today · 8:12am',
    hole: 7,
    holePar: 4,
    holeYards: 412,
    holeHcp: 5,
    games: ['Nassau $5/5/5', 'Skins $1', 'Wolf $1/pt'],
    nassau: { front: 'UP 1', back: 'AS', overall: 'UP 1' }, // Mike's view
    skinsPot: 350,        // $3.50 carry
    skinsHolesCarried: 3,
    pressOffer: { active: true, from: 'Jay & Tom', context: '2 DOWN on the back', amount: 500 },
  },
  // Per-player score data, holes 1..18 (parsed from gross)
  scores: {
    me:   [4,5,3,4,4,5, null, null, null, null,null,null,null,null,null,null,null,null],
    sara: [5,5,3,5,4,5, null, null, null, null,null,null,null,null,null,null,null,null],
    jay:  [4,4,3,4,4,5, null, null, null, null,null,null,null,null,null,null,null,null],
    tom:  [5,6,4,5,4,6, null, null, null, null,null,null,null,null,null,null,null,null],
  },
  pars: [4,4,3,5,4,4,4,3,5, 4,5,4,3,4,5,4,4,3],
  // Money so far
  money: { me: 1200, sara: 600, jay: -800, tom: -1000 },
  invites: [
    { id: 'inv1', from: 'Carter Hayes', host: 'Carter Hayes', course: 'Doral Blue Monster', date: 'Sun · 7:30am', reserve: 1500, games: ['Nassau $5', 'Skins $1'] },
  ],
  finished: [
    { id: 'f1', course: 'Crandon Park', date: '2 days ago', score: 78, money: 1800, win: true },
    { id: 'f2', course: 'Killian Greens', date: 'Apr 28', score: 82, money: -600, win: false },
    { id: 'f3', course: 'Biltmore', date: 'Apr 22', score: 75, money: 4200, win: true },
  ],
  tournament: {
    name: 'Summer Series 2026',
    group: 'Saturday Crew',
    rounds: [
      { id: 'r1', course: 'Miami Golf Center',  date: 'Apr 12',  status: 'Final',  myScore: 76, myPts: 38 },
      { id: 'r2', course: 'Doral Blue Monster', date: 'Apr 26',  status: 'Final',  myScore: 81, myPts: 32 },
      { id: 'r3', course: 'Crandon Park',       date: 'May 10',  status: 'Final',  myScore: 74, myPts: 41 },
      { id: 'r4', course: 'Biltmore',           date: 'May 24',  status: 'Live',   myScore: null, myPts: null },
    ],
    leaderboard: [
      { id: 'jay',   pts: 118, money:  6400 },
      { id: 'me',    pts: 111, money:  4200 },
      { id: 'sara',  pts: 104, money:    -800 },
      { id: 'tom',   pts:  92, money: -9800 },
      { id: 'p5',    name: 'Carter Hayes', initials: 'CH', pts: 89, money: -200, color: '#6E5D8F' },
      { id: 'p6',    name: 'Dani Reyes',   initials: 'DR', pts: 81, money: -1200, color: '#B85C8A' },
    ],
  },
  group: {
    name: 'Saturday Crew',
    description: 'Weekly money game, South Florida courses. No mercy.',
    inviteCode: 'SATCREW',
    members: 8,
    activity: [
      { id: 'a1', kind: 'round',    text: 'Mike beat 3 players in Nassau', detail: '+$12 · Crandon Park', when: '2d', money: 1200 },
      { id: 'a2', kind: 'tournament', text: 'Round 3 of Summer Series finalized', detail: 'Jay leads by 7 pts', when: '8d' },
      { id: 'a3', kind: 'member',   text: 'Carter Hayes joined the group', when: '12d' },
      { id: 'a4', kind: 'wager',    text: 'Sarah won a $20 press', detail: 'vs Tom · Biltmore', when: '18d', money: 2000 },
    ],
    chat: [
      { id: 'c1', who: 'jay',  text: 'Tee time confirmed 7:30am Sat', t: '8:14' },
      { id: 'c2', who: 'sara', text: 'I\'m bringing the new putter', t: '8:18' },
      { id: 'c3', who: 'me',   text: 'Press allowance set to 2 per nine', t: '8:22' },
      { id: 'c4', who: 'tom',  text: 'Down for Wolf this week?', t: '8:30' },
    ],
    events: [
      { id: 'e1', title: 'Saturday round', course: 'Crandon Park', date: 'Sat 7:30am', attending: 4, of: 8 },
      { id: 'e2', title: 'Summer Series · R4', course: 'Biltmore',  date: 'May 24', attending: 6, of: 8, tournament: true },
    ],
  },
  formats: [
    { key: 'match',   name: 'Match Play',  desc: 'Hole-by-hole, 1-up / 1-down',  popular: true },
    { key: 'stroke',  name: 'Stroke Play', desc: 'Net or gross total over 18',   popular: true },
    { key: 'nassau',  name: 'Nassau',      desc: 'F9 / B9 / Overall, +presses',  popular: true },
    { key: 'skins',   name: 'Skins',       desc: 'Low score takes the hole',     popular: true },
    { key: 'wolf',    name: 'Wolf',        desc: 'Rotating partner game',        popular: false },
    { key: 'stable',  name: 'Stableford',  desc: 'Points by score vs par',       popular: false },
    { key: 'birdie',  name: 'Birdie Pool', desc: 'Most birdies wins the pot',    popular: false },
    { key: 'bbb',     name: 'Bingo Bango Bongo', desc: '3 pts per hole',          popular: false },
    { key: 'vegas',   name: 'Vegas',       desc: 'Combine team scores',          popular: false },
    { key: 'snake',   name: 'Snake',       desc: 'Last 3-putt holds it',         popular: false },
    { key: 'hammer',  name: 'Hammer',      desc: 'Double mid-hole',              popular: false },
    { key: 'rabbit',  name: 'Rabbit',      desc: 'Hold low-score outright',      popular: false },
    { key: 'splitsix', name: 'Split Sixes', desc: '6 pts split by finish',       popular: false },
  ],
};

// ─── Money helpers ────────────────────────────────────────────────
function fmtMoney(cents, opts = {}) {
  const { sign = true, zeroDash = false } = opts;
  if (cents === 0 && zeroDash) return '—';
  const abs = Math.abs(cents / 100);
  const dec = abs % 1 === 0 ? 0 : 2;
  const s = `$${abs.toFixed(dec)}`;
  if (!sign) return s;
  if (cents < 0) return `−${s}`;
  if (cents > 0) return `+${s}`;
  return s;
}

function moneyColor(cents) {
  if (cents > 0) return T.win;
  if (cents < 0) return T.loss;
  return T.inkSub;
}

// ─── Atoms ────────────────────────────────────────────────────────
function Avatar({ player, size = 36, ring = false }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: player.color || T.primary, color: '#fff',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      font: `700 ${Math.round(size * 0.36)}px/1 ${T.fontApp}`,
      flexShrink: 0,
      boxShadow: ring ? `0 0 0 3px ${T.bg}, 0 0 0 5px ${T.mint}` : 'none',
    }}>{player.initials}</div>
  );
}

function Money({ cents, mono = true, bold = false, size = 14, sign = true }) {
  return (
    <span style={{
      color: moneyColor(cents),
      font: `${bold ? 700 : 600} ${size}px/1.2 ${mono ? T.fontMono : T.fontApp}`,
      fontVariantNumeric: 'tabular-nums',
    }}>{fmtMoney(cents, { sign })}</span>
  );
}

function Chip({ children, tone = 'default', size = 'md', style = {} }) {
  const tones = {
    default: { bg: T.mint, fg: T.primary, bd: 'transparent' },
    outline: { bg: 'transparent', fg: T.inkSub, bd: T.divider },
    accent:  { bg: '#FFEFE0', fg: T.accent, bd: 'transparent' },
    gold:    { bg: '#FBF4DA', fg: '#8C6A1B', bd: 'transparent' },
    win:     { bg: T.mint, fg: T.win, bd: 'transparent' },
    loss:    { bg: '#FBEAE7', fg: T.loss, bd: 'transparent' },
    dark:    { bg: T.primaryDeep, fg: '#fff', bd: 'transparent' },
  };
  const sizes = {
    sm: { p: '3px 8px', f: 11 },
    md: { p: '5px 10px', f: 12 },
    lg: { p: '7px 14px', f: 13 },
  };
  const c = tones[tone], s = sizes[size];
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 5,
      padding: s.p, borderRadius: 999,
      background: c.bg, color: c.fg, border: `1px solid ${c.bd}`,
      font: `600 ${s.f}px/1.2 ${T.fontApp}`,
      letterSpacing: '0.02em', whiteSpace: 'nowrap',
      ...style,
    }}>{children}</span>
  );
}

function Card({ children, style = {}, padding = 16, dark = false, onClick }) {
  return (
    <div onClick={onClick} style={{
      background: dark ? T.primaryDeep : T.card,
      color: dark ? '#fff' : T.ink,
      borderRadius: 16,
      padding,
      boxShadow: dark ? 'none' : '0 1px 2px rgba(27,58,45,0.04), 0 4px 12px rgba(27,58,45,0.05)',
      cursor: onClick ? 'pointer' : 'default',
      ...style,
    }}>{children}</div>
  );
}

function SectionLabel({ children, action, style = {} }) {
  return (
    <div style={{
      display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
      padding: '0 4px', marginBottom: 10,
      font: `600 11px/1 ${T.fontApp}`, color: T.inkSub,
      letterSpacing: '0.12em', textTransform: 'uppercase', ...style,
    }}>
      <span>{children}</span>
      {action && <span style={{ color: T.primary, letterSpacing: 0, textTransform: 'none', font: `600 13px/1 ${T.fontApp}` }}>{action}</span>}
    </div>
  );
}

// Tiny SVG icon set. 22x22 stroke 1.75 currentColor.
function Icon({ name, size = 22, stroke = 1.75, style = {} }) {
  const paths = {
    home:      'M3 11l9-8 9 8M5 10v10h5v-6h4v6h5V10',
    flag:      'M5 21V4M5 4h11l-2 4 2 4H5',
    plus:      'M12 5v14M5 12h14',
    wallet:    'M3 7h16a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2zM3 7l2-3h12M16 14h2',
    menu:      'M4 6h16M4 12h16M4 18h16',
    users:     'M17 11a4 4 0 100-8 4 4 0 000 8zM3 21v-2a4 4 0 014-4h6a4 4 0 014 4v2M21 21v-2a4 4 0 00-3-3.87',
    trophy:    'M8 21h8M12 17v4M7 4h10v4a5 5 0 01-10 0V4zM4 4h3v3a2 2 0 01-2-2zM20 4h-3v3a2 2 0 002-2z',
    cal:       'M3 7h18M5 5h14a2 2 0 012 2v12a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2zM8 3v4M16 3v4',
    clock:     'M12 7v5l3 2M12 22a10 10 0 110-20 10 10 0 010 20z',
    chevR:     'M9 6l6 6-6 6',
    chevL:     'M15 6l-9 6 9 6',
    chevD:     'M6 9l6 6 6-6',
    chevU:     'M6 15l6-6 6 6',
    check:     'M5 12l5 5 9-11',
    x:         'M6 6l12 12M18 6L6 18',
    bell:      'M6 8a6 6 0 1112 0c0 7 3 9 3 9H3s3-2 3-9zM10 21a2 2 0 004 0',
    star:      'M12 2l3 7h7l-6 4 2 8-6-4-6 4 2-8-6-4h7z',
    bolt:      'M13 2L4 14h7l-1 8 9-12h-7z',
    pin:       'M12 21s7-7 7-12a7 7 0 10-14 0c0 5 7 12 7 12zM12 11a2 2 0 100-4 2 2 0 000 4z',
    chat:      'M21 12a8 8 0 01-12 7l-5 1 1-5a8 8 0 1116-3z',
    shield:    'M12 2l9 4v6c0 5-4 9-9 10-5-1-9-5-9-10V6z',
    target:    'M12 12m-9 0a9 9 0 1018 0a9 9 0 10-18 0M12 12m-5 0a5 5 0 1010 0a5 5 0 10-10 0M12 12h.01',
    eye:       'M2 12s4-8 10-8 10 8 10 8-4 8-10 8-10-8-10-8zM12 15a3 3 0 100-6 3 3 0 000 6z',
    plusBig:   'M12 4v16M4 12h16',
    arrowR:    'M5 12h14M13 5l7 7-7 7',
    minus:     'M5 12h14',
    grid:      'M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM14 14h7v7h-7',
    settle:    'M7 17l10-10M7 7h10v10',
    share:     'M4 12v8a2 2 0 002 2h12a2 2 0 002-2v-8M16 6l-4-4-4 4M12 2v14',
    copy:      'M9 9h11v11H9zM5 15V5a2 2 0 012-2h10',
    qr:        'M3 3h6v6H3zM15 3h6v6h-6zM3 15h6v6H3zM15 15v3M18 15v6M21 15v3M15 21h6',
    list:      'M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01',
    spark:     'M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1',
    map:       'M3 6l6-3 6 3 6-3v15l-6 3-6-3-6 3zM9 3v15M15 6v15',
    course:    'M3 18h18M5 18v-7l7-5 7 5v7M9 18v-5h6v5',
  };
  const d = paths[name] || 'M3 3h18v18H3z';
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke="currentColor" strokeWidth={stroke}
      strokeLinecap="round" strokeLinejoin="round"
      style={{ display: 'inline-block', verticalAlign: 'middle', ...style }}>
      <path d={d}/>
    </svg>
  );
}

// Simulated phone screen wrapper (rounded; safe area inside)
function PhoneScreen({ children, bg = T.bg, statusDark = false, label, hideStatus = false, hideHome = false }) {
  return (
    <div style={{
      width: '100%', height: '100%', background: bg,
      position: 'relative', overflow: 'hidden',
      font: `400 14px/1.5 ${T.fontApp}`, color: T.ink,
      display: 'flex', flexDirection: 'column',
    }}>
      {!hideStatus && (
        <div style={{
          padding: '12px 24px 6px', display: 'flex', justifyContent: 'space-between',
          color: statusDark ? '#fff' : T.ink, font: `600 14px/1 ${T.fontApp}`,
          flexShrink: 0,
        }}>
          <span>9:41</span>
          <span style={{ display: 'flex', gap: 6, alignItems: 'center', fontSize: 12 }}>
            <span>●●●●●</span><span>5G</span><span>▮</span>
          </span>
        </div>
      )}
      {label && <div style={{ position: 'absolute', top: 6, left: 12, font: `700 9px/1 ${T.fontMono}`, color: T.inkFaint, letterSpacing: '0.1em' }}>{label}</div>}
      <div style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column' }}>
        {children}
      </div>
      {!hideHome && (
        <div style={{
          padding: '8px 0 10px', display: 'flex', justifyContent: 'center', flexShrink: 0,
        }}>
          <div style={{ width: 134, height: 5, borderRadius: 3, background: statusDark ? 'rgba(255,255,255,0.5)' : 'rgba(0,0,0,0.3)' }}/>
        </div>
      )}
    </div>
  );
}

// Bottom tab bar (Material-style)
function BottomNav({ active = 'home', dark = false }) {
  const items = [
    { id: 'home',   icon: 'home',   label: 'Home' },
    { id: 'groups', icon: 'users',  label: 'Groups' },
    { id: 'create', icon: 'plus',   label: '', center: true },
    { id: 'wallet', icon: 'wallet', label: 'Wallet' },
    { id: 'menu',   icon: 'menu',   label: 'Options' },
  ];
  return (
    <div style={{
      flexShrink: 0,
      display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)',
      background: dark ? T.primaryDeep : T.card,
      borderTop: `1px solid ${dark ? 'rgba(255,255,255,0.06)' : T.divider}`,
      padding: '8px 0 4px',
    }}>
      {items.map(it => {
        if (it.center) {
          return (
            <div key={it.id} style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
              <div style={{
                width: 52, height: 52, borderRadius: '50%',
                background: T.secondary, color: '#fff',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                marginTop: -16, boxShadow: '0 6px 20px rgba(39,174,96,0.4)',
              }}><Icon name="plusBig" size={26} stroke={2.5}/></div>
            </div>
          );
        }
        const isActive = it.id === active;
        return (
          <div key={it.id} style={{
            display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 2,
            color: isActive ? (dark ? T.gold : T.primary) : (dark ? 'rgba(255,255,255,0.5)' : T.inkFaint),
          }}>
            <Icon name={it.icon} size={22} stroke={isActive ? 2.25 : 1.75}/>
            <span style={{ font: `600 10px/1 ${T.fontApp}` }}>{it.label}</span>
          </div>
        );
      })}
    </div>
  );
}

// Sticky app header (Material-style green bar)
function AppHeader({ title, subtitle, left, right, dark = true, big = false }) {
  return (
    <div style={{
      flexShrink: 0, padding: big ? '16px 20px 18px' : '12px 16px',
      background: dark ? T.primaryDeep : T.card,
      color: dark ? '#fff' : T.ink,
      display: 'flex', alignItems: 'center', gap: 12,
    }}>
      {left}
      <div style={{ flex: 1 }}>
        <div style={{ font: `700 ${big ? 22 : 17}px/1.2 ${T.fontApp}` }}>{title}</div>
        {subtitle && <div style={{ font: `400 12px/1.3 ${T.fontApp}`, opacity: 0.7, marginTop: 2 }}>{subtitle}</div>}
      </div>
      {right}
    </div>
  );
}

// ─── Export ───────────────────────────────────────────────────────
Object.assign(window, {
  T_AU: T,
  D_AU: D,
  fmtMoney_AU: fmtMoney,
  moneyColor_AU: moneyColor,
  Avatar_AU: Avatar,
  Money_AU: Money,
  Chip_AU: Chip,
  Card_AU: Card,
  SectionLabel_AU: SectionLabel,
  Icon_AU: Icon,
  PhoneScreen_AU: PhoneScreen,
  BottomNav_AU: BottomNav,
  AppHeader_AU: AppHeader,
});
