// ─────────────────────────────────────────────────────────────
// LifeWheel Coach — shared brutalism primitives
// Loaded BEFORE all coach .jsx pages so they can pull tokens,
// the useBrutMode hook, the Atmosphere/Styles components, and
// the ModeToggle from one place.
//
// Attached to window.LWBrutal namespace per the babel-standalone
// global-collision footgun documented in
// .claude/memory/feedback/coach_portal_global_function_collision_2026_05_07.md
// ─────────────────────────────────────────────────────────────

(function () {
  // ── Theme tokens ────────────────────────────────────────────
  const lightTokens = {
    bg:           '#F2EBD8',
    bgSubtle:     '#EAE2CB',
    card:         '#FFFFFF',
    cardHover:    '#FFF8E5',
    elevated:     '#FFFFFF',
    overlay:      'rgba(242,235,216,0.92)',
    borderSubtle:  'rgba(26,26,26,0.10)',
    borderDefault: 'rgba(26,26,26,0.18)',
    borderStrong:  'rgba(26,26,26,0.32)',
    ink:          '#1A1A1A',
    textPrimary:   '#1A1A1A',
    textSecondary: '#4A4A40',
    textTertiary:  '#7A7468',
    textOnAccent:  '#F2EBD8',
    accent:        '#0F8F5F',
    accentHover:   '#0B6F49',
    accentMuted:   'rgba(15,143,95,0.12)',
    accentInk:     '#0B5436',
    stamp:         '#9B2C2C',
    flame:         '#B8501F',
    flameBg:       'rgba(184,80,31,0.10)',
    flameBorder:   'rgba(184,80,31,0.35)',
    error:         '#B53030',
    info:          '#3E60A8',
    spheres: {
      health:'#B83A3A', career:'#B8501F', money:'#B89010', love:'#A83864',
      joy:'#B8870F', growth:'#0F8F5F', people:'#3E60A8', contribution:'#6F3FB8',
    },
    shadow: 'none',
    shadowModal: '0 4px 0 0 #1A1A1A',
  };

  const darkTokens = {
    bg:           '#15140F',
    bgSubtle:     '#1C1B16',
    card:         '#22211B',
    cardHover:    '#2A2922',
    elevated:     '#22211B',
    overlay:      'rgba(21,20,15,0.92)',
    borderSubtle:  'rgba(242,235,216,0.10)',
    borderDefault: 'rgba(242,235,216,0.20)',
    borderStrong:  'rgba(242,235,216,0.36)',
    ink:          '#F2EBD8',
    textPrimary:   '#F2EBD8',
    textSecondary: '#C8BFA8',
    textTertiary:  '#8A8170',
    textOnAccent:  '#15140F',
    accent:        '#3EC08D',
    accentHover:   '#5BD4A0',
    accentMuted:   'rgba(62,192,141,0.16)',
    accentInk:     '#7EE0AC',
    stamp:         '#E85555',
    flame:         '#E8943A',
    flameBg:       'rgba(232,148,58,0.14)',
    flameBorder:   'rgba(232,148,58,0.40)',
    error:         '#E85555',
    info:          '#5D8CE8',
    spheres: {
      health:'#E85555', career:'#E8943A', money:'#E8C73A', love:'#E85D8C',
      joy:'#E8B83A', growth:'#3EC08D', people:'#5D8CE8', contribution:'#8C5DE8',
    },
    shadow: 'none',
    shadowModal: '0 4px 0 0 #F2EBD8',
  };

  // ── Fonts (IBM Plex Mono primary, Fraunces for selective italic) ──
  const fonts = {
    display: '"Fraunces", "Iowan Old Style", Georgia, serif',
    app:     '"IBM Plex Mono", "Menlo", "Courier New", monospace',
    body:    '"IBM Plex Mono", "Menlo", "Courier New", monospace',
    mono:    '"IBM Plex Mono", "Menlo", "Courier New", monospace',
  };

  // ── Helper: hex+alpha → rgba ────────────────────────────────
  function hexToRgba(hex, alpha) {
    if (!hex) return `rgba(0,0,0,${alpha})`;
    if (hex.startsWith('rgb')) return hex;
    const h = hex.replace('#', '');
    const r = parseInt(h.substring(0, 2), 16);
    const g = parseInt(h.substring(2, 4), 16);
    const b = parseInt(h.substring(4, 6), 16);
    return `rgba(${r},${g},${b},${alpha})`;
  }

  // ── Hook: useBrutMode (state + localStorage + cross-instance sync) ──
  // Multiple components call this hook independently (SettingsPage, the
  // theme toggle, ModeToggle in nav, etc.). Without an external broadcast
  // their useState copies drift, so flipping the toggle would change one
  // instance and leave the rest of the tree painting the old palette.
  // We sync via a 'brutmodechange' window event + the standard 'storage'
  // event for cross-tab.
  function useBrutMode() {
    const { useState, useEffect } = React;
    const [mode, setModeRaw] = useState(() => {
      try {
        const stored = localStorage.getItem('lw_coach_brutmode');
        if (stored === 'dark' || stored === 'light') return stored;
      } catch {}
      return 'light';
    });
    useEffect(() => {
      const onSync = (e) => {
        const next = (e && e.detail && e.detail.mode) || (() => {
          try { return localStorage.getItem('lw_coach_brutmode'); } catch { return null; }
        })();
        if (next === 'dark' || next === 'light') setModeRaw(next);
      };
      const onStorage = (e) => {
        if (e && e.key === 'lw_coach_brutmode' && (e.newValue === 'dark' || e.newValue === 'light')) {
          setModeRaw(e.newValue);
        }
      };
      window.addEventListener('brutmodechange', onSync);
      window.addEventListener('storage', onStorage);
      return () => {
        window.removeEventListener('brutmodechange', onSync);
        window.removeEventListener('storage', onStorage);
      };
    }, []);
    useEffect(() => {
      try { localStorage.setItem('lw_coach_brutmode', mode); } catch {}
    }, [mode]);
    const setMode = (m) => {
      if (m !== 'dark' && m !== 'light') return;
      setModeRaw(m);
      try { localStorage.setItem('lw_coach_brutmode', m); } catch {}
      try { window.dispatchEvent(new CustomEvent('brutmodechange', { detail: { mode: m } })); } catch {}
    };
    return [mode, setMode];
  }

  // ── Build a c-tokens object given a base ────────────────────
  function makeC(cBase, mode) {
    return { ...cBase, ...(mode === 'dark' ? darkTokens : lightTokens) };
  }

  // ── Atmosphere: paper backdrop ──────────────────────────────
  function Atmosphere({ c, brutMode = 'light' }) {
    const isDark = brutMode === 'dark';
    return React.createElement('div', {
      'aria-hidden': true,
      style: {
        position: 'fixed', inset: 0, pointerEvents: 'none', zIndex: 0,
        background: c.bg,
      },
    },
      React.createElement('div', {
        style: {
          position: 'absolute', top: 0, right: 0, width: '45vw', height: '45vw',
          background: isDark
            ? `radial-gradient(circle at top right, ${hexToRgba(c.accent, 0.14)} 0%, transparent 60%)`
            : `radial-gradient(circle at top right, ${hexToRgba('#D4A537', 0.10)} 0%, transparent 60%)`,
        },
      }),
      isDark && React.createElement('div', {
        style: {
          position: 'absolute', bottom: 0, left: 0, width: '40vw', height: '40vw',
          background: `radial-gradient(circle at bottom left, ${hexToRgba(c.spheres.contribution, 0.08)} 0%, transparent 60%)`,
        },
      }),
      React.createElement('div', {
        style: {
          position: 'absolute', inset: 0,
          backgroundImage: `url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/></filter><rect width='100%' height='100%' filter='url(%23n)' opacity='0.65'/></svg>")`,
          opacity: isDark ? 0.06 : 0.10,
          mixBlendMode: isDark ? 'screen' : 'multiply',
        },
      })
    );
  }

  // ── Styles: injects .br-* utilities scoped to whatever c/fonts is given ──
  function Styles({ c, fonts: f }) {
    const fns = f || fonts;
    const css = `
      @keyframes lwb-fade-up {
        from { opacity: 0; transform: translateY(14px); }
        to   { opacity: 1; transform: translateY(0); }
      }
      .lwb-reveal { opacity: 0; animation: lwb-fade-up 700ms cubic-bezier(.2,.7,.2,1) forwards; }

      .br-paper {
        background: ${c.card};
        border: 1.5px solid ${c.ink};
        border-radius: 2px;
        position: relative;
        transition: transform 160ms cubic-bezier(.2,.7,.2,1), box-shadow 200ms ease, background 200ms ease;
      }
      .br-paper:hover {
        transform: translate(-2px, -2px);
        box-shadow: 4px 4px 0 0 ${c.ink};
        background: ${c.cardHover};
      }
      .br-paper-shadowed {
        background: ${c.card};
        border: 1.5px solid ${c.ink};
        border-radius: 2px;
        box-shadow: 4px 4px 0 0 ${c.ink};
        transition: transform 160ms cubic-bezier(.2,.7,.2,1), box-shadow 200ms ease;
      }

      .br-input {
        background: ${c.card} !important;
        border: 1.5px solid ${c.ink} !important;
        border-radius: 2px;
        font-family: ${fns.mono};
        color: ${c.textPrimary};
        transition: box-shadow 160ms ease, background 160ms ease, border-color 160ms ease;
      }
      .br-input:focus {
        outline: none;
        background: ${c.cardHover} !important;
        box-shadow: 4px 4px 0 0 ${c.accent};
        border-color: ${c.accent} !important;
      }
      .br-input::placeholder { color: ${c.textTertiary}; opacity: 1; }

      .br-cta {
        position: relative;
        background: ${c.accent};
        color: ${c.textOnAccent};
        border: 1.5px solid ${c.ink};
        border-radius: 2px;
        box-shadow: 4px 4px 0 0 ${c.ink};
        font-family: ${fns.mono};
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.08em;
        cursor: pointer;
        transition: transform 120ms cubic-bezier(.2,.7,.2,1), box-shadow 120ms ease, background 160ms ease;
      }
      .br-cta:hover:not(:disabled) {
        transform: translate(-2px, -2px);
        box-shadow: 6px 6px 0 0 ${c.ink};
        background: ${c.accentHover};
      }
      .br-cta:active:not(:disabled) {
        transform: translate(2px, 2px);
        box-shadow: 0 0 0 0 ${c.ink};
      }

      .br-btn {
        background: transparent;
        color: ${c.ink};
        border: 1.5px solid ${c.ink};
        border-radius: 2px;
        box-shadow: 4px 4px 0 0 ${c.ink};
        font-family: ${fns.mono};
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.08em;
        cursor: pointer;
        transition: transform 120ms cubic-bezier(.2,.7,.2,1), box-shadow 120ms ease, background 160ms ease;
      }
      .br-btn:hover {
        transform: translate(-2px, -2px);
        box-shadow: 6px 6px 0 0 ${c.ink};
        background: ${c.ink};
        color: ${c.bg};
      }
      .br-btn:active {
        transform: translate(2px, 2px);
        box-shadow: 0 0 0 0 ${c.ink};
      }

      .br-marker {
        font-family: ${fns.mono};
        font-size: 11px;
        font-weight: 600;
        letter-spacing: 0.16em;
        text-transform: uppercase;
        color: ${c.ink};
        display: inline-flex;
        align-items: center;
        gap: 8px;
        padding: 4px 10px;
        border: 1.5px solid ${c.ink};
        border-radius: 2px;
        background: ${c.bg};
      }

      .br-rule { height: 1.5px; background: ${c.ink}; width: 100%; }

      .br-note {
        border-left: 2px solid ${c.ink};
        padding: 4px 14px;
        font-family: ${fns.mono};
        font-style: italic;
        font-size: 14px;
        line-height: 1.55;
        color: ${c.textSecondary};
      }

      .lwb-link-hover { transition: color 160ms ease, background 160ms ease; }
      .lwb-link-hover:hover { color: ${c.ink} !important; background: ${hexToRgba(c.accent, 0.18)}; }

      @media (prefers-reduced-motion: reduce) {
        .lwb-reveal, .br-paper, .br-paper-shadowed, .br-cta, .br-btn, .br-input { animation: none !important; transition: none !important; }
      }
    `;
    return React.createElement('style', null, css);
  }

  // ── ModeToggle + LangToggle (same as signup.jsx) ────────────
  function ModeToggle({ c, fonts: f, brutMode, setBrutMode }) {
    const fns = f || fonts;
    const item = (m, glyph) => {
      const active = brutMode === m;
      return React.createElement('button', {
        onClick: () => setBrutMode(m),
        title: `${m} mode`,
        style: {
          background: active ? c.ink : 'transparent',
          color: active ? c.bg : c.textTertiary,
          border: 'none', cursor: 'pointer', padding: '2px 6px',
          fontFamily: fns.mono, fontSize: 11, fontWeight: 700,
          letterSpacing: '0.10em',
        },
      }, glyph);
    };
    return React.createElement('div', {
      style: {
        display: 'inline-flex', alignItems: 'center', gap: 4,
        padding: '5px 6px', borderRadius: 2,
        border: `1.5px solid ${c.ink}`, background: c.bg,
      },
    }, item('light', '☀'), item('dark', '☾'));
  }

  // ── LWMark — 8 sphere wedges (small logo) ────────────────────
  function LWMark({ c, size = 28 }) {
    const sphereColors = Object.values(c.spheres);
    const r = size / 2;
    const wedges = sphereColors.map((col, i) => {
      const a0 = (i / 8) * Math.PI * 2 - Math.PI / 2;
      const a1 = ((i + 1) / 8) * Math.PI * 2 - Math.PI / 2;
      const x0 = r + Math.cos(a0) * r, y0 = r + Math.sin(a0) * r;
      const x1 = r + Math.cos(a1) * r, y1 = r + Math.sin(a1) * r;
      return React.createElement('path', {
        key: i,
        d: `M${r} ${r} L${x0} ${y0} A${r} ${r} 0 0 1 ${x1} ${y1} Z`,
        fill: col, opacity: 0.9,
      });
    });
    return React.createElement('svg', {
      width: size, height: size, viewBox: `0 0 ${size} ${size}`,
    }, ...wedges, React.createElement('circle', {
      cx: r, cy: r, r: r * 0.30, fill: c.bg,
      stroke: c.ink, strokeWidth: 1,
    }));
  }

  // ── BrutalTopNav — for in-app pages ─────────────────────────
  // Drop-in replacement for the existing TopNav, but in the
  // product dialect: hard ink borders, mono caps tabs, no
  // backdrop-blur, mode toggle inline, brutalist invite CTA.
  function BrutalTopNav({ c, fonts: f, active, brutMode, setBrutMode }) {
    const fns = f || fonts;
    const { useState, useEffect } = React;
    const t = (k) => (window.LWLang ? window.LWLang.t(k) : k);
    const lang = window.LWLang ? window.LWLang.lang() : 'en';
    const isRu = lang === 'ru';
    const [authedCoach, setAuthedCoach] = useState(null);
    const [menuOpen, setMenuOpen] = useState(false);
    useEffect(() => {
      if (!window.LWAuth) return;
      return window.LWAuth.onAuthChanged(setAuthedCoach);
    }, []);
    const isMobile = typeof window !== 'undefined' && window.innerWidth < 768;
    const items = [
      { id: 'dashboard', label: t('nav.today')   || (isRu ? 'Сегодня'  : 'Today'),    href: '#/dashboard' },
      { id: 'feed',      label: t('nav.feed')    || (isRu ? 'Лента'    : 'Feed'),     href: '#/feed' },
      { id: 'calendar',  label: t('nav.calendar')|| (isRu ? 'Календарь': 'Calendar'), href: '#/calendar' },
      { id: 'settings',  label: t('nav.settings')|| (isRu ? 'Настройки': 'Settings'), href: '#/settings' },
    ];
    const initials = (authedCoach && authedCoach.profile && authedCoach.profile.initials)
      || (authedCoach && authedCoach.email && authedCoach.email[0].toUpperCase())
      || '·';
    return React.createElement('header', {
      style: {
        position: 'sticky', top: 0, zIndex: 20,
        background: c.bg,
        borderBottom: `1.5px solid ${c.ink}`,
        paddingTop: 'env(safe-area-inset-top)',
        fontFamily: fns.mono,
      },
    },
      React.createElement('div', {
        style: {
          maxWidth: 1280, margin: '0 auto',
          padding: isMobile ? '12px 16px' : '14px 28px',
          display: 'flex', alignItems: 'center', gap: isMobile ? 10 : 22,
        },
      },
        // Logo
        React.createElement('a', {
          href: '#/dashboard',
          style: { display: 'inline-flex', alignItems: 'center', gap: 9, textDecoration: 'none', color: c.ink },
        },
          React.createElement(LWMark, { c, size: 22 }),
          React.createElement('span', {
            style: { fontFamily: fns.mono, fontWeight: 700, fontSize: 14, letterSpacing: '0.04em', textTransform: 'uppercase' },
          }, 'LifeWheel'),
          !isMobile && React.createElement('span', {
            style: { fontFamily: fns.mono, fontSize: 10, fontWeight: 700, letterSpacing: '0.18em', textTransform: 'uppercase', color: c.textTertiary, marginTop: 4 },
          }, t('nav.coach') || 'COACH')
        ),
        // Tabs
        !isMobile && React.createElement('nav', {
          style: { display: 'flex', alignItems: 'center', gap: 0, marginLeft: 12 },
        },
          ...items.map(it => React.createElement('a', {
            key: it.id, href: it.href,
            style: {
              padding: '8px 14px',
              fontFamily: fns.mono, fontSize: 11, fontWeight: 700,
              letterSpacing: '0.10em', textTransform: 'uppercase',
              color: active === it.id ? c.bg : c.textSecondary,
              background: active === it.id ? c.ink : 'transparent',
              textDecoration: 'none',
              borderTop: `1.5px solid transparent`,
              borderBottom: `1.5px solid transparent`,
            },
          }, it.label))
        ),
        React.createElement('div', { style: { flex: 1 } }),
        // Mode + lang toggles
        React.createElement(ModeToggle, { c, fonts: fns, brutMode, setBrutMode }),
        window.LangToggle && React.createElement(window.LangToggle, { c, fonts: fns }),
        // Invite CTA
        !isMobile && React.createElement('a', {
          href: '#/invite', className: 'br-cta',
          style: {
            display: 'inline-flex', alignItems: 'center', gap: 6,
            padding: '8px 14px', fontSize: 11,
            textDecoration: 'none',
            background: c.accent, color: c.textOnAccent,
          },
        }, '+ ' + (t('nav.invite_client') || 'Invite client').toUpperCase()),
        // Avatar (small)
        React.createElement('div', {
          style: {
            width: 32, height: 32, borderRadius: 2,
            border: `1.5px solid ${c.ink}`, background: c.bg,
            display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
            fontFamily: fns.mono, fontSize: 12, fontWeight: 700, color: c.ink,
            letterSpacing: '0.04em',
          },
        }, initials)
      ),
      // Mobile tabs row
      isMobile && React.createElement('div', {
        style: {
          padding: '6px 16px 10px',
          borderTop: `1.5px solid ${c.borderDefault}`,
          display: 'flex', gap: 4, overflowX: 'auto',
        },
      },
        ...items.map(it => React.createElement('a', {
          key: it.id, href: it.href,
          style: {
            padding: '6px 10px',
            fontFamily: fns.mono, fontSize: 10, fontWeight: 700,
            letterSpacing: '0.10em', textTransform: 'uppercase',
            color: active === it.id ? c.bg : c.textSecondary,
            background: active === it.id ? c.ink : 'transparent',
            textDecoration: 'none', whiteSpace: 'nowrap',
          },
        }, it.label))
      )
    );
  }

  // ── BrutalPageShell — drop-in PageShell replacement ─────────
  function BrutalPageShell({ active, children, maxWidth = 1280, c, fonts: f, brutMode, setBrutMode }) {
    const fns = f || fonts;
    const isMobile = typeof window !== 'undefined' && window.innerWidth < 768;
    return React.createElement('div', {
      style: {
        minHeight: '100vh', background: c.bg, color: c.textPrimary,
        fontFamily: fns.mono, position: 'relative',
      },
    },
      React.createElement(Atmosphere, { c, brutMode }),
      React.createElement('div', { style: { position: 'relative', zIndex: 1 } },
        React.createElement(BrutalTopNav, { c, fonts: fns, active, brutMode, setBrutMode }),
        React.createElement('main', {
          style: {
            maxWidth, margin: '0 auto',
            padding: isMobile ? '20px 16px calc(96px + env(safe-area-inset-bottom))' : '32px 28px 96px',
          },
        }, children)
      ),
      React.createElement(Styles, { c, fonts: fns })
    );
  }

  // Expose namespace
  window.LWBrutal = {
    lightTokens,
    darkTokens,
    fonts,
    hexToRgba,
    useBrutMode,
    makeC,
    Atmosphere,
    Styles,
    ModeToggle,
    LWMark,
    BrutalTopNav,
    BrutalPageShell,
  };
})();
