// components/ui.jsx — shared hooks + primitive UI components

// ── Routing ──────────────────────────────────────────────────
function usePathRoute() {
  const getRoute = () => window.location.pathname;
  const [route, setRoute] = React.useState(getRoute);
  React.useEffect(() => {
    const handler = () => setRoute(getRoute());
    window.addEventListener('popstate', handler);
    window.addEventListener('pushstate', handler);
    return () => {
      window.removeEventListener('popstate', handler);
      window.removeEventListener('pushstate', handler);
    };
  }, []);
  return route;
}

function navigate(path) {
  window.history.pushState(null, '', path);
  window.dispatchEvent(new Event('pushstate'));
  window.scrollTo({ top: 0, behavior: 'instant' });
}

// ── SEO ──────────────────────────────────────────────────────
function useSEO(title, description) {
  React.useEffect(() => {
    if (title) document.title = title;
    if (description) {
      let meta = document.querySelector('meta[name="description"]');
      if (!meta) {
        meta = document.createElement('meta');
        meta.name = "description";
        document.head.appendChild(meta);
      }
      meta.content = description;
    }
  }, [title, description]);
}

// ── Scroll animation ─────────────────────────────────────────
function useInView(threshold = 0.12) {
  const ref = React.useRef(null);
  const [inView, setInView] = React.useState(false);
  React.useEffect(() => {
    if (!ref.current) return;
    const obs = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setInView(true); obs.disconnect(); }
    }, { threshold });
    obs.observe(ref.current);
    return () => obs.disconnect();
  }, [threshold]);
  return [ref, inView];
}

function AnimEl({ as: Tag = 'div', delay = 0, className = '', children, style = {}, ...rest }) {
  const [ref, inView] = useInView();
  const delayClass = delay > 0 ? ` delay-${delay}` : '';
  return (
    <Tag
      ref={ref}
      className={`anim-init${inView ? ' in-view' : ''}${delayClass} ${className}`}
      style={style}
      {...rest}
    >
      {children}
    </Tag>
  );
}

// ── Button ───────────────────────────────────────────────────
function Btn({ variant = 'primary', size = 'lg', href, to, onClick, className = '', children, style = {}, disabled, type }) {
  const sizeClass = { sm: 'btn-sm', md: 'btn-md', lg: 'btn-lg', xl: 'btn-xl' }[size] || 'btn-lg';
  const varClass = { primary: 'btn-primary', secondary: 'btn-secondary', ghost: 'btn-ghost' }[variant] || 'btn-primary';
  const cls = `btn ${sizeClass} ${varClass} ${className}`;

  if (href) {
    return <a href={href} target={href.startsWith('http') ? '_blank' : undefined}
              rel={href.startsWith('http') ? 'noopener noreferrer' : undefined}
              className={cls} style={style}>{children}</a>;
  }
  if (to) {
    return <a href={to} className={cls} style={style}
              onClick={(e) => { e.preventDefault(); navigate(to); }}>{children}</a>;
  }
  return <button onClick={onClick} className={cls} style={style} disabled={disabled} type={type}>{children}</button>;
}

// ── Copy button ───────────────────────────────────────────────
function CopyBtn({ text, style = {} }) {
  const [state, setState] = React.useState('idle');
  const copy = () => {
    navigator.clipboard.writeText(text).then(() => {
      setState('done');
      setTimeout(() => setState('idle'), 2000);
    });
  };
  return (
    <button onClick={copy} title="Copy" style={{
      background: 'none', border: 'none', cursor: 'pointer', padding: '2px 6px',
      color: state === 'done' ? 'var(--color-green)' : 'var(--color-muted)',
      fontSize: '0.7rem', fontFamily: 'var(--font-mono)', transition: 'color 0.15s', ...style
    }}>
      {state === 'done' ? '✓ copied' : 'copy'}
    </button>
  );
}

