/* global React */
const { useEffect, useRef, useState } = React;

// ===== Logo =====
function ChicLogo({ size = "md", color, style }) {
  const cls = `chic-logo chic-logo--${size}`;
  return (
    <div className={cls} style={{ color, ...style }}>
      <div><b>C</b>entre</div>
      <div><b>H</b>ospitalier</div>
      <div><b>I</b>nternational de</div>
      <div><b>C</b>alavi (CHIC)</div>
    </div>
  );
}

// ===== Pills =====
function StatusPill({ status, dense }) {
  const open = status === "open";
  return (
    <span className={`pill ${open ? "pill-open" : "pill-soon"}`}>
      <span className="dot" />
      {dense ? (open ? "Ouvert" : "Bientôt") : (open ? "Disponible" : "Bientôt")}
    </span>
  );
}

// ===== Animated number counter (counts up when visible) =====
function Counter({ to = 0, duration = 1400, suffix = "", className = "", style }) {
  const [val, setVal] = useState(0);
  const ref = useRef(null);
  const started = useRef(false);
  useEffect(() => {
    const node = ref.current;
    if (!node) return;
    const obs = new IntersectionObserver(entries => {
      entries.forEach(e => {
        if (e.isIntersecting && !started.current) {
          started.current = true;
          const start = performance.now();
          const tick = t => {
            const p = Math.min(1, (t - start) / duration);
            // ease-out cubic
            const eased = 1 - Math.pow(1 - p, 3);
            setVal(Math.round(eased * to));
            if (p < 1) requestAnimationFrame(tick);
          };
          requestAnimationFrame(tick);
        }
      });
    }, { threshold: 0.4 });
    obs.observe(node);
    return () => obs.disconnect();
  }, [to, duration]);
  return <span ref={ref} className={className} style={style}>{val.toLocaleString("fr-FR")}{suffix}</span>;
}

// ===== Stat block =====
function Stat({ value, label, frac, prefix = "", suffix = "" }) {
  // value may include a fraction "openSpec/totalSpec" — split visually
  if (typeof value === "string" && value.includes("/")) {
    const [a, b] = value.split("/");
    return (
      <div className="stat">
        <div className="stat-value">
          <Counter to={Number(a)} />
          <span className="frac">/{b}</span>
        </div>
        <div className="stat-label">{label}</div>
      </div>
    );
  }
  return (
    <div className="stat">
      <div className="stat-value">
        {prefix}<Counter to={Number(value) || 0} />{suffix}
        {frac && <span className="frac"> /{frac}</span>}
      </div>
      <div className="stat-label">{label}</div>
    </div>
  );
}

// ===== Reveal on scroll =====
function FadeUp({ children, delay = 0, as: As = "div", className = "", style }) {
  const [shown, setShown] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    const node = ref.current;
    if (!node) return;
    const obs = new IntersectionObserver(entries => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          setTimeout(() => setShown(true), delay);
          obs.disconnect();
        }
      });
    }, { threshold: 0.1, rootMargin: "0px 0px -40px 0px" });
    obs.observe(node);
    return () => obs.disconnect();
  }, [delay]);
  return (
    <As ref={ref} className={`fade-up ${shown ? "in" : ""} ${className}`} style={style}>
      {children}
    </As>
  );
}

// ===== Crumbs =====
function Crumbs({ trail }) {
  return (
    <div className="crumbs">
      {trail.map((t, i) => (
        <React.Fragment key={i}>
          {i > 0 && <span className="sep">/</span>}
          {i === trail.length - 1
            ? <span className="current">{t.label}</span>
            : <a href={t.href || "#/"}>{t.label}</a>}
        </React.Fragment>
      ))}
    </div>
  );
}

// ===== Section header (eyebrow + title + lead + optional right) =====
function SectionHeader({ eyebrow, title, lead, right }) {
  return (
    <div className="sec-header">
      <div>
        {eyebrow && <div className="eyebrow" style={{ marginBottom: 18 }}>{eyebrow}</div>}
        {title && <h2 className="h2">{title}</h2>}
        {lead && <p className="lead" style={{ marginTop: 18, maxWidth: "62ch" }}>{lead}</p>}
      </div>
      {right && <div className="right">{right}</div>}
    </div>
  );
}

Object.assign(window, {
  ChicLogo, StatusPill, Counter, Stat, FadeUp, Crumbs, SectionHeader,
});
