/* Shared UI primitives for the WKYHB site. Exports to window.U */
const DS = window.WKYHBHutchinsonBellDesignSystem_7985db || {};
const ASSET = 'assets';
const bellSrc = `${ASSET}/icon-bell-mark.png`;
const texSrc = `${ASSET}/texture-faceted-red.png`;

const uStyles = {
  container: { maxWidth: 'var(--container)', marginInline: 'auto', width: '100%', boxSizing: 'border-box' },
  narrow: { maxWidth: 760, marginInline: 'auto', width: '100%', boxSizing: 'border-box' },
};

/* ---- layout ---- */
function Container({ narrow = false, children, style = {} }) {
  return <div className="wk-container" style={{ ...(narrow ? uStyles.narrow : uStyles.container), ...style }}>{children}</div>;
}

function Section({ bg = 'surface', pad = '76px 0', children, style = {} }) {
  const bgs = {
    surface: 'var(--surface)', paper: 'var(--surface-paper)', sunken: 'var(--surface-sunken)',
    ink: 'var(--ink)', crimson: 'var(--bell-crimson)',
  };
  return <section style={{ background: bgs[bg] || bg, padding: pad, ...style }}>{children}</section>;
}

/* Striped image placeholder with a monospace caption. */
function Placeholder({ label = 'photo', height = 240, radius = 'var(--radius-lg)', style = {} }) {
  return (
    <div style={{
      height, borderRadius: radius, overflow: 'hidden',
      background: 'repeating-linear-gradient(135deg, var(--gray-100) 0, var(--gray-100) 13px, var(--gray-50) 13px, var(--gray-50) 26px)',
      border: '1px solid var(--border)', display: 'flex', alignItems: 'center', justifyContent: 'center', ...style,
    }}>
      <span style={{ fontFamily: 'var(--font-condensed)', textTransform: 'uppercase', letterSpacing: '0.16em', fontSize: 12, color: 'var(--text-muted)' }}>{label}</span>
    </div>
  );
}

/* Interior page header band (crimson) with bell mark. */
function PageHeader({ eyebrow, title, lead }) {
  return (
    <header style={{ position: 'relative', overflow: 'hidden', background: 'linear-gradient(135deg, #7E1626 0%, #C4122E 60%, #9E1B2F 100%)', color: '#fff', padding: '64px 0 60px' }}>
      <div style={{ position: 'absolute', inset: 0, backgroundImage: `url(${texSrc})`, backgroundSize: 'cover', backgroundPosition: 'center', opacity: 0.20, mixBlendMode: 'overlay', pointerEvents: 'none' }} />
      <Container style={{ position: 'relative', display: 'flex', flexDirection: 'column', gap: 14 }}>
        {eyebrow && <span style={{ fontFamily: 'var(--font-condensed)', textTransform: 'uppercase', letterSpacing: '0.18em', fontSize: 13, fontWeight: 500, color: 'rgba(255,255,255,0.9)' }}>{eyebrow}</span>}
        <h1 style={{ fontFamily: 'var(--font-display)', fontWeight: 900, fontSize: 'clamp(34px,5vw,56px)', lineHeight: 1.05, letterSpacing: '-0.025em', margin: 0, maxWidth: 860 }}>{title}</h1>
        {lead && <p style={{ fontFamily: 'var(--font-serif)', fontSize: 'clamp(16px,1.6vw,20px)', lineHeight: 1.6, color: 'rgba(255,255,255,0.92)', maxWidth: 680, margin: '4px 0 0' }}>{lead}</p>}
      </Container>
    </header>
  );
}

/* Eyebrow label (Oswald caps). */
function Eyebrow({ children, onDark = false, style = {} }) {
  return <span style={{ fontFamily: 'var(--font-condensed)', textTransform: 'uppercase', letterSpacing: '0.14em', fontSize: 13, fontWeight: 600, color: onDark ? 'var(--falcon-red)' : 'var(--bell-crimson)', ...style }}>{children}</span>;
}