// ── Code block ───────────────────────────────────────────────
function CodeBlock({ code, lang = 'bash', filename, showDots = true, copyable = true }) {
  const codeRef = React.useRef(null);

  React.useEffect(() => {
    if (!codeRef.current) return;
    const el = codeRef.current;
    delete el.dataset.highlighted;
    el.className = `language-${lang}`;
    el.textContent = code;
    if (window.hljs) window.hljs.highlightElement(el);
  }, [code, lang]);

  return (
    <div className="code-panel">
      <div className="code-panel-header">
        {showDots && (
          <div className="code-dots">
            <div className="code-dot code-dot-r" />
            <div className="code-dot code-dot-y" />
            <div className="code-dot code-dot-g" />
          </div>
        )}
        {filename && <span className="code-filename">{filename}</span>}
        {copyable && <CopyBtn text={code} style={{ marginLeft: 'auto' }} />}
      </div>
      <pre style={{ margin: 0 }}>
        <code ref={codeRef} className={`language-${lang}`}>{code}</code>
      </pre>
    </div>
  );
}

// ── Tabbed code block ─────────────────────────────────────────
function TabbedCode({ tabs, showDots = true }) {
  const [active, setActive] = React.useState(0);
  const tab = tabs[active];

  return (
    <div className="code-panel">
      <div style={{ display: 'flex', flexDirection: 'column' }}>
        <div style={{ display: 'flex', alignItems: 'center', background: '#0a0a11', borderBottom: '1px solid var(--color-border)', padding: '0.6rem 1rem 0 1rem' }}>
          {showDots && (
            <div className="code-dots" style={{ marginRight: '0.75rem', paddingBottom: '0.5rem' }}>
              <div className="code-dot code-dot-r" />
              <div className="code-dot code-dot-y" />
              <div className="code-dot code-dot-g" />
            </div>
          )}
          <div style={{ display: 'flex', flex: 1 }}>
            {tabs.map((t, i) => (
              <button key={i} onClick={() => setActive(i)}
                className={`code-tab${i === active ? ' active' : ''}`}>
                {t.label}
              </button>
            ))}
          </div>
          <CopyBtn text={tab.code} />
        </div>
        <pre style={{ margin: 0, padding: '1.25rem 1.5rem', overflowX: 'auto' }}>
          <CodeInner code={tab.code} lang={tab.lang || 'bash'} key={active} />
        </pre>
      </div>
    </div>
  );
}

function CodeInner({ code, lang }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!ref.current) return;
    const el = ref.current;
    delete el.dataset.highlighted;
    el.className = `language-${lang}`;
    el.textContent = code;
    if (window.hljs) window.hljs.highlightElement(el);
  }, [code, lang]);
  return <code ref={ref} className={`language-${lang}`}>{code}</code>;
}

// ── Section header ────────────────────────────────────────────
function SectionHeader({ eyebrow, title, sub, center = true, className = '' }) {
  return (
    <div className={`${className}`} style={{ textAlign: center ? 'center' : 'left', maxWidth: center ? '640px' : undefined, margin: center ? '0 auto' : undefined }}>
      {eyebrow && <div className="section-eyebrow">— {eyebrow}</div>}
      <h2 className="section-title" style={{ marginBottom: sub ? '0.75rem' : 0 }} dangerouslySetInnerHTML={{ __html: title }} />
      {sub && <p className="section-sub" style={{ margin: center ? '0 auto' : 0 }}>{sub}</p>}
    </div>
  );
}

// ── Badge ─────────────────────────────────────────────────────
function Badge({ variant = 'brand', children, className = '' }) {
  return <span className={`badge badge-${variant} ${className}`}>{children}</span>;
}

// ── Card ──────────────────────────────────────────────────────
function Card({ children, className = '', hover = false, glow = false, style = {} }) {
  return (
    <div className={`card ${hover ? 'card-glow' : ''} ${className}`} style={style}>
      {children}
    </div>
  );
}

// ── Divider ───────────────────────────────────────────────────
function Divider() { return <hr className="divider" />; }

Object.assign(window, {
  usePathRoute, useSEO, navigate, useInView, AnimEl,
  Btn, CopyBtn, CodeBlock, TabbedCode, CodeInner,
  SectionHeader, Badge, Card, Divider,
});
