/* ============================================================
   components.jsx — live, interactive brutalist UI widgets
   Exported to window for use by app.jsx
   ============================================================ */
const { useState, useEffect, useRef } = React;

/* --- little arrow / icon glyphs (geometric, no slop) --- */
const Arrow = ({ s = 16 }) => (
  <svg width={s} height={s} viewBox="0 0 16 16" fill="none" aria-hidden="true">
    <path d="M3 8h9M8 3l5 5-5 5" stroke="currentColor" strokeWidth="2.4" strokeLinecap="square"/>
  </svg>
);
const Check = ({ s = 16 }) => (
  <svg width={s} height={s} viewBox="0 0 16 16" fill="none" aria-hidden="true">
    <path d="M2.5 8.5l4 4 7-9" stroke="currentColor" strokeWidth="2.8" strokeLinecap="square"/>
  </svg>
);
const Star = ({ s = 16, fill = "none" }) => (
  <svg width={s} height={s} viewBox="0 0 24 24" fill={fill} aria-hidden="true">
    <path d="M12 2l2.9 6.3 6.9.8-5.1 4.7 1.4 6.8L12 17.8 5.9 20.6l1.4-6.8L2.2 9.1l6.9-.8z"
      stroke="currentColor" strokeWidth="2" strokeLinejoin="miter"/>
  </svg>
);

/* ---------- Toggle ---------- */
function BToggle({ defaultOn = true, label }) {
  const [on, setOn] = useState(defaultOn);
  return (
    <button
      role="switch" aria-checked={on} aria-label={label || 'toggle'}
      onClick={() => setOn(o => !o)}
      style={{
        display: 'inline-flex', alignItems: 'center', padding: 4,
        width: 64, height: 34, cursor: 'pointer',
        border: 'var(--bw) solid var(--line)', borderRadius: 'var(--radius)',
        background: on ? 'var(--accent)' : 'var(--bg-panel)',
        justifyContent: on ? 'flex-end' : 'flex-start',
        transition: 'background .15s', boxShadow: 'none',
      }}>
      <span style={{
        width: 24, height: 24, background: 'var(--line)',
        borderRadius: 'calc(var(--radius) * .6)', display: 'block',
      }}/>
    </button>
  );
}

/* ---------- Checkbox ---------- */
function BCheck({ label, defaultChecked = false }) {
  const [c, setC] = useState(defaultChecked);
  return (
    <label style={{ display: 'inline-flex', alignItems: 'center', gap: 11, cursor: 'pointer', fontWeight: 600 }}>
      <span aria-hidden="true" onClick={() => setC(v => !v)} style={{
        width: 26, height: 26, border: 'var(--bw) solid var(--line)', borderRadius: 'calc(var(--radius) * .5)',
        background: c ? 'var(--accent-2)' : 'var(--bg-panel)', color: '#0A0A0A',
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
      }}>{c && <Check s={16}/>}</span>
      <input type="checkbox" checked={c} onChange={() => setC(v => !v)} style={{ position: 'absolute', opacity: 0, width: 0, height: 0 }}/>
      {label}
    </label>
  );
}

/* ---------- Radio group ---------- */
function BRadio({ options, name }) {
  const [v, setV] = useState(options[0]);
  return (
    <div role="radiogroup" style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
      {options.map(o => (
        <label key={o} style={{ display: 'inline-flex', alignItems: 'center', gap: 11, cursor: 'pointer', fontWeight: 600 }}>
          <span aria-hidden="true" onClick={() => setV(o)} style={{
            width: 26, height: 26, border: 'var(--bw) solid var(--line)', borderRadius: 999,
            background: 'var(--bg-panel)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
          }}>{v === o && <span style={{ width: 12, height: 12, borderRadius: 999, background: 'var(--accent-3)' }}/>}</span>
          <input type="radio" name={name} checked={v === o} onChange={() => setV(o)} style={{ position: 'absolute', opacity: 0, width: 0, height: 0 }}/>
          {o}
        </label>
      ))}
    </div>
  );
}

/* ---------- Text input ---------- */
function BInput({ label, placeholder, type = 'text' }) {
  const [val, setVal] = useState('');
  const [focus, setFocus] = useState(false);
  return (
    <label style={{ display: 'flex', flexDirection: 'column', gap: 7, width: '100%' }}>
      <span className="eyebrow" style={{ color: 'var(--muted)' }}>{label}</span>
      <input
        type={type} value={val} placeholder={placeholder}
        onChange={e => setVal(e.target.value)}
        onFocus={() => setFocus(true)} onBlur={() => setFocus(false)}
        style={{
          padding: '12px 14px', fontSize: 15, fontWeight: 600,
          border: 'var(--bw) solid var(--line)', borderRadius: 'var(--radius)',
          background: 'var(--bg-panel)', color: 'var(--fg)',
          boxShadow: focus ? 'var(--shadow) var(--shadow) 0 0 var(--accent)' : 'none',
          transition: 'box-shadow .12s', outline: 'none',
        }}/>
    </label>
  );
}