/* Labeled textarea matching DS Input. */
function TextArea({ label, value, onChange, rows = 5, required, ...rest }) {
  const [focus, setFocus] = React.useState(false);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6, width: '100%' }}>
      {label && <label style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--text-sm)', color: 'var(--text-strong)' }}>{label}</label>}
      <textarea value={value} onChange={onChange} rows={rows} required={required}
        onFocus={() => setFocus(true)} onBlur={() => setFocus(false)}
        style={{ fontFamily: 'var(--font-body)', fontSize: 'var(--text-base)', color: 'var(--text-body)', background: 'var(--surface)', border: `1.5px solid ${focus ? 'var(--bell-crimson)' : 'var(--border-strong)'}`, boxShadow: focus ? '0 0 0 3px var(--focus-ring)' : 'none', borderRadius: 'var(--radius-md)', padding: '11px 14px', width: '100%', boxSizing: 'border-box', outline: 'none', resize: 'vertical', transition: 'border-color var(--dur-fast), box-shadow var(--dur-fast)' }}
        {...rest} />
    </div>
  );
}

/* Labeled select matching DS Input. */
function Select({ label, value, onChange, children, ...rest }) {
  const [focus, setFocus] = React.useState(false);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 6, width: '100%' }}>
      {label && <label style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--text-sm)', color: 'var(--text-strong)' }}>{label}</label>}
      <select value={value} onChange={onChange}
        onFocus={() => setFocus(true)} onBlur={() => setFocus(false)}
        style={{ fontFamily: 'var(--font-body)', fontSize: 'var(--text-base)', color: 'var(--text-body)', background: 'var(--surface)', border: `1.5px solid ${focus ? 'var(--bell-crimson)' : 'var(--border-strong)'}`, boxShadow: focus ? '0 0 0 3px var(--focus-ring)' : 'none', borderRadius: 'var(--radius-md)', padding: '11px 14px', width: '100%', boxSizing: 'border-box', outline: 'none', appearance: 'none', cursor: 'pointer', transition: 'border-color var(--dur-fast), box-shadow var(--dur-fast)' }}
        {...rest}>{children}</select>
    </div>
  );
}

/* Centered confirmation panel (forms success state). */
function SuccessPanel({ title, children, onReset, resetLabel = 'Done' }) {
  const { Button } = DS;
  return (
    <div style={{ textAlign: 'center', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 16, padding: '12px 0' }}>
      <div style={{ width: 64, height: 64, borderRadius: '50%', background: 'rgba(46,125,79,0.12)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--success)', fontSize: 30 }}>✓</div>
      <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 800, fontSize: 'var(--text-xl)', color: 'var(--text-strong)', margin: 0, letterSpacing: '-0.02em' }}>{title}</h3>
      <p style={{ fontFamily: 'var(--font-serif)', fontSize: 'var(--text-md)', lineHeight: 1.6, color: 'var(--text-muted)', margin: 0, maxWidth: 460 }}>{children}</p>
      {onReset && <Button variant="outline" size="sm" onClick={onReset}>{resetLabel}</Button>}
    </div>
  );
}