/* ---------- Slider ---------- */
function BSlider({ label, defaultValue = 60 }) {
  const [v, setV] = useState(defaultValue);
  return (
    <div style={{ width: '100%' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 8 }}>
        <span className="eyebrow" style={{ color: 'var(--muted)' }}>{label}</span>
        <span className="mono" style={{ fontWeight: 700, fontSize: 13 }}>{v}</span>
      </div>
      <div style={{ position: 'relative', height: 26, display: 'flex', alignItems: 'center' }}>
        <div style={{ position: 'absolute', left: 0, right: 0, height: 'var(--bw)', background: 'var(--line)' }}/>
        <div style={{ position: 'absolute', left: 0, width: `${v}%`, height: 'var(--bw)', background: 'var(--accent-4)' }}/>
        <input type="range" min="0" max="100" value={v} onChange={e => setV(+e.target.value)}
          aria-label={label}
          style={{ position: 'absolute', width: '100%', margin: 0, opacity: 0, cursor: 'pointer', height: 26 }}/>
        <span aria-hidden="true" style={{
          position: 'absolute', left: `calc(${v}% - 13px)`, width: 26, height: 26,
          background: 'var(--accent)', border: 'var(--bw) solid var(--line)',
          borderRadius: 'calc(var(--radius) * .5)', pointerEvents: 'none',
        }}/>
      </div>
    </div>
  );
}

/* ---------- Tabs ---------- */
function BTabs() {
  const tabs = ['Overview', 'Specs', 'A11y'];
  const [active, setActive] = useState('Overview');
  const body = {
    Overview: 'A complete kit of accessible, theimable primitives. Drop in, ship today.',
    Specs: '42 components · 9 themes · ESM + CJS · 14kb core · zero runtime deps.',
    'A11y': 'WAI-ARIA patterns, full keyboard nav, visible focus, screen-reader tested.',
  };
  return (
    <div style={{ width: '100%' }}>
      <div style={{ display: 'flex', gap: 0 }}>
        {tabs.map(t => (
          <button key={t} onClick={() => setActive(t)} style={{
            flex: 1, padding: '11px 8px', fontWeight: 800, fontSize: 14, cursor: 'pointer',
            border: 'var(--bw) solid var(--line)', borderRadius: 0,
            borderBottom: active === t ? 'none' : 'var(--bw) solid var(--line)',
            marginRight: -1,
            background: active === t ? 'var(--accent)' : 'var(--bg-panel)',
            color: '#0A0A0A',
          }}>{t}</button>
        ))}
      </div>
      <div style={{
        border: 'var(--bw) solid var(--line)', borderTop: 'none', padding: 18,
        fontWeight: 600, minHeight: 78, background: 'var(--bg-panel)',
      }}>{body[active]}</div>
    </div>
  );
}

/* ---------- Accordion ---------- */
function BAccordion() {
  const items = [
    ['Is it really accessible?', 'Every component ships WAI-ARIA roles, keyboard handlers and tested focus order.'],
    ['Can I theme it?', 'Yes — swap a handful of CSS variables and the whole kit re-skins instantly.'],
  ];
  const [open, setOpen] = useState(0);
  return (
    <div style={{ width: '100%', display: 'flex', flexDirection: 'column', gap: -1 }}>
      {items.map(([q, a], i) => (
        <div key={i} style={{ border: 'var(--bw) solid var(--line)', marginBottom: -1, background: 'var(--bg-panel)' }}>
          <button onClick={() => setOpen(open === i ? -1 : i)} aria-expanded={open === i} style={{
            width: '100%', display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            padding: '13px 15px', fontWeight: 800, fontSize: 14, cursor: 'pointer',
            background: open === i ? 'var(--accent-4)' : 'var(--bg-panel)', color: '#0A0A0A', border: 'none',
          }}>
            {q}
            <span className="mono" style={{ fontSize: 20 }}>{open === i ? '–' : '+'}</span>
          </button>
          {open === i && <div style={{ padding: '0 15px 15px', fontWeight: 600, fontSize: 14 }}>{a}</div>}
        </div>
      ))}
    </div>
  );
}