/* Modal shell. */
function Modal({ open, onClose, children, maxWidth = 520 }) {
  React.useEffect(() => {
    if (!open) return;
    const h = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 100, background: 'rgba(20,20,20,0.55)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20, animation: 'wkfade 160ms var(--ease-out)' }}>
      <div onClick={(e) => e.stopPropagation()} style={{ background: 'var(--surface)', borderRadius: 'var(--radius-lg)', boxShadow: 'var(--shadow-lg)', borderTop: '4px solid var(--bell-crimson)', width: '100%', maxWidth, maxHeight: '88vh', overflow: 'auto', padding: 'var(--space-7)', boxSizing: 'border-box' }}>{children}</div>
    </div>
  );
}

// History-API navigation for clean URLs (e.g. /events). pushState doesn't fire
// popstate, so we dispatch a 'wknavigate' event for the app to react to.
function navTo(path) {
  const url = path.startsWith('/') ? path : `/${path}`;
  if (url !== window.location.pathname + window.location.search) window.history.pushState({}, '', url);
  window.dispatchEvent(new Event('wknavigate'));
}
function goTo(key) { navTo(key === 'home' ? '/' : `/${key}`); }
function scrollTop() { try { window.scrollTo({ top: 0, left: 0, behavior: 'auto' }); } catch (e) { window.scrollTo(0, 0); } }

/* Spread onto a DS <Button> to make an outline button on a dark/crimson
   background. The DS Button's built-in hover handlers reset to the variant's
   default crimson colors on mouse-leave — invisible on a dark background — so
   we pass our own handlers (component props override the built-ins) to keep
   the button white throughout the hover. */
function darkOutlineBtn({ border = 'rgba(255,255,255,0.7)', style = {} } = {}) {
  return {
    variant: 'outline',
    style: { color: '#fff', borderColor: border, ...style },
    onMouseEnter: (e) => { e.currentTarget.style.background = 'rgba(255,255,255,0.16)'; },
    onMouseLeave: (e) => {
      e.currentTarget.style.background = 'transparent';
      e.currentTarget.style.color = '#fff';
      e.currentTarget.style.borderColor = border;
      e.currentTarget.style.transform = 'translateY(0)';
    },
  };
}
function mailto(to, subject, body, cc) {
  const params = [];
  if (cc) params.push(`cc=${encodeURIComponent(cc)}`);
  params.push(`subject=${encodeURIComponent(subject)}`);
  params.push(`body=${encodeURIComponent(body)}`);
  return `mailto:${to}?${params.join('&')}`;
}

/* Brand logos as inline SVG. fill="currentColor" so they inherit the
   surrounding text color; pass `size` (px) to scale. */
function IconFacebook({ size = 18, style = {} }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" focusable="false" style={{ display: 'block', flex: 'none', ...style }}>
      <path d="M24 12.073C24 5.404 18.627 0 12 0S0 5.404 0 12.073C0 18.1 4.388 23.094 10.125 24v-8.437H7.078v-3.49h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.49h-2.796V24C19.612 23.094 24 18.1 24 12.073z" />
    </svg>
  );
}
function IconInstagram({ size = 18, style = {} }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" focusable="false" style={{ display: 'block', flex: 'none', ...style }}>
      <path d="M12 2.163c3.204 0 3.584.012 4.85.07 1.17.054 1.805.249 2.227.415.56.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227a3.81 3.81 0 01-.896 1.382 3.744 3.744 0 01-1.379.896c-.421.164-1.057.36-2.227.413-1.266.057-1.646.07-4.85.07s-3.585-.015-4.85-.074c-1.17-.061-1.805-.256-2.227-.421a3.716 3.716 0 01-1.379-.899 3.644 3.644 0 01-.9-1.381c-.165-.421-.36-1.056-.413-2.226-.057-1.266-.07-1.646-.07-4.85s.015-3.585.074-4.85c.061-1.171.256-1.805.421-2.227.217-.562.477-.96.896-1.382.42-.418.819-.679 1.381-.896.422-.164 1.057-.36 2.227-.413 1.266-.057 1.646-.07 4.85-.07zm0-2.163C8.741 0 8.332.014 7.052.072 5.775.13 4.905.333 4.14.63c-.79.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.052.012 8.332 0 8.741 0 12s.014 3.668.072 4.948c.058 1.277.261 2.147.558 2.913.306.788.717 1.459 1.384 2.126.667.666 1.336 1.079 2.126 1.384.766.296 1.636.499 2.913.558C8.332 23.986 8.741 24 12 24s3.668-.014 4.948-.072c1.277-.059 2.147-.262 2.913-.558.788-.306 1.459-.718 2.126-1.384.666-.667 1.079-1.335 1.384-2.126.296-.766.499-1.636.558-2.913.058-1.28.072-1.689.072-4.948s-.014-3.668-.072-4.948c-.059-1.277-.262-2.147-.558-2.913-.306-.789-.718-1.459-1.384-2.126C21.319 1.347 20.651.935 19.86.63c-.766-.297-1.636-.5-2.913-.558C15.668.014 15.259 0 12 0zm0 5.838a6.162 6.162 0 100 12.324 6.162 6.162 0 000-12.324zM12 16a4 4 0 110-8 4 4 0 010 8zm6.406-11.845a1.44 1.44 0 100 2.881 1.44 1.44 0 000-2.881z" />
    </svg>
  );
}

/* Small external-link arrow as inline SVG. Sized in `em` so it scales with the
   surrounding text and stays optically centered — unlike the ↗ font glyph,
   which renders oversized and high, and varies by device. */
function IconExternal({ size = '0.82em', style = {} }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" focusable="false" style={{ display: 'inline-block', verticalAlign: '-0.05em', flex: 'none', ...style }}>
      <path d="M7 17 17 7" />
      <path d="M8 7h9v9" />
    </svg>
  );
}

Object.assign(window, {
  U: { Container, Section, Placeholder, PageHeader, Eyebrow, TextArea, Select, SuccessPanel, Modal, goTo, navTo, scrollTop, mailto, darkOutlineBtn, ASSET, bellSrc, texSrc, IconExternal, IconFacebook, IconInstagram },
});