/* ---------- Counter / stepper ---------- */
function BStepper() {
  const [n, setN] = useState(3);
  const Btn = ({ children, onClick, label }) => (
    <button onClick={onClick} aria-label={label} style={{
      width: 40, height: 40, fontWeight: 900, fontSize: 18, cursor: 'pointer',
      border: 'var(--bw) solid var(--line)', background: 'var(--bg-panel)', color: 'var(--fg)',
    }}>{children}</button>
  );
  return (
    <div style={{ display: 'inline-flex', alignItems: 'stretch' }}>
      <Btn onClick={() => setN(v => Math.max(0, v - 1))} label="decrement">−</Btn>
      <span style={{ minWidth: 56, height: 40, display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        borderTop: 'var(--bw) solid var(--line)', borderBottom: 'var(--bw) solid var(--line)',
        fontWeight: 900, fontSize: 17, fontFamily: 'Space Mono, monospace', background: 'var(--accent)', color: '#0A0A0A' }}>{n}</span>
      <Btn onClick={() => setN(v => v + 1)} label="increment">+</Btn>
    </div>
  );
}

/* ---------- Rating ---------- */
function BRating() {
  const [r, setR] = useState(4);
  const [hover, setHover] = useState(0);
  return (
    <div style={{ display: 'inline-flex', gap: 4 }} onMouseLeave={() => setHover(0)}>
      {[1,2,3,4,5].map(i => (
        <button key={i} aria-label={`${i} stars`} onMouseEnter={() => setHover(i)} onClick={() => setR(i)}
          style={{ background: 'none', border: 'none', padding: 2, cursor: 'pointer', color: 'var(--fg)',
            display: 'inline-flex' }}>
          <Star s={26} fill={(hover || r) >= i ? 'var(--accent)' : 'none'} />
        </button>
      ))}
    </div>
  );
}

/* ---------- Badge row ---------- */
function BBadges() {
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 9 }}>
      <span className="tag" style={{ background: 'var(--accent)', color: '#0A0A0A' }}>NEW</span>
      <span className="tag" style={{ background: 'var(--accent-2)', color: '#0A0A0A' }}>v3.0</span>
      <span className="tag" style={{ background: 'var(--accent-3)', color: '#fff' }}>STABLE</span>
      <span className="tag" style={{ background: 'var(--accent-4)', color: '#0A0A0A' }}>MIT</span>
    </div>
  );
}

/* ---------- Avatar stack ---------- */
function BAvatars() {
  const cols = ['var(--accent)', 'var(--accent-2)', 'var(--accent-3)', 'var(--accent-4)'];
  const labels = ['JK', 'MR', 'AB', 'TZ'];
  return (
    <div style={{ display: 'flex' }}>
      {labels.map((l, i) => (
        <span key={l} style={{
          width: 42, height: 42, marginLeft: i ? -10 : 0,
          border: 'var(--bw) solid var(--line)', borderRadius: 'calc(var(--radius) * .6)',
          background: cols[i], color: '#0A0A0A', display: 'inline-flex',
          alignItems: 'center', justifyContent: 'center', fontWeight: 900, fontSize: 14,
          fontFamily: 'Space Mono, monospace', zIndex: 4 - i,
        }}>{l}</span>
      ))}
    </div>
  );
}

/* ---------- Toast trigger ---------- */
function BToast() {
  const [show, setShow] = useState(false);
  useEffect(() => { if (show) { const t = setTimeout(() => setShow(false), 2600); return () => clearTimeout(t); } }, [show]);
  return (
    <div style={{ width: '100%' }}>
      <button className="btn btn-blue btn-sm" onClick={() => setShow(true)}>Trigger toast</button>
      <div aria-live="polite" style={{
        marginTop: 12, transform: show ? 'translateY(0)' : 'translateY(6px)',
        opacity: show ? 1 : 0, transition: 'all .2s', pointerEvents: 'none',
        display: 'flex', alignItems: 'center', gap: 10,
        border: 'var(--bw) solid var(--line)', background: 'var(--accent-4)', color: '#0A0A0A',
        padding: '10px 13px', fontWeight: 800, fontSize: 14,
      }}>
        <Check s={16}/> Saved to your library.
      </div>
    </div>
  );
}

Object.assign(window, {
  Arrow, Check, Star,
  BToggle, BCheck, BRadio, BInput, BSlider, BTabs, BAccordion,
  BStepper, BRating, BBadges, BAvatars, BToast,
});
